Search by

payzum / sylius-payzum-plugin

Accept crypto and stablecoin payments (USDC, USDT and more) in Sylius through Payzum — non-custodial

Maintainers

Package info

github.com/payzum-dev/sylius-payzum-plugin

Homepage

Type:sylius-plugin

pkg:composer/payzum/sylius-payzum-plugin

Transparency log

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.2.0 2026-09-03 15:31 UTC

This package is auto-updated.

Last update: 2026-09-03 15:35:38 UTC


README

Accept crypto and stablecoin payments (USDC, USDT and more, multi-chain) in Sylius through Payzumnon-custodial: funds settle directly to your own wallet, Payzum never takes custody.

Built for Sylius 2.x on the PaymentRequest flow (not Payum), following the structure of the official StripePlugin.

How it works

  1. The customer picks Payzum at checkout and is redirected to a hosted checkout page, where they choose the asset and chain and send the payment. No wallet or card data touches your server.
  2. Crypto confirmation is asynchronous, so the payment is completed from Payzum's signed server-to-server notification, never from the browser return. When the buyer comes back, the pay page shows the real state — a payment that is still confirming stays in processing.
  3. Every notification is verified with HMAC-SHA-512 over the raw request bytes (with a replay window) before a single field of it is read, and the invoice amount and currency are re-checked against the payment before it is completed. Redelivered notifications are a no-op, so an order is never fulfilled twice.

Installation

composer require payzum/sylius-payzum-plugin

Register the bundle in config/bundles.php:

return [
    // ...
    Payzum\SyliusPayzumPlugin\PayzumSyliusPayzumPlugin::class => ['all' => true],
];

Then create a payment method in the admin panel (Configuration → Payment methods → Create), choose the Payzum (crypto & stablecoins) gateway and fill in:

Setting Meaning
API key From your Payzum merchant dashboard
Webhook secret Verifies incoming payment notifications; shown once, separately from the API key
Pay currency Optional. Pin one asset, e.g. usdc; empty lets the buyer choose
Network Optional. Pin one chain for that asset, e.g. polygon
Sandbox mode Use the Payzum staging environment

The notification endpoint is Sylius' own sylius_payment_method_notify route (/payment-methods/{code}); the plugin sends it to Payzum with every invoice, so there is nothing to configure in the dashboard.

Architecture

The Payzum-specific code is kept out of the Sylius layer, so the API client, signature verification and status mapping can be read and tested on their own:

src/
  Payzum/                  API client factory, gateway config, webhook
                           verification, status mapping, amount conversion
  Command/                 Capture / Notify / Status / Cancel payment requests
  CommandHandler/          One handler per command
  CommandProvider/         Maps a payment request action to its command
  Processor/               Raw-body notify payload processor; guarded
                           payment transitions
  Provider/                Invoice parameters, notification → payment
                           resolution, return URL
  OrderPay/Provider/       Redirect to the hosted checkout page
  Form/Type/               Gateway configuration form

Two design points worth knowing:

  • The payment request hash travels as the Payzum order_id, so a verified notification is matched to its payment without trusting anything else in the payload — and each delivery is handled as a fresh payment request, which is what keeps the gateway's retries working after the order is paid.
  • Amounts are converted with exact string arithmetic (never through a float) and the currency's own number of decimals, so zero-decimal currencies (JPY) and three-decimal ones (KWD) are correct too.

Tests

composer install
vendor/bin/phpunit

License

MIT. The payzum/payzum-php SDK it builds on is MIT as well and has no runtime dependencies.