Manual Installation

1. Install the Plugin via Composer

composer require sylius/mollie-plugin:^3.1 --no-scripts -W

2. Enable the Bundle

# config/bundles.php

return [
    ...
    Bazinga\Bundle\JsTranslationBundle\BazingaJsTranslationBundle::class => ['all' => true],
    Sylius\MolliePlugin\SyliusMolliePlugin::class => ['all' => true],
];

3. Import Configuration

# config/packages/_sylius.yaml

imports:
    ...
    - { resource: "@SyliusMolliePlugin/config/config.yaml" }

4. Import routes

# config/routes.yaml

...
sylius_mollie:
    resource: "@SyliusMolliePlugin/config/routes.yaml"

5. Extend the GatewayConfig entity

<?php
// src/Entity/Payment/GatewayConfig.php

declare(strict_types=1);

namespace App\Entity\Payment;

use Doctrine\ORM\Mapping as ORM;
use Sylius\Bundle\PayumBundle\Model\GatewayConfig as BaseGatewayConfig;
use Sylius\MolliePlugin\Entity\GatewayConfigInterface;
use Sylius\MolliePlugin\Entity\GatewayConfigTrait;

/**
 * @ORM\Entity
 * @ORM\Table(name="sylius_gateway_config")
 */
#[ORM\Entity]
#[ORM\Table(name: 'sylius_gateway_config')]
class GatewayConfig extends BaseGatewayConfig implements GatewayConfigInterface
{
    use GatewayConfigTrait;

    public function __construct()
    {
        parent::__construct();

        $this->initializeMollieGatewayConfig();
    }
}

Register the GatewayConfig entity

# config/packages/_sylius.yaml
...

sylius_payment:
    resources:
        gateway_config:
            classes:
                model: App\Entity\Payment\GatewayConfig

6. Extend the Order entity

<?php
// src/Entity/Order/Order.php

declare(strict_types=1);

namespace App\Entity\Order;

use Doctrine\ORM\Mapping as ORM;
use Sylius\Component\Core\Model\Order as BaseOrder;
use Sylius\MolliePlugin\Entity\AbandonedEmailOrderTrait;
use Sylius\MolliePlugin\Entity\MolliePaymentIdOrderTrait;
use Sylius\MolliePlugin\Entity\OrderInterface;
use Sylius\MolliePlugin\Entity\QRCodeOrderTrait;
use Sylius\MolliePlugin\Entity\RecurringOrderTrait;

/**
 * @ORM\Entity
 * @ORM\Table(name="sylius_order")
 */
#[ORM\Entity]
#[ORM\Table(name: 'sylius_order')]
class Order extends BaseOrder implements OrderInterface
{
    use AbandonedEmailOrderTrait;
    use RecurringOrderTrait;
    use QRCodeOrderTrait;
    use MolliePaymentIdOrderTrait;
}

Register the Order entity

# config/packages/_sylius.yaml
...

sylius_order:
    resources:
        order:
            classes:
                model: App\Entity\Order\Order

7. Extend the Product entity

<?php
// src/Entity/Product/Product.php

declare(strict_types=1);

namespace App\Entity\Product;

use Doctrine\ORM\Mapping as ORM;
use Sylius\Component\Core\Model\Product as BaseProduct;
use Sylius\MolliePlugin\Entity\ProductInterface;
use Sylius\MolliePlugin\Entity\ProductTrait;

/**
 * @ORM\Entity
 * @ORM\Table(name="sylius_product")
 */
#[ORM\Entity]
#[ORM\Table(name: 'sylius_product')]
class Product extends BaseProduct implements ProductInterface
{
    use ProductTrait;
}

Register the Product entity

# config/packages/_sylius.yaml
...

sylius_product:
    resources:
        product:
            classes:
                model: App\Entity\Product\Product

8. Extend the ProductVariant entity

<?php
// src/Entity/Product/ProductVariant.php

<?php

declare(strict_types=1);

namespace App\Entity\Product;

use Doctrine\ORM\Mapping as ORM;
use Sylius\Component\Core\Model\ProductVariant as BaseProductVariant;
use Sylius\MolliePlugin\Entity\ProductVariantInterface;
use Sylius\MolliePlugin\Entity\RecurringProductVariantTrait;

/**
 * @ORM\Entity
 * @ORM\Table(name="sylius_product_variant")
 */
#[ORM\Entity]
#[ORM\Table(name: 'sylius_product_variant')]
class ProductVariant extends BaseProductVariant implements ProductVariantInterface
{
    use RecurringProductVariantTrait;
}

Register the ProductVariant entity

# config/packages/_sylius.yaml
...

sylius_product:
    resources:
        product_variant:
            classes:
                model: App\Entity\Product\ProductVariant

9. Extend the AdminUser entity

<?php
// src/Entity/User/AdminUser.php

declare(strict_types=1);

namespace App\Entity\User;

use Doctrine\ORM\Mapping as ORM;
use Sylius\Component\Core\Model\AdminUser as BaseAdminUser;
use Sylius\MolliePlugin\Entity\OnboardingStatusAwareInterface;
use Sylius\MolliePlugin\Entity\OnboardingStatusAwareTrait;

/**
 * @ORM\Entity
 * @ORM\Table(name="sylius_admin_user")
 */
#[ORM\Entity]
#[ORM\Table(name: 'sylius_admin_user')]
class AdminUser extends BaseAdminUser implements OnboardingStatusAwareInterface
{
    use OnboardingStatusAwareTrait;
}

Register the AdminUser entity

# config/packages/_sylius.yaml
...

sylius_user:
    resources:
        admin:
            user:
                classes:
                    model: App\Entity\User\AdminUser

10. Run Doctrine Migrations

Update your database schema:

bin/console doctrine:migrations:migrate

11. Frontend Assets Installation

Install assets:

bin/console assets:install

Add the plugin's assets to your entrypoint files:

// assets/admin/entrypoint.js

import '../../vendor/sylius/mollie-plugin/assets/admin/entrypoint';

and:

// assets/shop/entrypoint.js

import '../../vendor/sylius/mollie-plugin/assets/shop/entrypoint';

Add JS dependencies:

yarn add bazinga-translator intl-messageformat lodash.get [email protected]

Build frontend assets:

yarn encore dev # for development
yarn encore production # for production

12. Clear the Symfony Cache

php bin/console cache:clear

🧩 Optional Features

These steps are optional but recommended depending on your use case.

Enable Refunds with Refund Plugin

To support order refunds:

composer require sylius/refund-plugin:^2.0.2 --no-scripts -W

Then follow Refund Plugin Installation Guide.


Refund Plugin Troubleshooting

If you see: Duplicate transition 'complete' in state machine 'sylius_refund_refund_payment'

You likely have legacy state machine config.

Fix: Remove the file:

rm config/packages/sylius_refund.yaml
Load Fixtures

To populate the shop with demo data:

bin/console sylius:fixtures:load
Set Up Apple Pay

To support Apple Pay, upload this file to your server:

public/.well-known/apple-developer-merchantid-domain-association

Usage

During configuration, first save the keys to the database and then click "Load methods".

Last updated

Was this helpful?