Adyen Payment Components Integration

Follow this guide to implement the Adyen Payment Components integration for use on your websites basket or PDP (product display page). For Apple Pay & Google Pay, please make sure the payment methods are correctly enabled in your Adyen Merchant account. For Apple Pay, take special care to correctly configure your website URL's when you add the Apple Pay method from within Adyen. If you get it wrong, Apple Pay will not work and you will have to contact Adyen support to have it removed and then you can re-add it.

Files & Templates

FilePurposeNotes
templates/example.com/_js/aapc.jsAurora Adyen Payment Components Javascript LibraryThis script should be added to whichever page is using the Adyen Payments Component
templates/example.com/_js/aapc.applepay.jsAurora Adyen Apple Pay Payment Components Javascript LibraryThis script should be added to whichever page is using the Adyen Apple Pay Payments Component
templates/example.com/_js/aapc.googlepay.jsAurora Adyen Google Pay Payment Components Javascript LibraryThis script should be added to whichever page is using the Adyen Google Pay Payments Component
templates/example.com/_js/basket.jsThe main Basket functionalityThis file should contain code which configures the Aurora Adyen Payment Components when values are changed on the basket page
templates/example.com/_js/product_attributes.jsThe main product attributes functionalityThis file should contain code which configures the Aurora Adyen Payment Components when attribute options are changed on the product page
templates/example.com/basket/adyen-buttons.tpl.htmlTemplate for displaying Aurora Adyen Payment Components on the BasketThis template will be loaded on the Basket page. It includes all of the main component JavaScript libraries and configures them. It includes store information, currencies, prices and so on.
templates/example.com/basket/index.tpl.htmlTemplate for the main basket page.This template includes the above Adyen buttons template.
templates/example.com/products/adyen-buttons.tpl.htmlTemplate for displaying Aurora Adyen Payment Components on the BasketThis template will be loaded on the Product page. It includes all of the main component JavaScript libraries and configures them. It includes store information, currencies, prices, shipping and so on.

Modifications to demo files

There have been some modifications to Aurora Demo files to facilitate Adyen Payment Components. Those updates will need to be migrated to your websites templates. In all cases, please compare your files to that of Aurora Demo to find where the modifications need to be made.

  1. templates/example.com/products/details.tpl.html
  2. templates/example.com/_js/product_attributes.js
  3. templates/example.com/basket/index.tpl.html

templates/example.com/products/details.tpl.html

The following snippet was added to show checkout errors on the product page.

<div class="errorbox" id="product-errors-container" style="display: none">
    <h2>{site_text page="Global" part="Warning: Error has occured"}</h2>
    <ul></ul>
</div>

The next snippet includes the Adyen Payment Components template which configures the buttons.

<br />
{include file="products/adyen-buttons.tpl.html"}

templates/example.com/_js/product_attributes.js

The below snippet has been added to refresh the Adyen Payment Components when a products selected attribute value has changed which could cause a change in price.

//Where the Adyen Payment Components library is loaded, load/update the button
if (typeof($.aapc)==="object") {
    $.aapc.updateFromProductReference(response.variation_reference, response.variation_stock, 1);
}

templates/example.com/basket/index.tpl.html

This last snippet includes the Adyen Payment Components template which configures the buttons (on the basket page).

{include file="basket/adyen-buttons.tpl.html"}

Please note that these are all provided with a view to having them working within the Aurora demo website. As such, if you have customised your templates and their supporting JavaScript files away from the standard Aurora Demo implementations, you may need to use these files for 'inspiration' only.

JavaScript configuration for the PDP components

The component configuration is gathered in templates/example.com/basket/adyen-buttons.tpl.html and used to populate the main component and the individual payment components (Apple Pay & Google Pay)

let containerSelector = "#adyen-components-container";
var userId = '{$smarty.session.user.id}';
var country = '{$default_country_iso2|upper}';
var locale = '{$language_iso_selected}';
var viewCurrency = '{$currency_iso|upper}';
var chargeableCurrency = '{$currency_iso_chargeable|upper}';
var productReference = '{$product.product_reference}';
var productStock = '{$product.product_stock}';
var productQuantity = $('#product_quantity').val();
var productHasVariations = {if $variations|count > 0}true{else}false{/if};

The above gathers data from the Smarty variables and populates JavaScript variables.

$(document).ready(function() {
    // Set the Adyen components core
    $.aapc.setup({
        placement: $.aapc.placements.pdp,
        userId: userId,
        country: country,
        locale: locale,
        viewCurrency: viewCurrency,
        chargeableCurrency: chargeableCurrency,
        containerSelector: containerSelector,
    });
    // Set the Apple Pay component
    $.aapc.applepay.setup({
        buttonType: "plain",
        buttonColor: "black",
    });
    // Set the Google Pay component
    $.aapc.googlepay.setup({
        environment: "TEST", // TEST or PRODUCTION
        gatewayMerchantId: "AuroraCommerceAdmin", // Your Adyen merchant or company account name
        //merchantIdentifier: "", // Required for PRODUCTION. Removed for TEST. Your Google Merchant ID
        merchantName: "Aurora Commerce", // The name that appears in the payment sheet.
    });
    // Only load the payment components where there are no variations,
    // otherwise rely on the variation selection hook with product_attributes.js
    if (!productHasVariations) {
        $.aapc.loadFromProductReference(productReference, productStock, productQuantity);
    }
});

 // Update the payment components when the product quantity is changed
$(document).on('change', '#product_quantity', function() {
    $.aapc.updateLineFromQuantity(0, $(this).val());
});

The above uses the collected configuration values to setup the Adyen Payment Components.First, the main component $.aapc.setup is configured, then each of the individual methods, $.aapc.applepay.setup & $.aapc.googlepay.setup. Next, if the product does not have any variation, we load the components. If there are variations, this task is delegated to product_attributes.js.Finally, after configuring the components it is necessary to make sure event listeners are registered to reload the components when the product quantity has changed.Please find below an explanation of each configuration option.Main Component

OptionTypeExample valueNotes
placementString$.aapc.placements.pdpThe location of the component so it knows which actions to perform.
userIdStringuserId variableThe user ID of the customer.
countryStringGBThe uppercased 2 letter ISO2 country code.
localeStringen-GBThe customers currently selected language code.
viewCurrencyStringEURThe customers currently selected currency code.
chargeableCurrencyStringGBPThe currency the customer should be charged in.
containerSelectorDOM Selector as String#adyen-components-containerAdyen's components will be loaded within this element.

Apple Pay

Google Pay

OptionTypeExample valueNotes
environmentStringTESTTEST or PRODUCTION
gatewayMerchantIdStringAuroraCommerceAdminYour Adyen merchant or company account name. This is optional and if not specified it will use the account configured in the plugin settings. If specified, merchantName should also be specified.
merchantIdentifierStringRequired for PRODUCTION. Removed for TEST. Your Google Merchant ID.
merchantNameStringAurora CommerceThe name that appears in the payment sheet. This is optional and if not specified it will use the account configured in the plugin settings. If specified, gatewayMerchantId should also be specified.

JavaScript configuration for the Basket components

The component configuration is gathered in templates/example.com/basket/adyen-buttons.tpl.html and used to populate the main component and the individual payment components (Apple Pay & Google Pay)

let userId = '{$smarty.session.user.id}';
let locale = '{$language_iso_selected}';
let viewCurrency = '{$currency_iso|upper}';
let chargeableCurrency = '{$currency_iso_chargeable|upper}';
let amountTotal = '{$paymentCostChargeable}';
let countryMap = [];
{if $country_list}{foreach from=$country_list item="info"}
    countryMap['{$info.id}'] = '{$info.iso2|upper}';
{/foreach}{/if}
let countryID = $('#basket_country').val();
let countryISO = countryID.length > 0 && typeof(countryMap[countryID]) !== "undefined" ? countryMap[countryID] : 'GB';
let countryList = []
{if $country_list}{foreach from=$country_list item="info"}
    countryList.push('{$info.iso2|upper}');
{/foreach}{/if}
{if $delivery_store_info}
    let selectedStoreData = {literal}{{/literal}
        address_1: '{$delivery_store_info.address_1}',
        address_2: '{$delivery_store_info.address_2}',
        name: '{$delivery_store_info.company_name}',
        town: '{$delivery_store_info.town}',
        filename: '{$delivery_store_info.filename}',
        county: '{$delivery_store_info.county}',
        country: '{$delivery_store_info.country}',
        country_id: '{$delivery_store_info.country_id}',
        country_code: '{$delivery_store_info.country_code}',
        postcode: '{$delivery_store_info.postcode}',
    {literal}}{/literal};
{else}
    let selectedStoreData = null;
{/if}
let selectedDeliveryType = $('#basket_choose_delivery_type:checked').val();
let selectedDeliveryOption = $('#basket_delivery_option').val();
let containerSelector = "#adyen-components-container";
let basketUserReference = "{$userReference}";

The above gathers data from the Smarty variables and populates JavaScript variables.

$(document).ready(function() {
    // Set the Adyen components core
    $.aapc.setup({
        placement: $.aapc.placements.basket,
        userId: userId,
        country: countryISO,
        locale: locale,
        viewCurrency: viewCurrency,
        chargeableCurrency: chargeableCurrency,
        availableCountryList: countryList,
        selectedDeliveryType: selectedDeliveryType,
        selectedDeliveryOption: selectedDeliveryOption,
        selectedStoreData: selectedStoreData,
        containerSelector: containerSelector,
        basketUserReference: basketUserReference
    });
    // Set the Apple Pay component
    $.aapc.applepay.setup({
        buttonType: "plain",
        buttonColor: "black",
    });
    // Set the google page component
    $.aapc.googlepay.setup({
        environment: "TEST", // TEST or PRODUCTION
        gatewayMerchantId: "AuroraCommerceAdmin", // Your Adyen merchant or company account name
        //merchantIdentifier: "", // Required for PRODUCTION. Removed for TEST. Your Google Merchant ID
        merchantName: "Aurora Commerce", // The name that appears in the payment sheet.
    });
    // Load the payment buttons
    $.aapc.loadFromStoredBasketUserReference();


    $.frontend.events.on('collect_plus.save.after', async () => {
        $.aapc.updateFromStoredBasketUserReference();
    });
});

$(document).on('change', '#basket_choose_delivery_type', function() {
    $.aapc.setSelectedDeliveryType($('#basket_choose_delivery_type:checked').val());
    $.aapc.setSelectedDeliveryOption($('#basket_delivery_option').val());
    $.aapc.updateFromStoredBasketUserReference();
});

The above uses the collected configuration values to setup the Adyen Payment Components.First, the main component $.aapc.setup is configured, then each of the individual methods, $.aapc.applepay.setup & $.aapc.googlepay.setup. Next, we load the components.Finally, after configuring the components it is necessary to make sure event listeners are registered to reload the components when the basket delivery type is changed and when collected plus is used.Please find below an explanation of each configuration option.

Main Component

OptionTypeExample valueNotes
placementString$.aapc.placements.basketThe location of the component so it knows which actions to perform.
userIdStringuserId variableThe user ID of the customer.
countryStringGBThe uppercased 2 letter ISO2 country code.
localeStringen-GBThe customers currently selected language code.
viewCurrencyStringEURThe customers currently selected currency code.
chargeableCurrencyStringGBPThe currency the customer should be charged in.
availableCountryListArray['UK', 'FR']An array of countries to accept payments from.
selectedDeliveryTypeStringstore OR homeThe selected delivery type, which the customer has selected on the basket.
selectedDeliveryOptionInteger96The selected delivery option ID.
selectedStoreData`Nul|Object`An object containing the store data.
containerSelectorDOM Selector as String#adyen-components-containerAdyen's components will be loaded within this element.
basketUserReferenceStringac1-ab63d41ac35An ID representing the customers current basket.

Apple Pay

Google Pay

OptionTypeExample valueNotes
environmentStringTESTTEST or PRODUCTION
gatewayMerchantIdStringAuroraCommerceAdminYour Adyen merchant or company account name
merchantIdentifierStringRequired for PRODUCTION. Removed for TEST. Your Google Merchant ID.
merchantNameStringAurora CommerceThe name that appears in the payment sheet.

Component Usage

Once the components have been loaded with loadFromStoredBasketUserReferenc or loadFromProductReference the payment buttons will be rendered in the provided HTML element.

Clicking on the payment buttons will show the payment sheet for the respective method. Depending on the location and the delivery method the sheets will present different information and options.

On the PDP, the payment sheets will present the available shipping options which the customer can choose from.

On the Basket, the payment sheets will not present the available shipping options, they are managed by the basket page. If the customer wants to change the method they should close the payment sheet and modify the shipping option on the basket. This will cause the components to re-render and then the customer can proceed to payment again.

On the Basket, when a customer selects a store delivery type, such as Store Delivery, when they continue to payment the delivery address selection field will not be available.

After a customer has finished the payment, as long as everything was successful, the customer will be redirected to the order complete page.

Updating the components

When changes are made to the basket that will result in price, shipping or item modifications, the payment components need to reinitialised with the correct values. There are various hooks to accomplish this.

$.aapc.updateFromStoredBasketUserReference() - This will reload the components based on the user basket reference which is set as part of the component configuration on the basket.

$.aapc.loadFromProductReference() - This will create a new basket based on the given product configuration and should be used on the PDP.

$.aapc.updateLineFromQuantity() - This will update the quantity of a specific line item and should be used on the PDP.

Error Handling

When checking out via Adyen Payment Components we provide a default error handler for the Checkout Setup Submit endpoint. This error handler can be found below and does the following:

  1. If purchasing from the Basket and an error occurs, redirect back to the basket where the errors will be printed on the page.
  2. If purchasing from the PDP and an error occurs, extract the errors from the AJAX response and append them to the error box and scroll it in to view.
$.aapc.handleErrors = function (errors, redirectUrl, placement) {
    //if we're on the PDP, show errors in an errorbox
    if (placement === $.aapc.placements.pdp) {
        const errorContainer = $($.aapc.components.productErrorsSelector + ' > ul');
        errorContainer.empty();
        errors.forEach(e => errorContainer.append(`<li>${e}</li>`))
        errorContainer.parent().css("display", "block");
        window.scrollTo(0, 0);
        return;
    }

    //if we're anywhere else, just redirect to page the framework instructs us to
    window.location.replace(redirectUrl);
}

You can replace this error handler with any mechanism you please, which could display errors in popups or just redirect back to the product/basket page. To define your own error handler, redefine the function on the $.aapc component in your template or additional JavaScript file. For example, in templates/example.com/products/adyen-buttons.tpl.html before you call $.aapc.setup() you can define:

$.aapc.handleErrors = function (errors, redirectUrl, placement) {

}

The first parameters is an array of string error messages. The second is a string URL which you can redirect to, to present the errors and lastly placement is a string containing the placement of the component, it will be one of:

$.aapc.placements.pdp = "pdp";
$.aapc.placements.basket = "basket";

Allowing you to handler errors differently, based on the components location.

Basket Restoring from the PDP

When purchasing from the product page, the customers existing basket is saved for the duration of the checkout. When the purchase (from the PDP) is finished, the previous basket is restored.

This is achieved by first creating a "temporary" basket when the Adyen Payment Components are initialised. When payment commences, the existing permanent basket is swapped with the temporary one so that the payment process can work seamlessly. Once complete the permanent basket is restored again.

This process is handled in $.aapc.setupSubmit()