setono / sylius-quickpay-plugin
Quickpay payment plugin for Sylius
Package info
github.com/Setono/SyliusQuickpayPlugin
Type:sylius-plugin
pkg:composer/setono/sylius-quickpay-plugin
Fund package maintenance!
Requires
- php: >=8.1
- ext-json: *
- ext-mbstring: *
- doctrine/collections: ^1.6
- doctrine/orm: ^2.7
- fakerphp/faker: ^1.21
- payum/payum: ^1.6
- setono/payum-quickpay: ^1.3
- symfony/config: ^5.4 || ^6.0
- symfony/dependency-injection: ^5.4 || ^6.0
- symfony/form: ^5.4 || ^6.0
- symfony/http-foundation: ^5.4 || ^6.0
- symfony/http-kernel: ^5.4 || ^6.0
- symfony/intl: ^5.4 || ^6.0
- symfony/validator: ^5.4 || ^6.0
- viison/address-splitter: ^0.3.4
- webmozart/assert: ^1.11
- winzou/state-machine: ^0.3 || ^0.4
Requires (Dev)
- api-platform/core: ^2.7
- behat/behat: ^3.12
- lexik/jwt-authentication-bundle: ^2.16
- matthiasnoback/symfony-config-test: ^4.3
- matthiasnoback/symfony-dependency-injection-test: ^4.3
- phpspec/phpspec: ^7.3
- phpunit/phpunit: ^9.5
- psalm/plugin-phpunit: ^0.18
- psalm/plugin-symfony: ^5.0
- setono/code-quality-pack: ^2.4
- sylius/sylius: ~1.12.3
- symfony/debug-bundle: ^5.4 || ^6.0
- symfony/dotenv: ^5.4 || ^6.0
- symfony/property-info: ^5.4 || ^6.0
- symfony/serializer: ^5.4 || ^6.0
- symfony/web-profiler-bundle: ^5.4 || ^6.0
- symfony/webpack-encore-bundle: ^1.16
This package is auto-updated.
Last update: 2026-08-06 13:43:32 UTC
README
Adds Quickpay as a payment gateway to your Sylius store, including credit card and Klarna
payments. The plugin integrates the setono/payum-quickpay Payum gateway
into Sylius' checkout, state machine, and admin.
Requirements
- PHP 8.1 or higher
- Sylius 1.14 on Symfony 6.4
Installation
1. Install the plugin
composer require setono/sylius-quickpay-plugin
2. Register the bundle
<?php # config/bundles.php return [ // ... Setono\SyliusQuickpayPlugin\SetonoSyliusQuickpayPlugin::class => ['all' => true], ];
3. Import the plugin configuration
# config/packages/setono_sylius_quickpay.yaml imports: - { resource: "@SetonoSyliusQuickpayPlugin/Resources/config/app/config.yaml" }
This registers the state machine callback that captures, refunds, and cancels Quickpay payments when the corresponding Sylius payment transitions are applied (see How it works). Each operation can be turned off individually:
# config/packages/setono_sylius_quickpay.yaml setono_sylius_quickpay: disable_capture: false disable_refund: false disable_cancel: false
Note: The callback is registered with winzou_state_machine, the default state machine adapter in Sylius 1.14.
If your application runs the sylius_payment graph on the symfony_workflow adapter, the callback will not fire.
4. Import the routes
# config/routes/setono_sylius_quickpay.yaml setono_sylius_quickpay: resource: "@SetonoSyliusQuickpayPlugin/Resources/config/routing.yaml"
This registers the callback endpoint (POST /payment/quickpay/notify) that Quickpay's servers use to notify your
store about payment state changes.
5. Set the order prefix environment variable
# .env QUICKPAY_ORDER_PREFIX=qp_
The prefix is prepended to your order numbers before they are sent to Quickpay as the order_id. It must be
defined for the container to compile, and it must be unique per project and environment sharing the same
Quickpay account — see Troubleshooting. Keep it at 11 characters or less.
6. Add the validator constraint (optional, Klarna only)
Klarna requires structured street addresses. In Germany and the Netherlands the plugin splits a one-line street into street and house number, and this constraint prevents customers from entering an address that cannot be split.
<?xml version="1.0" encoding="UTF-8"?> <!-- config/validator/Address.xml --> <constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping http://symfony.com/schema/dic/services/constraint-mapping-1.0.xsd"> <class name="Sylius\Component\Addressing\Model\Address"> <constraint name="Setono\SyliusQuickpayPlugin\Validator\Constraints\AddressStreetEligibility"> <option name="message">setono_sylius_quickpay.address.street_eligibility</option> <option name="groups"> <value>sylius_shipping_address_update</value> <value>sylius_checkout_complete</value> <value>sylius</value> </option> </constraint> </class> </constraint-mapping>
See the test application for a working example.
7. Import fixtures (optional, development only)
# config/packages/setono_sylius_quickpay.yaml imports: - { resource: "@SetonoSyliusQuickpayPlugin/Resources/config/app/fixtures.yaml" }
The fixtures create Quickpay credit card and Klarna payment methods, matching channels, and a test customer. They read the gateway credentials from these environment variables:
QUICKPAY_API_KEY= QUICKPAY_PRIVATE_KEY= QUICKPAY_MERCHANT_ID= QUICKPAY_AGREEMENT_ID=
Configuration
Create a new payment method of type Quickpay in the admin panel (Configuration → Payment methods) and fill out the gateway configuration:
| Field | Description |
|---|---|
| Api key | The API key of the API user in your Quickpay manager (Settings → Users) |
| Private key | The private key of your merchant account (Settings → Integration) |
| Merchant id | Your Quickpay merchant id |
| Agreement id | The agreement id of the API user |
| Order prefix | Prepended to order numbers sent to Quickpay — keep in sync with QUICKPAY_ORDER_PREFIX |
| Payment methods | Which payment methods the Quickpay payment window offers, e.g. creditcard or klarna-payments — see the Quickpay documentation |
| Auto capture | Capture the payment automatically right after authorization — useful for digital products |
How it works
- During checkout the customer is redirected to the Quickpay payment window through a payment link. The payment is authorized, not captured (unless Auto capture is enabled).
- Quickpay notifies your store of every payment change on the callback endpoint. The callback's
Quickpay-Checksum-SHA256header is validated against your private key before the payment details are updated. - When you complete, refund, or cancel a payment in the Sylius admin, the plugin performs the matching capture, refund, or cancel operation against Quickpay. A failed cancel at Quickpay (e.g. the customer never completed checkout, so there is nothing to cancel) is logged but does not block cancelling the order.
Testing
composer phpunit # unit tests composer analyse # static analysis (PHPStan) composer check-style # coding standards
For manual testing, use the credit card numbers from the Quickpay test data.
Troubleshooting
-
Validation error: Transaction in wrong state for this operationafter upgrading to Sylius v1.6After this commit,
use_authorizeconfig option should be strictlybooleantyped. Update yourpayment_methodfixtures like done at this commit.At live app - open each quickpay payment method at admin and click save so hidden
use_authorizeform field will be stored in database in new format. -
Not authorized: Not authorized to PUT /payments/:id/linkat/payment/authorize/...url:You should check at
https://manage.quickpay.net/account/{QUICKPAY_MERCHANT_ID}/settings/usersthatSystem users>API User>User permissions>Create or update payment linkhavePUTcheckbox checked. Also checkQUICKPAY_API_KEYandQUICKPAY_AGREEMENT_IDis filled withAPI User's api key and agreement id rather thanPayment Window's. -
Validation error: order_id already exists on another paymentMake sure you changed your
QUICKPAY_ORDER_PREFIXat.env.*to some unique string likeqp_<projectname>_<date>_(whendateshould be updated to actual every time you recreate dev database) whenever you:- Recreating your database on dev environment and your order IDs become same as they was before
- Use
SetonoSyliusQuickpayPluginat two different projects but with same Quickpay (developer) account credentials
-
Validation error: order_id must have length between 4 and 20You should cut your
QUICKPAY_ORDER_PREFIXto 11 chars or less.