This document is for technical personal assigned to integrate Openpay into an existing Commerce Cloud shop solution.
This document describes the technical integration of Openpay link cartridge.
Openpay is a next generation payment solution that allows customers to buy now and pay over a flexible timeframe without interest, giving them added cash flow confidence. Creating a seamless omni channel experience (in-store, online and through our app), we service several brands across multiple industries including retail, healthcare, automotive and home improvement.
We offer our customers convenient terms, and our merchants the opportunity to increase their incremental sales with a higher ATV.
Our customers are empowered to live their best life; with more choice, time and flexibility.
The Openpay link cartridge features include:
Designed for Commerce Cloud API version 16.2 or higher, based on SiteGenesis 2.
Openpay integration has the following cartridge:
To begin the checkout of a customer that chooses Openpay payment method on your website, a POST request must be submitted to request a PlanID. This happens when the order is placed after the summary page. The request contains the orders total price and an auth token issued by Openpay. The response to this request provides a unique PlanID that is saved to the order object as a custom attribute.
Once a PlanID is received a handover URL is composed that is used for redirection to Openpay. It contains all relevant information like return URL, cancel URL, customer and order information beside the PlanID.
For the Openpay integration to work, the following needs to be configured in the Business manager.
Go to Menu > Administration > Site Development > Import & Export. Upload and import the meta file system-objects.xml which is available in metadata folder of the cartridge bundle. On successful import of this meta file you will be new site preference groups and fields are detailed below.
Group ID: Openpay General Config
Group ID: Openpay Category Config
Group ID: Openpay Checkout Config
Group ID: Openpay Popup Config
Please ask your Openpay account manager for your Live credentials.
Test credentials can be found under Testing section.
Open Group Openpay Checkout Configuration and find the field Select Two Plans (openPaySelectTwoPlans). Set two values, for example, 2 and 3.
In Business Manager section <your-site> Merchant Tools > Ordering > Payment Processors create (click new button) a new Payment Processor named ‘OPENPAY’. In section Ordering > Payment Methods create a new payment method by clicking ‘New’ button, set ID as OPENPAY, name it Openpay – Buy now. Pay smarter. and set the payment processor you created before.
(Alternatively, you can upload and import payment method meta file, metadata/payment-method.xml, which is available in the cartridge bundle, in BM Ordering > Import/Export > Import & Export > Payment Methods. Import does NOT contain the payment processor. It has to be created.)
Openpay utlizes Commerce Cloud’s default configurations of payment method to restrict payments based on minimum and maximum ranges, countries or currencies.
Please refer Merchandizing your site > Ordering > Managing credit/debit cards in Commerce Cloud’s documentation portal to learn how to configure min/max ranges, countries and currencies restrictions on payments done via Openpay.
To configure necessary service in Business Manager Section > Administration > Operations > Import & Export first upload and then import (Service Import) file metadata/services.xml.
If your site uses a shared library then edit the metadata/content-assets.xml file in cartridge bundle, to change the line
<library xmlns=”http://www.demandware.com/xml/impex/library/2006-10-31″>
to
<library xmlns=”http://www.demandware.com/xml/impex/library/2006-10-31″ library-id=”Site’sSharedLibraryID”>
Go to Merchant Tools > Content > Import & Export: Import and Export Files, then click on Upload button and upload metadata/content-assets.xml file.
Go to Merchant Tools > Content > Import & Export: Libraries, then click on Import button and import the uploaded content-assets.xml file.
Go to Merchant Tools > Content > Import & Export: Content Image Upload, then click on Upload button.
On the Content Image page go to section titled as ‘Directories’, under library’s directory structure, create new directory namely ‘openpay’ under library > images directory. Select the ‘openpay’ directory and upload all images from metadata/images/openpay folder in cartridge bundle.
Go to Administration > Operations > Import & Export: Import & Export Files, then click on Upload button.
Click on the Upload File browser field and upload metadata/jobs.xml. Go to Administration > Operations > Import & Export: Jobs and click on Import button. From the file list, select the radio button that corresponds to jobs.xml and press next button. After validating the file, continue import pressing Next button.
Go to Administration > Operations > Jobs and open newly added job – Openpay-Update-OrderStatus and open Job Steps. Two Job Steps are set by default, one for SFRA based sites and the other for SGJC based sites. Remove unwanted Job Step and choose relevant sites in required flow.
Job Step Parameter:
Integration may vary based on the SiteGenesis application version. SiteGenesis version 13.1 is used to demonstrate Openpay integration.
Openpay will be offered as another payment method for the shopper to be selected on the Billing Page.
When the shopper selects to Continue, they will be redirected to the Openpay site shopper is identified and . If the shopper selects to Cancel the transaction, they will be returned back to the Billing page. Upon return to Commerce Cloud the shopper will be presented with the Order receipt page with their order number.
In both cases, the cartridge can first be downloaded from Commerce Cloud’s Xchange marketplace: https://xchange.Commerce Cloud.com/community/marketplace
Once downloaded, please import the cartridge into your UX studio. Please refer following article on how to install UX studio: Getting started > Installing or updating UX studio in Commerce Cloud’s documentation portal.
Please refer to following articles if you need assistance with how to connect UX studio with your sandbox and registering (installing) cartridge to sandbox:
To integrate Openpay into SiteGenesis a few changes have to be made depending on whether Javascript controllers or Pipelines are being used.
In file <default Site Genesis controllers cartridge>/cartridge/scripts/hooks.json add a new hook definition for Openpay processor script by adding
{
“name”:”app.payment.processor.OPENPAY”,
“script”:”./payment/processor/OPENPAY”
}
into the ‘hook’ array of the json.
Move OPENPAY.js from folder int_openpay_controllers/reference/scripts/payment/processor/ to folder <default Site Genesis controllers cartridge>/cartridge/scripts/payment/processor/.
In SiteGenesis controller COPlaceOrder.js (<default Site Genesis controllers cartridge >/cartridge/controllers/COPlaceOrder.js) in function start() at around line 175 after the call of function handlePayments(order) add another “else if” branch to the response handling.
else if (handlePaymentsResult.redirected) {
return Transaction.wrap(function () {
return {
error: false
};
});
}
In the same file, in function handlePayments(order) at around line 71 after the call of function handlePayments(order) add another “else if” branch to return a response indicating a redirect to openpay.
else if (authorizationResult.redirected) {
return {
redirected: true
};
}
In < default Site Genesis core cartridge>/cartridge/templates/default/checkout/billing/paymentmethods.isml make following changes
<isscript>
var showOpenpay = dw.system.Site.current.getCustomPreferenceValue(‘isOpenpayEnabled’);
var openpayMinPrice = dw.system.Site.current.getCustomPreferenceValue(‘openpayMinPrice’);
var openpayMaxPrice = dw.system.Site.current.getCustomPreferenceValue(‘openpayMaxPrice’);
var basketObject = dw.order.BasketMgr.getCurrentBasket();
var totalPrice = Number(basketObject.totalGrossPrice);
if(showOpenpay){
if(!empty(openpayMinPrice)){
openpayMinPrice = parseFloat(openpayMinPrice, 10);
if(openpayMinPrice > totalPrice){
showOpenpay = false;
}
if(!empty(openpayMaxPrice)){
openpayMaxPrice = parseFloat(openpayMaxPrice, 10);
if(openpayMaxPrice > openpayMinPrice && openpayMaxPrice < totalPrice){
showOpenpay = false;
}
}
}
else if(!empty(openpayMaxPrice)){
openpayMaxPrice = parseFloat(openpayMaxPrice, 10);
if(openpayMaxPrice < totalPrice){
showOpenpay = false;
}
}
}
</isscript>
<iscomment>Ignore OPENPAY method if it is not supposed to be displayed</iscomment>
<isif condition=“${!(paymentMethodType.value.toLowerCase().equals(‘openpay’) && showOpenpay)}”><iscontinue/></isif>
Custom processor
————————————————-
</iscomment>
add the below mentioned code snippet :
<div class=”payment-method <isif condition=”${!empty(pdict.selectedPaymentID) && pdict.selectedPaymentID==’OPENPAY’}”>payment-method-expanded</isif>” data-method=”OPENPAY“>
<iscomment>Openpay</iscomment>
<isinclude template=”util/modulesopenpay”/>
<div class=”checkout-logo”>
<iscontentasset aid=”${‘openpay’+dw.system.Site.getCurrent().getCustomPreferenceValue(‘openpayLogoType’).value}” />
</div>
<isdisplayopenpayatcheckout context=”checkout” issfra=”${false}” totalprice=”${pdict.OrderTotal}” />
</div>
<link rel=”stylesheet” href=”${URLUtils.staticURL(‘/css/openpaystyle.css’)}” />
<iscomment>Openpay</iscomment>
<isinclude template=”util/modulesopenpay”/>
<isdisplayacceleratorwidget context=”minicart” issfra=”${false}” totalprice=”${pdict.Basket.getAdjustedMerchandizeTotalPrice(false).add(pdict.Basket.giftCertificateTotalPrice)}”/>
In <default Site Genesis core cartridge>/cartridge/templates/default/product/components/pricing.isml, just before the isif condition <isif condition=”${!empty(pdict.OrgProduct)}”> , place the below mentioned code :
<iscomment>Openpay</iscomment>
<isinclude template=”util/modulesopenpay”/>
<isdisplayopenpaymessage context=”product” issfra=”${false}” productid=”${pdict.Product.ID}” productprice=”${(SalesPrice ? SalesPrice : StandardPrice)}”/>
<isinclude template=”util/modulesopenpay”/>
<isdisplayopenpaymessage context=”${‘category’}” issfra=”${false}” productid=”${Product.ID}” productprice=”${(prices[prices.length-2].value)}”/>
<link rel=”stylesheet” href=”${URLUtils.staticURL(‘/css/openpaystyle.css’)}” />
<iscomment>Add template-specific header information here.</iscomment>
<link rel=”stylesheet” href=”${URLUtils.staticURL(‘/css/openpaystyle.css’)}” />
$(‘.openpay-overview’).on(‘click’, function (e) {
e.preventDefault();
dialog.open({
url: $(e.target).attr(‘href’),
options: {
}
});
});
Below integration steps will give you access to following features that can be controlled by configurations mentioned in section 2.2.
Upload int_openpay_sfra and bm_openpay cartridges to your active code version in SFCC instance using UX Studio (Eclipse).
Login to SFCC instance and open following page:
Administration > Sites > Manage Sites > {Your SFRA Site} – Settings
Inside the input box which is labelled as ‘Cartridges:’ prepend the cartridge name int_openpay_sfra separated by a colon (:)
In the same way, open the following page:
Administration > Sites > Manage Sites > Business Manager – Settings
Prepend the cartridge name bm_openpay in the input box which is labelled as ‘Cartridges:’
Following changes need to be made on your custom storefront cartridge from which you build SCSS and client side JS files:
– File: {custom storefront cartridge}/cartridge/client/default/js/checkout/checkout.js
On the global variable declaration section, add the following line
var openpayCheckout = require(‘./openpayCheckout’);
(You can copy the above path if the cartridges int_openpay_sfra and custom storefront cartridge are inside the same folder. Else path of the required file is to be changed as per the relative path in your file system.)
In the same file add the following line segment inside any section where plugins are getting initialized.
// Openpay
openpayCheckout.init();
(For example, include the above lines after the following existing code
members.initialize();
)
File: {custom storefront cartridge}/cartridge/client/default/js/components/miniCart.js
On the global variable declaration section, add the following line
var openpayMiniCart = require(‘./openpayMiniCart’);
(You can copy the above path if the cartridges int_openpay_sfra and custom storefront cartridge are inside the same folder. Else path of the required file is to be changed as per the relative path in your file system.)
Find the function definition as module.exports = function () { and at the beginning add the following lines
// openpay
openpayMiniCart.init();
Find the mouseenter event handing function $(‘.minicart’).on(‘mouseenter focusin touchstart’, function () { find the ajax call in it starting with $.get(url, function (data) {. Find code $.spinner().stop(); and keep the following code below it.
// Openpay
openpayMiniCart.show(url);
File: {custom storefront cartridge}/cartridge/client/default/js/cart/cart.js
On the global variable declaration section, add the following line
var openpayMiniCart = require(‘../components/openpayMiniCart’);
Find the ajax call inside the method “$(‘body’).on(‘change’, ‘.quantity-form > .quantity’, function () {“
and add the below mentioned code after “validateBasket(data);”
openpayMiniCart.init();
File: {custom storefront cartridge}/cartridge/client/default/js/checkout/billing.js
Inside the method “updateBillingInformation”, replace “updateBillingAddressFormValues(order);” with
updateBillingAddressFormValues(order, customer);
Update the parameters list of “function updateBillingAddressFormValues(order) {“ with
updateBillingAddressFormValues(order, customer) {
Inside the method “updateBillingAddressFormValues”, after the condition “if (!billing.billingAddress || !billing.billingAddress.address) return;” add the below mentioned code:
var email = order.orderEmail ? order.orderEmail : ”;
if(customer.registeredUser){
email = customer.profile.email;
}
And replace “$(‘input[name$=_email]’, form).val(order.orderEmail);” with
“$(‘input[name$=_email]’, form).val(email);”
File: {custom storefront cartridge}/cartridge/client/default/js/product/base.js
On the global variable declaration section, add the following line
var openpayContent = require(‘./openpayContent’);
(You can copy the above path if the cartridges int_openpay_sfra and custom storefront cartridge are inside the same folder. Else path of the required file is to be changed as per the relative path in your file system.)
In the same file find the module.exports = { section, find addToCart: function () { function definition. Inside it after all the event definitions, add the following lines
// Openpay
openpayContent.init();
File: {custom storefront cartridge}/cartridge/client/default/scss/global.scss
Add the following line at the end of other @import section
@import “openpaystyle.css”;
(You can copy the above path if the cartridges int_openpay_sfra and custom storefront cartridge are inside the same folder. Else path of the imported file is to be changed as per the relative path in your file system.)
– After making above mentioned changes on client side JS and SCSS files, build them.
– int_openpay_sfra has already built files (int_openpay_sfra/cartridge/static/) that were built from base cartridge which can be removed if custom storefront cartridge has its own path of built files.
Following files are overriding templates on top your storefront custom cartridge. Actual custom changes in those files are mentioned below, so you can reuse your customized storefront templates with following custom changes in it.
Template 1: int_openpay_sfra/cartridge/templates/default/product/productDetails.isml
<iscomment>Openpay</iscomment>
<isset name=“openpayAppliedPrice” value=“${product.price.type == ‘range’ ? product.price.min.sales.decimalPrice : (product.price.type == ‘tiered’ ? product.price.startingFromPrice.sales.decimalPrice : product.price.sales.decimalPrice)}” scope=“page” />
<isinclude template=“util/modulesopenpay”/>
<isdisplayopenpaymessage context=“${‘product’}” productid=“${product.id}” productprice=“${openpayAppliedPrice}”/>
Template 2: int_openpay_sfra/cartridge/templates/default/product/productTile.isml
<iscomment>Openpay</iscomment>
<isset name=“openpayAppliedPrice” value=“${product.price.type == ‘range’ ? product.price.min.sales.decimalPrice : (product.price.type == ‘tiered’ ? product.price.startingFromPrice.sales.decimalPrice : product.price.sales.decimalPrice)}” scope=“page” />
<isinclude template=“util/modulesopenpay”/>
<input type=“hidden” class=“openpay-widget-plp” value=“${URLUtils.https(‘OpenpayContent-Show’)}”>
<isdisplayopenpaymessage context=“${‘product’}” productid=“${product.id}” productprice=“${openpayAppliedPrice}”/>
Template 3: int_openpay_sfra/cartridge/templates/default/checkout/cart/miniCart.isml
<iscomment>Openpay</iscomment>
<isinclude template=“util/modulesopenpay”/>
<isdisplayacceleratorwidget context=“minicart” issfra=“${true}” totalprice=“${pdict.totals.subTotal}”/>
Template 4: int_openpay_sfra/cartridge/templates/default/checkout/billing/paymentOptions/paymentOptionsSummary.isml
Add iselse condition for the if condition <isif condition=“${payment.paymentMethod === ‘CREDIT_CARD’}”>
<iselse>
<isprint value=”${payment.paymentMethod}” />
Template 5: int_openpay_sfra/cartridge/templates/default/checkout/billing/paymentOptions/paymentOptionsContent.isml
Add iselse condition for the if condition <isif condition=“${paymentOption.ID === ‘CREDIT_CARD’}”>
<iselse>
<iselse>
<div class=“tab-pane ${paymentOption.ID.toLowerCase() + ‘-content’}” id=“${paymentOption.ID.toLowerCase() + ‘-content’}” role=“tabpanel”>
<isif condition=“${paymentOption.ID.toLowerCase() === ‘openpay’}”>
<isinclude template=“util/displayopenpayatcheckout” />
</isif>
</div>
Template 6: int_openpay_sfra/cartridge/templates/default/checkout/billing/paymentOptions/paymentOptionsTabs.isml
Add below mentioned code in top of the isml :
<isscript>
var showOpenpay = dw.system.Site.current.getCustomPreferenceValue(‘isOpenpayEnabled’);
var openpayMinPrice = dw.system.Site.current.getCustomPreferenceValue(‘openpayMinPrice’);
var openpayMaxPrice = dw.system.Site.current.getCustomPreferenceValue(‘openpayMaxPrice’);
var orderTotal = pdict.order.totals.grandTotal;
var totalPrice = Number(orderTotal.replace(/[^0-9.-]+/g,”));
if(showOpenpay){
if(!empty(openpayMinPrice)){
openpayMinPrice = parseFloat(openpayMinPrice, 10);
if(openpayMinPrice > totalPrice){
showOpenpay = false;
}
if(!empty(openpayMaxPrice)){
openpayMaxPrice = parseFloat(openpayMaxPrice, 10);
if(openpayMaxPrice > openpayMinPrice && openpayMaxPrice < totalPrice){
showOpenpay = false;
}
}
}
else if(!empty(openpayMaxPrice)){
openpayMaxPrice = parseFloat(openpayMaxPrice, 10);
if(openpayMaxPrice < totalPrice){
showOpenpay = false;
}
}
}
</isscript>
And for the if condition <isif condition=“${paymentOption.ID === ‘CREDIT_CARD’}”>, add the below mentioned iselse condition :
<iselseif condition=“${paymentOption.ID.toLowerCase() != ‘openpay’ || (paymentOption.ID.toLowerCase() == ‘openpay’ && showOpenpay)}”>
<li class=“nav-item” data-method-id=“${paymentOption.ID}”>
<a class=“nav-link ${paymentOption.ID.toLowerCase() + ‘-tab’}” data-toggle=“tab” href=“${‘#’ + paymentOption.ID.toLowerCase() + ‘-content’}” role=“tab”>
<isprint value=“${paymentOption.name}” />
</a>
</li>
Template 7:
int_openpay_sfra/cartridge/templates/default/checkout/checkout.isml
Add the below mentioned code snippet before the button <button class=“btn btn-primary btn-block place-order”
<input type=“hidden” class=“openpay-isopenpayURL” value=“${URLUtils.https(‘OpenpayCheckout-IsOpenpay’)}”>
<input type=“hidden” class=“openpay-redirectURL” value=“${URLUtils.https(‘OpenpayCheckout-Redirect’)}”>
For the Openpay integration to work, the following needs to be configured in the Business manager.
This section provides the credentials for test user and test merchant account on Openpay Training Environment to create and check your Openpay plan.
30000000000001183|abfea8e7-9c15-4889-bc44-0df8a05ad73c
Username: AppTestUser@xx.yy
Password: Test123
https://retailer.myopenpay.com.au/training
Username: adminmag
Password: Test123
Once the cartridge is installed and integrated based on instructions, please try to place an order on your sandbox to test the functionality.
Once you login then you will be prompted to choose the premium and fill/verify your billing address:
To refund the transaction: Go to > Merchant Tools > Openpay > Transactions Management > click on the order Id from the list of orders which has to be refunded > Enter the amount to be refunded and click on ‘Refund’
# | Date | Version | Description |
---|---|---|---|
1 | 02-Jul-2019 | 19.2.0 |
|
2 | 25-Jun-2019 | 19.1.1 |
|
3 | 21-Mar-2019 | 19.1.0 |
|
4 | 20-Mar-2018 | 18.1.0 |
|