If you want to migrate to a newer version of the Cartridge, see Migrating to version 20.1.0.
If you are using SiteGenesis, you need to add Adyen-specific code to the storefront core code.
For a controller-based integration, you also need to implement changes in the storefront controller code. For a description of these changes, refer to Storefront controller changes.
If you use SFRA, you can skip this page – there are no code changes needed.
Storefront core changes
Below are the changes that you have to implement in the storefront core code, for each file. To find these files, go to app_storefront_core > cartridge.
forms/default/creditcard.xml
-
Add code under the specified line:
<!-- field for credit card owner --> <field formid="owner" label="creditcard.ownerlabel" type="string" mandatory="true" max-length="40" binding="creditCardHolder" missing-error="creditcard.ownermissingerror"/> <!-- ---------------------- ADD THE CODE BELOW ---------------------- --> <field formid="adyenEncryptedCardNumber" type="string" mandatory="false" binding="adyenEncryptedCardNumber"/> <field formid="adyenEncryptedExpiryMonth" type="string" mandatory="false" binding="adyenEncryptedExpiryMonth"/> <field formid="adyenEncryptedExpiryYear" type="string" mandatory="false" binding="adyenEncryptedExpiryYear"/> <field formid="adyenEncryptedSecurityCode" type="string" mandatory="false" binding="adyenEncryptedSecurityCode"/> <field formid="browserInfo" type="string" mandatory="false" binding="browserInfo"/>
-
Add code under the specified line:
<field formid="saveCard" label="creditcard.savecard" type="boolean" mandatory="false" default-value="true" /> <!-- ---------------------- ADD THE CODE BELOW ---------------------- --> <!-- field for credit card recurring payments / tokenization --> <field formid="selectedCardID" mandatory="false" type="string"/>
js/pages/account.js
-
Require the Adyen Checkout module:
var giftcert = require('../giftcert'), tooltip = require('../tooltip'), util = require('../util'), dialog = require('../dialog'), page = require('../page'), login = require('../login'), validator = require('../validator'), // ---------------------- ADD THE CODE BELOW ---------------------- adyenCheckout = require('../adyen-checkout');
-
Modify the
initializePaymentForm
function:function initializePaymentForm() { $('#CreditCardForm').on('click', '.cancel-button', function (e) { e.preventDefault(); dialog.close(); }); // ---------------------- ADD THE CODE BELOW ---------------------- if (SitePreferences.ADYEN_SF_ENABLED) { adyenCheckout.initAccount(); }
js/pages/checkout/billing.js
-
Require the Adyen Checkout module:
var ajax = require('../../ajax'), formPrepare = require('./formPrepare'), giftcard = require('../../giftcard'), util = require('../../util'), // ---------------------- ADD THE CODE BELOW ---------------------- adyenCheckout = require('../../adyen-checkout');
-
Modify the
setCCFields
function:function setCCFields (data){ // ... $creditCard.find('input[name$="_cvn"]').val('').trigger('change'); // ---------------------- ADD THE CODE BELOW ---------------------- $creditCard.find('[name$="creditCard_selectedCardID"]').val(data.selectedCardID).trigger('change');
-
Add the following functions:
/** * @function * @description Changes the payment type or issuerId of the selected payment method * @param {String, Boolean} value of payment type or issuerId and a test value to see which one it is, to which the payment type or issuerId should be changed to */ function updatePaymentType(selectedPayType, issuerType) { if(issuerType){ $('[name="issuer"]').val(selectedPayType); } else{ $('input[name="brandCode"]').removeAttr('checked'); $('input[value=' + selectedPayType + ']').prop('checked', 'checked'); } formPrepare.validateForm(); }
-
In the
exports.init
function, add the following variable definitions:exports.init = function () { // ... var selectedPaymentMethod = $selectPaymentMethod.find(':checked').val(); // ---------------------- ADD THE CODE BELOW ---------------------- var $payType = $('[name="brandCode"]'); var $issuer = $('.issuer'); var selectedPayType = $payType.find(':checked').val();
-
Modify the
exports.init
function:exports.init = function () { // ... $selectPaymentMethod.on('click', 'input[type="radio"]', function () { updatePaymentMethod($(this).val()); // ---------------------- ADD THE CODE BELOW ---------------------- if ($(this).val() == 'Adyen' && $payType.length > 0) { // set payment type of Adyen to the first one updatePaymentType((selectedPayType) ? selectedPayType : $payType[0].value, false); } else { $payType.removeAttr('checked'); } }); $issuer.on('change', function () { updatePaymentType($(this).val(), true);
-
Add code to the
exports.init
function:exports.init = function () { // ... $giftCertCode.on('keydown', function (e) { if (e.which === 13) { e.preventDefault(); $addGiftCert.click(); } }); // ---------------------- ADD THE CODE BELOW ---------------------- if (SitePreferences.ADYEN_SF_ENABLED) { adyenCheckout.initBilling(); } $payType.on('change', function() { $('#selectedIssuer').val(""); $issuer.hide(); $('.checkoutComponent').hide(); $('#component_' + $(this).val()).show(); if($(this).siblings( ".issuer").length > 0){ $('#selectedIssuer').val($(this).siblings( ".issuer" ).val()); $(this).siblings('.issuer').show(); } });
scripts/util/Resource.ds
-
Add Adyen helper:
/** * Resource helper * */ //... var ProductAvailabilityModel = require('dw/catalog/ProductAvailabilityModel'); // ---------------------- ADD THE CODE BELOW ---------------------- /* Script Modules */ var AdyenHelper = require ("int_adyen_overlay/cartridge/scripts/util/AdyenHelper");
-
Add a new validation message:
// Validation messages // ... VALIDATE_MIN : Resource.msg('validate.min', 'forms', null), // ---------------------- ADD THE CODE BELOW ---------------------- ADYEN_CC_VALIDATE : Resource.msg('adyen.creditcard', 'adyen', null)
-
Modify the
ResourceHelper.getPreferences
function:ResourceHelper.getPreferences = function(pageContext) { var cookieHintAsset = ContentMgr.getContent('cookie_hint'); return { // ... CHECK_TLS:Site.getCurrent().getCustomPreferenceValue('checkTLS'), // ---------------------- ADD THE CODE BELOW ---------------------- ADYEN_SF_ENABLED : AdyenHelper.getAdyenSecuredFieldsEnabled()
templates/default/account/payment/paymentinstrumentdetails.isml
-
Add code under the specified line:
<isscript> <!-- ... --> var numberAttributes = { maxlength: 16, size: 17 }; </isscript> <!-- ---------------------- ADD THE CODE BELOW ---------------------- --> <isset name="AdyenHelper" value="${require('int_adyen_overlay/cartridge/scripts/util/AdyenHelper')}" scope="pdict" /> <isset name="AdyenSecuredFieldsEnabled" value="${pdict.AdyenHelper.getAdyenSecuredFieldsEnabled()}" scope="page" /> <isif condition="${AdyenSecuredFieldsEnabled}"> <isinclude template="account/payment/adyenpaymentinstrumentdetails"/> <iselse/>
-
Close the tag:
<button class="cancel cancel-button simple" type="submit" name="${pdict.CurrentForms.paymentinstruments.creditcards.cancel.htmlName}" value="${Resource.msg('global.cancel','locale',null)}"> ${Resource.msg('global.cancel', 'locale', null)} </button> </div> <!-- ---------------------- ADD THE CODE BELOW ---------------------- --> </isif>
templates/default/checkout/billing/billing.isml
Replace the following:
<div class="form-row form-row-button">
<button class="button-fancy-large" type="submit" name="${pdict.CurrentForms.billing.save.htmlName}" value="${Resource.msg('global.continueplaceorder','locale',null)}"><span>${Resource.msg('global.continueplaceorder','locale',null)}</span></button>
</div>
with:
<div class="form-row form-row-button">
<isif condition="${(pdict.AdyenHelper && pdict.AdyenHelper.getAdyenSecuredFieldsEnabled()) || pdict.AdyenSecuredFieldsEnabled === true}">
<button class="button-fancy-large" type="hidden" id="billing-submit-hidden" style="display:none" name="${pdict.CurrentForms.billing.save.htmlName}" value="${Resource.msg('global.continueplaceorder','locale',null)}"><span>${Resource.msg('global.continueplaceorder','locale',null)}</span></button>
<button class="button-fancy-large" type="submit" id="billing-submit" name="${pdict.CurrentForms.billing.save.htmlName}" value="${Resource.msg('global.continueplaceorder','locale',null)}"><span>${Resource.msg('global.continueplaceorder','locale',null)}</span></button>
<iselse/>
<button class="button-fancy-large" type="submit" name="${pdict.CurrentForms.billing.save.htmlName}" value="${Resource.msg('global.continueplaceorder','locale',null)}"><span>${Resource.msg('global.continueplaceorder','locale',null)}</span></button>
</isif>
</div>
templates/default/checkout/billing/creditcardjson.isml
Add the following key-value pair:
expirationYear:pdict.SelectedCreditCard.creditCardExpirationYear,
<!-- ---------------------- ADD THE CODE BELOW ---------------------- -->
selectedCardID:pdict.SelectedCreditCard.UUID
templates/default/checkout/billing/paymentmethods.isml
-
Add code under the specified line:
<div class="payment-method <isif condition="${empty(pdict.selectedPaymentID) || pdict.selectedPaymentID=='CREDIT_CARD'}">payment-method-expanded</isif>" data-method="CREDIT_CARD"> <!-- ---------------------- ADD THE CODE BELOW ---------------------- --> <isset name="AdyenHelper" value="${require('int_adyen_overlay/cartridge/scripts/util/AdyenHelper')}" scope="pdict"/> <isset name="AdyenSecuredFieldsEnabled" value="${pdict.AdyenHelper.getAdyenSecuredFieldsEnabled()}" scope="page" /> <isif condition="${AdyenSecuredFieldsEnabled}"> <isinclude template="checkout/billing/adyenpaymentmethods"/> </isif>
-
In the Custom processor section, add the Adyen payment method:
<iscomment> Custom processor -------------------------------------------------------------- </iscomment> <div class="payment-method <isif condition="${!empty(pdict.selectedPaymentID) && pdict.selectedPaymentID=='PayPal'}">payment-method-expanded</isif>" data-method="Custom"> <!-- Your custom payment method implementation goes here. --> ${Resource.msg('billing.custompaymentmethod','checkout',null)} </div> <!-- ---------------------- ADD THE CODE BELOW ---------------------- --> <div class="payment-method <isif condition="${!empty(pdict.selectedPaymentID) && pdict.selectedPaymentID=='Adyen'}">payment-method-expanded</isif>" data-method="Adyen"> <isinclude template="hpp"/> </div>
-
To accept payments from POS devices, add code under the specified line:
<div class="payment-method <isif condition="${!empty(pdict.selectedPaymentID) && pdict.selectedPaymentID=='Adyen'}">payment-method-expanded</isif>" data-method="Adyen"> <isinclude template="hpp"/> </div> <!-- ---------------------- ADD THE CODE BELOW ---------------------- --> <div class="payment-method <isif condition="${!empty(pdict.selectedPaymentID) && pdict.selectedPaymentID=='AdyenPOS'}">payment-method-expanded</isif>" data-method="AdyenPOS"> <isinclude template="pos"/> </div>
templates/default/checkout/summary/summary.isml
Add code under the specified line:
<input type="hidden" name="${dw.web.CSRFProtection.getTokenName()}" value="${dw.web.CSRFProtection.generateToken()}"/>
<!-- ---------------------- ADD THE CODE BELOW ---------------------- -->
<iscomment>
Set the brandcode and issuerId in session for when user hits the back button on Adyen hpp
</iscomment>
<isif condition="${!empty(pdict.CurrentHttpParameterMap.brandCode.value) || !empty(session.custom.brandCode)}">
<isset name="brandCode" value="${!empty(pdict.CurrentHttpParameterMap.brandCode.value) ? pdict.CurrentHttpParameterMap.brandCode.value : session.custom.brandCode}" scope="page"/>
<input type="hidden" name="brandCode" value="${brandCode}" />
<isif condition="${!empty(pdict.CurrentHttpParameterMap.issuer.value) || !empty(session.custom.issuer)}">
<isset name="issuer" value="${!empty(pdict.CurrentHttpParameterMap.issuer.value) ? pdict.CurrentHttpParameterMap.issuer.value : session.custom.issuer}" scope="session"/>
<input type="hidden" name="issuer" value="${session.custom.issuer}" />
</isif>
<isset name="brandCode" value="${!empty(pdict.CurrentHttpParameterMap.brandCode.value) ? pdict.CurrentHttpParameterMap.brandCode.value : session.custom.brandCode}" scope="session"/>
<isset name="dob" value="${!empty(pdict.CurrentHttpParameterMap.dob.value) ? pdict.CurrentHttpParameterMap.dob.value : ''}" scope="session"/>
<isset name="gender" value="${!empty(pdict.CurrentHttpParameterMap.gender.value) ? pdict.CurrentHttpParameterMap.dob.value : ''}" scope="session"/>
</isif>
Storefront controller changes
If you integrate via the controller method, you have to implement changes in the storefront controller code. Below are the changes that you have to implement, for each file. To find these files, go to app_storefront_controllers > cartridge.
controllers/COBilling.js
-
Add Adyen helpers:
/* Script Modules */ var app = require('~/cartridge/scripts/app'); var guard = require('~/cartridge/scripts/guard'); // ---------------------- ADD THE CODE BELOW ---------------------- var AdyenController = require("int_adyen_controllers/cartridge/controllers/Adyen"); var AdyenHelper = require("int_adyen_overlay/cartridge/scripts/util/AdyenHelper");
-
In the
returnToForm
function, add the Adyen helper as a key toapp.getView
:if (params) { app.getView(require('~/cartridge/scripts/object').extend(params, { Basket: cart.object, // ---------------------- ADD THE FOLLOWING LINE ---------------------- AdyenHelper : AdyenHelper, ContinueURL: URLUtils.https('COBilling-Billing') })).render('checkout/billing/billing'); } else { app.getView({ Basket: cart.object, // ---------------------- ADD THE FOLLOWING LINE ---------------------- AdyenHelper : AdyenHelper, ContinueURL: URLUtils.https('COBilling-Billing') }).render('checkout/billing/billing'); }
-
In the
publicStart
function, add the following code:initEmailAddress(cart); // ---------------------- ADD THE FOLLOWING LINE ---------------------- // Get the Saved Cards from Adyen to get latest saved cards require('int_adyen_overlay/cartridge/scripts/updateSavedCards').updateSavedCards({CurrentCustomer : customer});
-
In the
publicStart
function, remove the following line:start(cart, {ApplicableCreditCards: creditCardList.ApplicableCreditCards});
If you are not using POS, replace it with:
var AdyenPaymentMethods = AdyenController.GetPaymentMethods(cart); start(cart, {ApplicableCreditCards: creditCardList.ApplicableCreditCards, AdyenPaymentMethods : AdyenPaymentMethods} );
If you are using POS, replace it with:
var AdyenPaymentMethods = AdyenController.GetPaymentMethods(cart); var AdyenPosTerminals = AdyenController.GetTerminals(); start(cart, {ApplicableCreditCards: creditCardList.ApplicableCreditCards, AdyenPaymentMethods : AdyenPaymentMethods, AdyenPosTerminals : AdyenPosTerminals});
-
Modify the
validatePayment
function:function validatePayment(cart) { var paymentAmount, countryCode, invalidPaymentInstruments, result; // ---------------------- ADD THE CODE BELOW ---------------------- if (AdyenHelper.getAdyenSecuredFieldsEnabled()) { result = true; return result; }
-
In the
saveCreditCard
function, add code under the specified line:function saveCreditCard() { // ---------------------- ADD THE CODE BELOW ---------------------- if (AdyenHelper.getAdyenRecurringPaymentsEnabled()) { //saved credit cards are handling in COPlaceOrder and Login for Adyen - saved cards are synced with Adyen ListRecurringDetails API call return true; } else {
-
Close the else condition:
customer.getProfile().getWallet().removePaymentInstrument(creditcard); } } }); } return true // ---------------------- ADD THE CODE BELOW ---------------------- }
controllers/COPlaceOrder.js
-
In the
handlePayments
function, add code under the specified line:function handlePayments(order) { // ... if (authorizationResult.not_supported || authorizationResult.error) { return { error: true }; } // ---------------------- ADD THE CODE BELOW ---------------------- if(authorizationResult.authorized == true){ if(PaymentMgr.getPaymentMethod(paymentInstrument.getPaymentMethod()).getPaymentProcessor().ID === 'ADYEN_CREDIT' && authorizationResult.authorized3d == true) { return { view:authorizationResult.view } ; } else if(PaymentMgr.getPaymentMethod(paymentInstrument.getPaymentMethod()).getPaymentProcessor().ID === 'Adyen' && authorizationResult.redirectObject) { return { redirectUrl:authorizationResult.redirectObject.url } } }
-
Replace
var handlePaymentsResult = handlePayments(order)
with the following:var skipSubmitOrder : Boolean = false; var handlePaymentsResult = handlePayments(order); if (!empty(handlePaymentsResult.view)){ skipSubmitOrder = true; }
-
Replace
var orderPlacementStatus = Order.submit(order);
withif (handlePaymentsResult.redirectUrl && order.paymentInstrument.paymentMethod == "Adyen") { return { Order: order, order_created: true, redirectUrl: handlePaymentsResult.redirectUrl }; } else { if (skipSubmitOrder) { return { Order: order, order_created: true, view : handlePaymentsResult.view, skipSubmitOrder : skipSubmitOrder }; } else { var orderPlacementStatus = Order.submit(order); } }
controllers/COSummary.js:
-
At the top of the file, add the following code:
var AdyenController = require("int_adyen_controllers/cartridge/controllers/Adyen");
-
In the
submit
function, replaceshowConfirmation(placeOrderResult.Order);
with:if (placeOrderResult.Order.paymentInstrument.paymentMethod == "Adyen" && placeOrderResult.redirectUrl) { AdyenController.Redirect(placeOrderResult.Order, placeOrderResult.redirectUrl); } else { if (placeOrderResult.skipSubmitOrder === true && placeOrderResult.view.token3ds2) { placeOrderResult.view.render('adyenpaymentredirect'); } else if (placeOrderResult.skipSubmitOrder === true) { placeOrderResult.view.render('adyenform'); } else { showConfirmation(placeOrderResult.Order); } }
controllers/PaymentInstruments.js
-
At the top of the file, add the following code:
/*API includes*/ var PaymentInstrument = require('dw/order/PaymentInstrument'); var Logger = require('dw/system/Logger');
-
At the top of the file, add the following code:
/*Script Modules*/ var AdyenHelper = require('int_adyen_overlay/cartridge/scripts/util/AdyenHelper');
-
Modify the
list
function:function list() { // ---------------------- ADD THE CODE BELOW ---------------------- // Get the Saved Cards from Adyen to get latest saved cards require('int_adyen_overlay/cartridge/scripts/updateSavedCards').updateSavedCards({CurrentCustomer : customer});
-
Modify the
create
function:var paymentInstruments = wallet.getPaymentInstruments(dw.order.PaymentInstrument.METHOD_CREDIT_CARD); // ---------------------- ADD THE CODE BELOW ---------------------- if (AdyenHelper.getAdyenRecurringPaymentsEnabled()) { var createRecurringPaymentAccountResult = AdyenHelper.createRecurringPaymentAccount({ Customer: customer }); if (createRecurringPaymentAccountResult.error) { return false; } pspReference = 'PspReference' in createRecurringPaymentAccountResult && !empty(createRecurringPaymentAccountResult.PspReference) ? createRecurringPaymentAccountResult.PspReference : ''; tokenID = 'TokenID' in createRecurringPaymentAccountResult && !empty(createRecurringPaymentAccountResult.TokenID) ? createRecurringPaymentAccountResult.TokenID : ''; /*if (empty(TokenID) || empty(PspReference)) { return false; }*/ try { Transaction.wrap(function() { /* var newCreditCard = customer.getProfile().getWallet().createPaymentInstrument(PaymentInstrument.METHOD_CREDIT_CARD); * // copy the credit card details to the payment instrument * newCreditCard.setCreditCardHolder( newCreditCard.setCreditCardNumber( newCreditCard.setCreditCardType( newCreditCard.setCreditCardToken(tokenID); newCreditCard.custom.AdyenPspReference = pspReference; */ require('int_adyen_overlay/cartridge/scripts/updateSavedCards').updateSavedCards({ CurrentCustomer: customer, PaymentsMap: createRecurringPaymentAccountResult.PaymentsMap }); }); } catch (e) { Logger.error('{0}: {1}', e, e.stack); return false; } return true; }
-
In the
Delete
function, replacewallet.removePaymentInstrument(action.object);
with:var paymentInstrument = action.object; if (!empty(paymentInstrument)) { if (AdyenHelper.getAdyenRecurringPaymentsEnabled() && !empty(paymentInstrument.getCreditCardToken())) { var result = require('int_adyen_overlay/cartridge/scripts/adyenDeleteRecurringPayment').deleteRecurringPayment({ Customer: customer, RecurringDetailReference: paymentInstrument.getCreditCardToken() }); if (result == PIPELET_NEXT) { wallet.removePaymentInstrument(paymentInstrument); } } else { wallet.removePaymentInstrument(paymentInstrument); } }
-
Modify the
verifyCreditCard
function:function verifyCreditCard() { var newCreditCardForm = app.getForm('paymentinstruments.creditcards.newcreditcard'); // ---------------------- ADD THE CODE BELOW ---------------------- if (AdyenHelper.getAdyenSecuredFieldsEnabled()) { return true; }