Sylius contains a very flexible payments management system with support for many gateways (payment providers). We are using a payment abstraction library - Payum, which handles all sorts of capturing, refunding and recurring payments logic.

On Sylius side, we integrate it into our checkout and manage all the payment data.


Every payment in Sylius, successful or failed, is represented by the Payment model, which contains basic information and a reference to appropriate order.


By installing the Sylius/InvoicingPlugin you can enhance your Sylius application with the automatic generation of invoicing documents for each Order’s payment.

Sylius invoices have their own numbers, issuing dates, consist of shop and customer’s data, the order items with prices and quantity and separated taxes section. Their templates can be changed, and of course the moment of invoice generation can be customized.

Payment State Machine

A Payment that is assigned to an order will have it’s own state machine with a few available states: cart, new, processing, completed, failed, cancelled, refunded.

The available transitions between these states are:

        from: [cart]
        to: new
        from: [new]
        to: processing
        from: [new, processing]
        to: authorized
        from: [new, processing, authorized]
        to: completed
        from: [new, processing]
        to: failed
        from: [new, processing, authorized]
        to: cancelled
        from: [completed]
        to: refunded

Of course, you can define your own states and transitions to create a workflow, that perfectly matches your needs. Full configuration can be seen in the PaymentBundle/Resources/config/app/state_machine.yml.

Changes to payment happen through applying appropriate transitions.

How to create a Payment programmatically?

We cannot create a Payment without an Order, therefore let’s assume that you have an Order to which you will assign a new payment.

$payment = $this->container->get('sylius.factory.payment')->createNew();




Not familiar with the Order concept? Check here.

Payment Methods

A PaymentMethod represents a way that your customer pays during the checkout process. It holds a reference to a specific gateway with custom configuration. Gateway is configured for each payment method separately using the payment method form.

How to create a PaymentMethod programmatically?

As usual, use a factory to create a new PaymentMethod and give it a unique code.

$paymentMethod = $this->container->get('sylius.factory.payment_method')->createWithGateway('offline');


In order to have your new payment method available in the checkout remember to add your desired channel to the payment method:


Payment Gateway configuration

Payment Gateways that already have a Sylius bridge

First you need to create the configuration form type for your gateway. Have a look at the configuration form types of

Then you should register its configuration form type with sylius.gateway_configuration_type tag. After that it will be available in the Admin panel in the gateway choice dropdown.


If you are not sure how your configuration form type should look like, head to Payum documentation.

Other Payment Gateways


Learn more about integrating payment gateways in the dedicated guide and in the Payum docs.

When the Payment Gateway you are trying to use does have a bridge available and you integrate them on your own, use our guide on extension development.


Sylius stores the payment output inside the details column of the sylius_payment table. It can provide valuable information when debugging the payment process.

PayPal Error Code 10409

The 10409 code, also known as the “Checkout token was issued for a merchant account other than yours” error. You have most likely changed the PayPal credentials during the checkout process. Clear the cache and try again:

bin/console cache:clear

Payment complete events


The following events are not a universal way to listen for a completed payment, as they are only dispatched by ResourceController at specific places, like completing the payment for a given order in the Admin Panel. It means that pre_complete and post_complete events won’t be triggered when a customer completes the payment by using, e.g., a payment gateway.


If you are looking for a way to listen for completing the payment, consider adding a new callback for a sylius_order_payment state machine on the pay transition.

There are two events that are triggered on the payment complete action:

Event id