Integrating Adyen

Edit on GitHub

There is currently an issue when using giftcards with Adyen. Our team is developing a fix for it.

This article provides step-by-step instructions on integrating the Adyen module into your project.

Prerequisites

Prior to integrating Adyen into your project, make sure you installed and configured the Adyen module.

Project integration

To integrate Adyen, do the following:

Data import

Import payment methods to be able to display them:

data/import/common/common/payment_method.csv

payment_method_key,payment_method_name,payment_provider_key,payment_provider_name,is_active
adyenCreditCard,Adyen Credit Card,Adyen,Adyen,1
adyenSofort,Adyen Sofort,Adyen,Adyen,1
adyenDirectDebit,Adyen Direct Debit,Adyen,Adyen,1
adyenKlarnaInvoice,Adyen Klarna Invoice,Adyen,Adyen,1
adyenPrepayment,Adyen Prepayment,Adyen,Adyen,1
adyenIdeal,Adyen Ideal,Adyen,Adyen,1
adyenPayPal,Adyen PayPal,Adyen,Adyen,1
adyenAliPay,Adyen AliPay,Adyen,Adyen,1
adyenWeChatPay,Adyen WeChatPay,Adyen,Adyen,1

data/import/common/DE/payment_method_store.csv

payment_method_key,store
adyenCreditCard,DE
adyenCreditCard,DE
adyenSofort,DE
adyenDirectDebit,DE
adyenKlarnaInvoice,DE
adyenPrepayment,DE
adyenIdeal,DE
adyenPayPal,DE
adyenAliPay,DE
adyenWeChatPay,DE

OMS

Exemplary content

The state machines provided below are examples of the payment service provider flow.

Create the OMS:

  1. Copy this state machines on the project level and adjust them according to your requirements:
src/Pyz/Zed/Oms/OmsDependencyProvider.php
<?php

$config[OmsConstants::PROCESS_LOCATION] = [
    ...
    APPLICATION_ROOT_DIR . '/vendor/spryker-eco/adyen/config/Zed/Oms', // Is not required after State machine are copied to project level.
];

$config[OmsConstants::ACTIVE_PROCESSES] = [
    ...
    'AdyenCreditCard01',
    'AdyenSofort01',
    'AdyenDirectDebit01',
    'AdyenKlarnaInvoice01',
    'AdyenPrepayment01',
    'AdyenIdeal01',
    'AdyenPayPal01',
    'AdyenAliPay01',
    'AdyenWeChatPay01',
];
$config[SalesConstants::PAYMENT_METHOD_STATEMACHINE_MAPPING] = [
    ...
    AdyenConfig::ADYEN_CREDIT_CARD => 'AdyenCreditCard01',
    AdyenConfig::ADYEN_SOFORT => 'AdyenSofort01',
    AdyenConfig::ADYEN_DIRECT_DEBIT => 'AdyenDirectDebit01',
    AdyenConfig::ADYEN_KLARNA_INVOICE => 'AdyenKlarnaInvoice01',
    AdyenConfig::ADYEN_PREPAYMENT => 'AdyenPrepayment01',
    AdyenConfig::ADYEN_IDEAL => 'AdyenIdeal01',
    AdyenConfig::ADYEN_PAY_PAL => 'AdyenPayPal01',
    AdyenConfig::ADYEN_ALI_PAY => 'AdyenAliPay01',
    AdyenConfig::ADYEN_WE_CHAT_PAY => 'AdyenWeChatPay01',
];
  1. In OmsDependencyProvider, add the OMS command and condition plugins:
src/Pyz/Zed/Oms/OmsDependencyProvider.php
<?php

/**
 * This file is part of the Spryker Suite.
 * For full license information, please view the LICENSE file that was distributed with this source code.
 */

namespace Pyz\Zed\Oms;

...
use SprykerEco\Zed\Adyen\Communication\Plugin\Oms\Command\AuthorizePlugin;
use SprykerEco\Zed\Adyen\Communication\Plugin\Oms\Command\CancelPlugin;
use SprykerEco\Zed\Adyen\Communication\Plugin\Oms\Command\CancelOrRefundPlugin;
use SprykerEco\Zed\Adyen\Communication\Plugin\Oms\Command\CapturePlugin;
use SprykerEco\Zed\Adyen\Communication\Plugin\Oms\Command\RefundPlugin;
use SprykerEco\Zed\Adyen\Communication\Plugin\Oms\Condition\IsAuthorizationFailedPlugin;
use SprykerEco\Zed\Adyen\Communication\Plugin\Oms\Condition\IsAuthorizedPlugin;
use SprykerEco\Zed\Adyen\Communication\Plugin\Oms\Condition\IsCanceledPlugin;
use SprykerEco\Zed\Adyen\Communication\Plugin\Oms\Condition\IsCancellationFailedPlugin;
use SprykerEco\Zed\Adyen\Communication\Plugin\Oms\Condition\IsCancellationReceivedPlugin;
use SprykerEco\Zed\Adyen\Communication\Plugin\Oms\Condition\IsCapturedPlugin;
use SprykerEco\Zed\Adyen\Communication\Plugin\Oms\Condition\IsCaptureFailedPlugin;
use SprykerEco\Zed\Adyen\Communication\Plugin\Oms\Condition\IsCaptureReceivedPlugin;
use SprykerEco\Zed\Adyen\Communication\Plugin\Oms\Condition\IsRefundedPlugin;
use SprykerEco\Zed\Adyen\Communication\Plugin\Oms\Condition\IsRefundFailedPlugin;
use SprykerEco\Zed\Adyen\Communication\Plugin\Oms\Condition\IsRefundReceivedPlugin;
use SprykerEco\Zed\Adyen\Communication\Plugin\Oms\Condition\IsRefusedPlugin;

class OmsDependencyProvider extends SprykerOmsDependencyProvider
{
    ...

    /**
     * @param \Spryker\Zed\Kernel\Container $container
     *
     * @return \Spryker\Zed\Kernel\Container
     */
    public function provideBusinessLayerDependencies(Container $container): Container
    {
        $container = parent::provideBusinessLayerDependencies($container);
        $container = $this->extendCommandPlugins($container);
        $container = $this->extendConditionPlugins($container);

        return $container;
    }

    /**
     * @param \Spryker\Zed\Kernel\Container $container
     *
     * @return \Spryker\Zed\Kernel\Container
     */
    protected function extendCommandPlugins(Container $container): Container
    {
        $container->extend(self::COMMAND_PLUGINS, function (CommandCollectionInterface $commandCollection) {
            ...
            $commandCollection->add(new AuthorizePlugin(), 'Adyen/Authorize');
            $commandCollection->add(new CancelPlugin(), 'Adyen/Cancel');
            $commandCollection->add(new CapturePlugin(), 'Adyen/Capture');
            $commandCollection->add(new RefundPlugin(), 'Adyen/Refund');
            $commandCollection->add(new CancelOrRefundPlugin(), 'Adyen/CancelOrRefund');

            return $commandCollection;
        });

        return $container;
    }

    /**
     * @param \Spryker\Zed\Kernel\Container $container
     *
     * @return \Spryker\Zed\Kernel\Container
     */
    protected function extendConditionPlugins(Container $container): Container
    {
        $container->extend(OmsDependencyProvider::CONDITION_PLUGINS, function (ConditionCollectionInterface $conditionCollection) {
            ...
            $conditionCollection->add(new IsAuthorizationFailedPlugin(), 'Adyen/IsAuthorizationFailed');
            $conditionCollection->add(new IsAuthorizedPlugin(), 'Adyen/IsAuthorized');
            $conditionCollection->add(new IsCanceledPlugin(), 'Adyen/IsCanceled');
            $conditionCollection->add(new IsCancellationFailedPlugin(), 'Adyen/IsCancellationFailed');
            $conditionCollection->add(new IsCancellationReceivedPlugin(), 'Adyen/IsCancellationReceived');
            $conditionCollection->add(new IsCapturedPlugin(), 'Adyen/IsCaptured');
            $conditionCollection->add(new IsCaptureFailedPlugin(), 'Adyen/IsCaptureFailed');
            $conditionCollection->add(new IsCaptureReceivedPlugin(), 'Adyen/IsCaptureReceived');
            $conditionCollection->add(new IsRefundedPlugin(), 'Adyen/IsRefunded');
            $conditionCollection->add(new IsRefundFailedPlugin(), 'Adyen/IsRefundFailed');
            $conditionCollection->add(new IsRefundReceivedPlugin(), 'Adyen/IsRefundReceived');
            $conditionCollection->add(new IsRefusedPlugin(), 'Adyen/IsRefused');

            return $conditionCollection;
        });

        return $container;
    }
}

Router

Add the router:

src/Pyz/Yves/Router/RouterDependencyProvider.php
<?php

namespace Pyz\Yves\Router;

use Spryker\Yves\Router\RouterDependencyProvider as SprykerRouterDependencyProvider;
use SprykerShop\Yves\CheckoutPage\Plugin\Router\CheckoutPageRouteProviderPlugin;
use SprykerEco\Yves\Adyen\Plugin\Router\AdyenRouteProviderPlugin;

class RouterDependencyProvider extends SprykerRouterDependencyProvider
{
    /**
     * @return array<\Spryker\Yves\RouterExtension\Dependency\Plugin\RouteProviderPluginInterface>
     */
    protected function getRouteProvider(): array
    {
        $routeProviders = [
            ...
            new AdyenRouteProviderPlugin(),
        ];

        ...
    }
}
Note

If you provide the Credit Card payment method, you have to overwrite CheckoutPageRouteProviderPlugin with the one from the project level. For details, see Adyen - Provided Payment Methods Credit Card (Step 7).

Checkout

  1. Add the checkout plugins:
src/Pyz/Zed/Checkout/CheckoutDependencyProvider.php
<?php

/**
 * This file is part of the Spryker Suite.
 * For full license information, please view the LICENSE file that was distributed with this source code.
 */

namespace Pyz\Zed\Checkout;

...
use SprykerEco\Zed\Adyen\Communication\Plugin\Checkout\AdyenDoSaveOrderPlugin;
use SprykerEco\Zed\Adyen\Communication\Plugin\Checkout\AdyenPostSaveHookPlugin;

class CheckoutDependencyProvider extends SprykerCheckoutDependencyProvider
{
    ...

    /**
     * @param \Spryker\Zed\Kernel\Container $container
     *
     * @return array<\Spryker\Zed\Checkout\Dependency\Plugin\CheckoutSaveOrderInterface>|array<\Spryker\Zed\CheckoutExtension\Dependency\Plugin\CheckoutDoSaveOrderInterface>
     */
    protected function getCheckoutOrderSavers(Container $container)
    {
        /** @var \Spryker\Zed\Checkout\Dependency\Plugin\CheckoutSaveOrderInterface[] $plugins */
        $plugins = [
            ...
            new AdyenDoSaveOrderPlugin(),
        ];

        return $plugins;
    }

    /**
     * @param \Spryker\Zed\Kernel\Container $container
     *
     * @return array<\Spryker\Zed\CheckoutExtension\Dependency\Plugin\CheckoutPostSaveInterface>
     */
    protected function getCheckoutPostHooks(Container $container)
    {
        return [
            ...
            new AdyenPostSaveHookPlugin(),
        ];
    }
}
  1. Add the subforms of the desired payment methods:
src/Pyz/Yves/CheckoutPage/CheckoutPageDependencyProvider.php
<?php

/**
 * This file is part of the Spryker Suite.
 * For full license information, please view the LICENSE file that was distributed with this source code.
 */

namespace Pyz\Yves\CheckoutPage;

...
use Spryker\Yves\StepEngine\Dependency\Plugin\Form\SubFormPluginCollection;
use SprykerEco\Shared\Adyen\AdyenConfig;
use SprykerEco\Yves\Adyen\Plugin\AdyenPaymentHandlerPlugin;
use SprykerEco\Yves\Adyen\Plugin\StepEngine\AdyenCreditCardSubFormPlugin;
use SprykerEco\Yves\Adyen\Plugin\StepEngine\AdyenDirectDebitSubFormPlugin;
use SprykerEco\Yves\Adyen\Plugin\StepEngine\AdyenIdealSubFormPlugin;
use SprykerEco\Yves\Adyen\Plugin\StepEngine\AdyenKlarnaInvoiceSubFormPlugin;
use SprykerEco\Yves\Adyen\Plugin\StepEngine\AdyenSofortSubFormPlugin;
use SprykerEco\Yves\Adyen\Plugin\StepEngine\AdyenPrepaymentSubFormPlugin;
use SprykerEco\Yves\Adyen\Plugin\StepEngine\AdyenPayPalSubFormPlugin;
use SprykerEco\Yves\Adyen\Plugin\StepEngine\AdyenAliPaySubFormPlugin;
use SprykerEco\Yves\Adyen\Plugin\StepEngine\AdyenWeChatPaySubFormPlugin;
...

class CheckoutPageDependencyProvider extends SprykerShopCheckoutPageDependencyProvider
{
    /**
     * @param \Spryker\Yves\Kernel\Container $container
     *
     * @return \Spryker\Yves\Kernel\Container
     */
    public function provideDependencies(Container $container)
    {
        $container = parent::provideDependencies($container);
        $container = $this->extendPaymentMethodHandler($container);
        $container = $this->extendSubFormPluginCollection($container);

        return $container;
    }

    ...

    /**
     * @param \Spryker\Yves\Kernel\Container $container
     *
     * @return \Spryker\Yves\Kernel\Container
     */
    protected function extendPaymentMethodHandler(Container $container): Container
    {
        $container->extend(static::PAYMENT_METHOD_HANDLER, function (StepHandlerPluginCollection $stepHandlerPluginCollection) {
            $stepHandlerPluginCollection->add(new AdyenPaymentHandlerPlugin(), AdyenConfig::ADYEN_CREDIT_CARD);
            $stepHandlerPluginCollection->add(new AdyenPaymentHandlerPlugin(), AdyenConfig::ADYEN_SOFORT);
            $stepHandlerPluginCollection->add(new AdyenPaymentHandlerPlugin(), AdyenConfig::ADYEN_DIRECT_DEBIT);
            $stepHandlerPluginCollection->add(new AdyenPaymentHandlerPlugin(), AdyenConfig::ADYEN_KLARNA_INVOICE);
            $stepHandlerPluginCollection->add(new AdyenPaymentHandlerPlugin(), AdyenConfig::ADYEN_PREPAYMENT);
            $stepHandlerPluginCollection->add(new AdyenPaymentHandlerPlugin(), AdyenConfig::ADYEN_IDEAL);
            $stepHandlerPluginCollection->add(new AdyenPaymentHandlerPlugin(), AdyenConfig::ADYEN_PAY_PAL);
            $stepHandlerPluginCollection->add(new AdyenPaymentHandlerPlugin(), AdyenConfig::ADYEN_ALI_PAY);
            $stepHandlerPluginCollection->add(new AdyenPaymentHandlerPlugin(), AdyenConfig::ADYEN_WE_CHAT_PAY);

            return $stepHandlerPluginCollection;
        });

        return $container;
    }

    /**
     * @param \Spryker\Yves\Kernel\Container $container
     *
     * @return \Spryker\Yves\Kernel\Container
     */
    protected function extendSubFormPluginCollection(Container $container): Container
    {
        $container->extend(static::PAYMENT_SUB_FORMS, function (SubFormPluginCollection $subFormPluginCollection) {
            $subFormPluginCollection->add(new AdyenCreditCardSubFormPlugin());
            $subFormPluginCollection->add(new AdyenSofortSubFormPlugin());
            $subFormPluginCollection->add(new AdyenDirectDebitSubFormPlugin());
            $subFormPluginCollection->add(new AdyenKlarnaInvoiceSubFormPlugin());
            $subFormPluginCollection->add(new AdyenPrepaymentSubFormPlugin());
            $subFormPluginCollection->add(new AdyenIdealSubFormPlugin());
            $subFormPluginCollection->add(new AdyenPayPalSubFormPlugin());
            $subFormPluginCollection->add(new AdyenAliPaySubFormPlugin());
            $subFormPluginCollection->add(new AdyenWeChatPaySubFormPlugin());

            return $subFormPluginCollection;
        });

        return $container;
    }
}

Filtering

Filter the available payment methods depending on the paymentMethods API result:

src/Pyz/Yves/CheckoutPage/CheckoutPageDependencyProvider.php

<?php

/**
 * This file is part of the Spryker Suite.
 * For full license information, please view the LICENSE file that was distributed with this source code.
 */

namespace Pyz\Zed\Payment;

...
use SprykerEco\Zed\Adyen\Communication\Plugin\AdyenPaymentMethodFilterPlugin;

class PaymentDependencyProvider extends SprykerPaymentDependencyProvider
{
    /**
     * @return array<\Spryker\Zed\PaymentExtension\Dependency\Plugin\PaymentMethodFilterPluginInterface>
     */
    protected function getPaymentMethodFilterPlugins(): array
    {
        return [
            ...
            new AdyenPaymentMethodFilterPlugin(),
        ];
    }
}

Frontend

Add the form templates of the desired payment methods to customForms:

src/Pyz/Yves/CheckoutPage/Theme/default/views/payment/payment.twig
{% define data = {
    backUrl: _view.previousStepUrl,
    forms: {
        payment: _view.paymentForm
    },
    title: 'checkout.step.payment.title' | trans,
    customForms: {
        'Adyen/alipay': ['alipay', 'adyen'],
        'Adyen/credit-card': ['credit-card', 'adyen'],
        'Adyen/direct-debit': ['direct-debit', 'adyen'],
        'Adyen/ideal': ['ideal', 'adyen'],
        'Adyen/klarna-invoice': ['klarna-invoice', 'adyen'],
        'Adyen/paypal': ['paypal', 'adyen'],
        'Adyen/prepayment': ['prepayment', 'adyen'],
        'Adyen/sofort': ['sofort', 'adyen'],
        'Adyen/wechatpay': ['wechatpay', 'adyen'],
    }
} %}

...

{% embed molecule('form') with {
    ...
    data: {
       ...
       submit: {
           ...
           class: '... js-payment-form__submit',
       },
    }