eiling-io / sylius-topi-plugin
Topi plugin for Sylius
Package info
github.com/eiling-io/topi-sylius
Type:sylius-plugin
pkg:composer/eiling-io/sylius-topi-plugin
Requires
- php: ^8.2
- guzzlehttp/guzzle: ^7.10
- payum/core: ^1.7
- payum/payum-bundle: ^2.7
- svix/svix: ^1.95
- sylius/sylius: ^2.0
Requires (Dev)
- behat/behat: ^3.16
- dbrekelmans/bdi: ^1.4
- dmore/behat-chrome-extension: ^1.4
- dmore/chrome-mink-driver: ^2.9
- friends-of-behat/mink: ^1.11
- friends-of-behat/mink-browserkit-driver: ^1.6
- friends-of-behat/mink-debug-extension: ^2.1
- friends-of-behat/mink-extension: ^2.7
- friends-of-behat/page-object-extension: ^0.3
- friends-of-behat/suite-settings-extension: ^1.1
- friends-of-behat/symfony-extension: ^2.6
- friends-of-behat/variadic-extension: ^1.6
- nyholm/psr7: ^1.8
- phpstan/phpstan: ^1.12
- phpstan/phpstan-doctrine: ^1.3
- phpstan/phpstan-webmozart-assert: ^1.2
- phpunit/phpunit: ^10.5
- sylius-labs/coding-standard: ^4.4
- sylius-labs/suite-tags-extension: ~0.2
- sylius/sylius-rector: ^2.0
- sylius/test-application: ^2.0.0@alpha
- symfony/browser-kit: ^6.4 || ^7.4
- symfony/debug-bundle: ^6.4 || ^7.4
- symfony/dotenv: ^6.4 || ^7.4
- symfony/http-client: ^6.4 || ^7.4
- symfony/intl: ^6.4 || ^7.4
- symfony/runtime: ^6.4 || ^7.4
- symfony/web-profiler-bundle: ^6.4 || ^7.4
- symfony/webpack-encore-bundle: ^2.2
This package is auto-updated.
Last update: 2026-08-07 11:36:21 UTC
README
Integrates Topi (B2B pay-later / financing) as a Payum-based payment gateway for Sylius 2.0 — checkout capture/webhook handling, catalog and shipping-method sync commands, and Topi Elements rental-price badges on the PDP, product listings, cart, and payment-selection page.
Ported from a Sylius 1.x implementation built for a larger shop application; see
the class-level docblocks on CatalogSyncService/TopiProductExtension/WebhookController
for the app-specific pieces (custom price lists, multi-tenant channel gating, a dedicated
Payment entity extension) that had no equivalent in stock Sylius and were simplified
during the port — EilingIo\SyliusTopiPlugin\Service\VariantPriceResolver is the
plugin-native replacement for price/tax resolution.
Requirements
- PHP 8.2 or higher
- Sylius 2.0 or higher
- A Topi seller account — for local/test use, sandbox credentials (client ID/secret) and a sandbox Topi Elements widget ID, both issued by Topi
Installation
Steps to add the plugin to an existing Sylius 2.0 project.
-
Require the package:
composer require eiling-io/sylius-topi-plugin
-
Enable the plugin in
config/bundles.php:<?php return [ // ... EilingIo\SyliusTopiPlugin\EilingIoSyliusTopiPlugin::class => ['all' => true], ];
-
Import the plugin's routes, e.g. in
config/routes/eiling_io_sylius_topi.yaml:eiling_io_sylius_topi: resource: "@EilingIoSyliusTopiPlugin/config/routes.yaml"
-
Add the required env variables to your
.env(or.env.local) file:# OAuth2 client credentials for the Topi seller API (identity.topi[-sandbox].eu). TOPI_CLIENT_ID="" TOPI_CLIENT_SECRET="" # 0 = sandbox (seller-api-sandbox.topi-sandbox.eu), 1 = production (seller-api.topi.eu). TOPI_ENABLE_LIVE=0 # Comma-separated Svix signing secrets from the Topi merchant portal's webhook # settings — WebhookVerificationService tries each until one verifies. TOPI_WEBHOOK_SIGNING_SECRETS="" # Keep this off only while wiring things up locally; turn it on once real # webhooks need to be trusted. TOPI_ENABLE_WEBHOOK_SIGNATURE_CHECKS=0 # Feature flag for both TopiProductExtension (is_topi_product()/topi_pdp_item()) # and the Topi Elements badges. TOPI_ENABLE=1 # Widget ID for the Topi Elements script (elements.topi[-sandbox].eu) — issued # separately from the client ID/secret above, ask Topi for one per environment. TOPI_WIDGET_ID=""
-
In the Sylius admin (Configuration → Payment methods → Create), add a payment method and pick Topi Payment as the gateway. Enable it for the channel(s) that should offer Topi at checkout.
-
Register the webhook URL (
https://your-shop.example/topi-payment/webhook) in the Topi merchant portal so offer/order lifecycle events reachWebhookController. -
Sync your catalog and shipping methods to Topi so the rental-price badges and checkout offers have something to price against:
bin/console topi:catalog:sync bin/console topi:shipping-methods:sync
At this point, checkout should offer "Topi Payment" as a method, and — once
TOPI_ENABLE/TOPI_WIDGET_ID are set — the PDP, product listings, cart, and
payment-selection page should show Topi's rental-price badges.
The
<x-topi-checkout-button>("Buy now") integration is built (seeBuyNowOfferService/BuyNowOrderCreator/checkout_button_*.html.twig) but not wired into any template by default — Topi'sPOST /offerscurrently rejects an offer with noshipping_addressforsales_channel=ecommerce, which the button's "address collected on Topi's hosted checkout" flow relies on. Hookcheckout_button_pdp.html.twig/checkout_button_cart.html.twigback intoconfig/config.yamlonce that's resolved with Topi.
ddev setup (plugin development)
For working on the plugin itself against the bundled Sylius test application
(vendor/sylius/test-application), rather than installing it into another project.
-
Install ddev and make sure Docker is running.
-
Install PHP dependencies (ddev's PHP version is pinned in
.ddev/config.yaml, so run this through ddev rather than the host's own PHP/Composer):ddev start ddev composer install
-
Add your Topi sandbox credentials to
tests/TestApplication/.env(or a sibling.env.local— see the env variables listed under Installation above; this is the filevendor/sylius/test-application's kernel loads on top of its own defaults, seeconfig/bootstrap.phpin that package for how). -
Run the project's
initcommand — creates the database, runs migrations, loads Sylius' demo fixtures, and builds the frontend assets:ddev init
This is equivalent to running, inside the web container:
doctrine:database:create→doctrine:migrations:migrate -n→sylius:fixtures:load -n→yarn install && yarn build(invendor/sylius/test-application) →assets:install. -
Open the shop at
https://syliustopiplugin.ddev.site/and the admin athttps://syliustopiplugin.ddev.site/admin/(default fixture login:sylius/sylius).
Useful follow-ups:
ddev exec php vendor/bin/console <command>— run any console command inside the web container (matches the PHP version Sylius actually runs under).ddev mysql <db-name> -e "<query>"— inspect the database directly; the app database is namedsylius_topi_plugin_dev(seeDATABASE_URLintests/TestApplication/.env).ddev exec php vendor/bin/console cache:clear --env=dev— after changing PHP, Twig hooks, orconfig/services.xml/config/config.yaml.ddev logs -s web --tail=50— tail the web container's logs; app-level errors (Guzzle/Topi API responses, webhook failures, ...) also land invar/log/dev.log.ddev stop— stop the containers without removing them;ddev deleteto remove the project (including its database) entirely.