Table of Contents

Adyen

Implementing Adyen as payment provider

Adyen is a Dutch payment company which enables you to accept electronic payment using a variety of payment methods, like credit cards, debit cards, etc.

You can sign up for an Adyen test account here.

To configure Adyen Checkout you need the following 5 keys:

After obtaining the 5 keys you can configure the payment method

  1. Open Settings > Areas > Commerce > Order Management > Payment and click '+ New payment
  2. Select the Adyen Checkout payment provider and configure it

Adyen

The following settings are available:

Section Setting Use Notes
General Merchant name The Adyen account name
API key The Adyen API key
Client key The Adyen Client key
Live URL prefix If it is not set, the test mode will be used, even if corresponding checkbox is not checked
Allow save cards Check to allow users to save cards via Adyen
Skip security code for one-off payments If not checked, the provider will redirect you to a template where you can enter the security code of your saved card. If checked, the provider will attempt to complete the payment transaction using the stored card data. Please note: SkipCvCForOneClick must be enabled on your Adyen account to make it work.
Test mode Switch between live/test mode
Debug mode
Template settings Payments template This template renders the payment form
Cancel template This payment renders the feedback if the user cancels a payment
Error template This payment renders errors from Adyen if they occur
Notification settings HMAC key If it is not set, notification processing will not be performed, even if it is configured in the Adyen control panel.

Payment templates

Templates for the Adyen provider should be placed in an Adyen-folder with subfolders located under Files/Templates/eCom7/CheckoutHandler:

/CheckoutHandler/
├── Adyen/
│   ├── Cancel/
│   │   ├── cancel_payment.cshtml
│   ├── Card/
│   │   ├── saved_card.cshtml
│   ├── Error/
│   │   ├── payment_error.cshtml
│   ├── Form/
│   │   ├── payment_form.cshtml

If it's not available on your solution, the standard payment form template we supply looks like this:

@using System.Collections.Generic
@using Dynamicweb.Rendering
@inherits RazorTemplateBase<RazorTemplateModel<Template>>

@{
    var supportedLocales = new HashSet<string>(
        new[] { "zh-CN", "zh-TW", "da-DK", "nl-NL", "en-US", "fi-FI", "fr-FR", "de-DE", "it-IT", "ja-JP", "ko-KR", "no-NO", "pl-PL", "pt-BR", "ru-RU", "es-ES", "sv-SE" },
        StringComparer.OrdinalIgnoreCase
    );
    var currentLocale = GetGlobalValue("Global:Area.Culture.Name");
    if (!supportedLocales.Contains(currentLocale))
    {
        currentLocale = "en-US";
    }
}

<script src="@GetString("Adyen.JavaScriptUrl")"
        integrity="@GetString("Adyen.JsIntegrityKey")"
        crossorigin="anonymous"></script>

<link rel="stylesheet" href="@GetString("Adyen.CssUrl")"
      integrity="@GetString("Adyen.CssIntegrityKey")"
      crossorigin="anonymous">

<div id="dropin-container"></div>

<script type="module">
    const baseUrl = '/Default.aspx?ID=@GetGlobalValue("Global:Page.ID")&CheckoutHandlerOrderID=@GetString("Ecom:Order.ID")&redirect=false';
    const configuration = {
        onSubmit: function (state, dropin) {
            dropin.setStatus('loading');
            processPaymentOperation(baseUrl + '&Action=SelectMethod', state.data, dropin);
        },
        onAdditionalDetails: (state, dropin) => { },
        onPaymentCompleted: (result, component) => { },
        showPayButton: true,
        locale: '@currentLocale',
        environment: '@GetString("Adyen.Environment")',
        clientKey: '@GetString("Adyen.ClientKey")',
        amount: {
            currency: '@GetString("Adyen.Currency")',
            value: @GetLong("Adyen.Price")
        },
        session: {
            id: '@GetString("Adyen.PaymentSessionId")',
            sessionData: '@GetString("Adyen.PaymentSessionData")'
        }
    };

    const checkout = await AdyenCheckout(configuration);
    checkout.create('dropin').mount('#dropin-container');

    async function processPaymentOperation(url, data, dropin) {
        const configuration = {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(data)
        };
        const response = await fetch(url, configuration);
        if (!response.ok) {
            showError(`Something went wrong. Response status: ${response.status}`, dropin);
            return;
        }

        const json = await response.json();
        if (json.redirectToReceipt) {
            // show payment result and redirect to receipt
            dropin.setStatus("success");
            setTimeout(function () {
                document.location = json.redirectToReceipt;
            }, 1500);
            return;
        }

        if (json.action) {
            dropin.handleAction(json.action);
        } else if (json.errorCode) {
            showError(json.message, dropin);
        } else {
            showError("Something went wrong.", dropin);
        }
    }

    function showError(message, dropin) {
        if (message && message.length > 0) {
            dropin.setStatus("error", { message: message });
        } else {
            dropin.setStatus("error");
        }
    }
</script>

The standard saved card payment form could look like this:

@using System.Collections.Generic
@using Dynamicweb.Rendering
@inherits RazorTemplateBase<RazorTemplateModel<Template>>

@{
    var supportedLocales = new HashSet<string>(
        new[] { "zh-CN", "zh-TW", "da-DK", "nl-NL", "en-US", "fi-FI", "fr-FR", "de-DE", "it-IT", "ja-JP", "ko-KR", "no-NO", "pl-PL", "pt-BR", "ru-RU", "es-ES", "sv-SE" },
        StringComparer.OrdinalIgnoreCase
    );
    var currentLocale = GetGlobalValue("Global:Area.Culture.Name");
    if (!supportedLocales.Contains(currentLocale))
    {
        currentLocale = "en-US";
    }
}

<script src="@GetString("Adyen.JavaScriptUrl")"
        integrity="@GetString("Adyen.JsIntegrityKey")"
        crossorigin="anonymous"></script>

<link rel="stylesheet" href="@GetString("Adyen.CssUrl")"
      integrity="@GetString("Adyen.CssIntegrityKey")"
      crossorigin="anonymous">

<div id="card-container"></div>
<span style="color:red" id="errorsContainer"></span>

<script type="module">
    const baseUrl = '/Default.aspx?ID=@GetGlobalValue("Global:Page.ID")&CheckoutHandlerOrderID=@GetString("Ecom:Order.ID")&redirect=false';
    const configuration = {
        onSubmit: function (state, card) {
            processPaymentOperation(baseUrl + '&Action=UseSavedMethod', state.data, card);
        },
        onAdditionalDetails: (state, card) => { },
        onPaymentCompleted: (result, card) => { },
        showPayButton: true,
        locale: '@currentLocale',
        environment: '@GetString("Adyen.Environment")',
        clientKey: '@GetString("Adyen.ClientKey")',
        amount: {
            currency: '@GetString("Adyen.Currency")',
            value: @GetLong("Adyen.Price")
        },
        enableStoreDetails: true,
        paymentMethodsResponse: JSON.parse(`@GetString("Adyen.PaymentMethods")`)
    };

    const checkout = await AdyenCheckout(configuration);
    const paymentMethod = checkout.paymentMethodsResponse.storedPaymentMethods[0];
    const cardComponent = checkout.create('card', paymentMethod).mount('#card-container');

    async function processPaymentOperation(url, data, card) {
        const configuration = {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(data)
        };
        const response = await fetch(url, configuration);
        if (!response.ok) {
            showError(`Something went wrong. Response status: ${response.status}`);
            return;
        }

        const json = await response.json();
        if (json.redirectToReceipt) {
            document.location = json.redirectToReceipt;
            return;
        }

        if (json.action) {
            card.handleAction(json.action);
        } else if (json.errorCode) {
            showError(json.message);
        } else {
            showError(null);
        }
    }

    function showError(message) {
        const errorsContainer = document.getElementById("errorsContainer");
        errorsContainer.textContent = message && message.length > 0 ? message : "Unhandled error is occured";
    }
</script>

Testing Adyen

Adyen supplies test cards which can be used to test the setup. Please note that some features, like saved cards, must be enabled in the Adyen administration before they work in DynamicWeb.

Please note that Adyen requires SSL & a public URL in order to complete a test payment. You must also add the website URL as an allowed origin under Developers > Api Credentials in the Adyen administration interface.

To top