Implementation Guide

2. Implementation Guide

2.1 Adding the cartridge in SFCC UX Studio

To upload the cartridges into the SFCC server, you first need to add the cartridges in SFCC UX Studio. In order to do this, follow these instructions.

  1. In UX Studio, select in the menu, File > Import.

  2. In the import dialog, select General > Existing Projects in the workspace and click on 'Next'.

  3. Ensure 'Select archive file' is selected and select the compressed cartridge file by clicking on the 'Browse' button.

  4. Click on the 'Finish' button to import the cartridges.

  5. Studio will now ask you if you want to link the cartridge to your active DigitalServer connection. Click on yes or manually link the cartridge to your server by checking the project under project references in the server connection properties.

2.2 Business Manager Configurations

For the Optty integration to work, the following needs to be configured in the Business manager.

2.2.1 Activating the cartridge in Business Manager

Before the Optty functionality can become available on Site, the cartridges have to be added to the cartridge path of the Site. In order to do this, follow the following instructions:

  1. Log into Business Manager.

  2. Navigate to Administration > Sites > Manage Sites.

  3. Click on the site name and on the next page go to the 'Settings' tab.

  4. In the 'Cartridges' input field add 'int_optty_controllers:int_optty_core' in front of the SiteGenesis cartridge.

  5. Click on the 'Apply' button.

  6. To activate the cartridge for the Sandbox/Development/Production instances repeat steps 4 and 5 after selecting the appropriate instance from the 'Instance Type' dropdown menu.

  7. Repeat steps 3 to 6 for each site that is to use Optty.

  8. Go to 'Manage the Business Manager site'.

  9. In the ‘Cartridges’ input field add 'bm_optty:bc_optty:int_optty_core'.

  10. Click on the ‘Apply’ button.

2.2.2 Enable Cartridge Module

To enable the Cartridge module,

  1. Go to Administration > Organization > Roles & Permissions.

  2. Click on ‘Administrator’ and click on the ‘Business Manager Modules’ tab.

  3. In the Select Context dialog, check your site ID checkbox and click on the ‘Apply’ button.

  4. Find ‘Optty’ and check the checkbox to enable it.

  5. Click on the ‘Update’ button.

3.2.3 Importing Metadata

For the Optty integration to work, the following object structures (metadata) need to be imported and configured in the Business manager. Follow the below steps:

  1. In the cartridge bundle find the ‘metadata/optty-meta-import’ folder.

  2. Find the ‘sites’ folder and inside it, find the ‘RefArch’ folder.

  3. Rename this ‘RefArch’ folder to the ID of your site. If you have multiple sites that need this meta to be imported, then copy and paste this ‘RefArch’ folder to replicate for other sites. Rename those folders with the ID of the corresponding sites.

  4. In the cartridge bundle, inside the ‘metadata’ folder, compress optty-meta-import folder to generate ‘optty-meta-import.zip’ file.

  5. Go to Business Manager Menu > Administration > Site Development > Site Import & Export

  6. Under Import: Upload Archive: Ensure that the radio button with the label ‘Local’ is enabled (Else click on the radio button to enable it)

  7. Click on Choose File input field, select the ‘optty-meta-import.zip’ file from the open dialog box and click on the upload button.

  8. After finishing the upload, from the Archives list click the radio button corresponding to ‘optty-meta-import.zip’ and click on the ‘Import’ button.

  9. Click on the ‘OK’ button of the confirmation box asking, ‘Are you sure that you want to import the selected archive?’

3.2.4 Custom Site Preferences

After the successful metadata import following attributes should have been created:

In Business Manager, navigate to Merchant Tools > Site Preferences > Custom Preferences. Custom site preference groups with the ID ‘Optty Settings’ will be available.

Please select it and edit the attributes according to your Optty account data.

For each site, set the values for your site preferences. Many of these values will be provided during sign-up to Optty or found within the UPP.

  1. Is Optty Enabled (ID: isOpttyEnabled, Type: Boolean) – Used to enable and disable Optty and its functionality in a single point.

  2. API Client ID (ID: opttyAPIClientID, Type: String) – API client Id of Optty.

  3. Client Secret (ID: opttyClientSecret, Type: String) – Client secret of Optty.

  4. Secret Key (ID: opttySecretKey, Type: String) – Secret key of Optty. Used to generate the signature.

  5. Widget Mode (ID: opttyWidgetMode, Type: Enum of Strings) – Used to select preview and live mode.

  6. Display Mini Cart Widget (ID: opttyEnableMinicartWidget, Type: Boolean) – Used to enable and disable the Optty widget on the minicart page.

  7. Display Cart Widget (ID: opttyEnableCartWidget, Type: Boolean) – Used to enable and disable the Optty widget on the cart page.

  8. Display Product Details Widget (ID: opttyEnableProductDetailsWidget, Type: Boolean) – Used to enable and disable Optty widget on the product details page.

  9. Display Product Listing Widget (ID: opttyEnableProductListingWidget, Type: Boolean) – Used to enable and disable Optty widget on the product listing page.

  10. Display Checkout Widget (ID: opttyEnableCheckoutWidget, Type: Boolean) – Used to enable and disable Optty widget on the checkout page.

  11. Display Footer Widget (ID: opttyEnableFooterWidget, Type: Boolean) – Used to enable and disable Optty widget in the footer.

  12. Summary Page Enabled (ID: isOpttySummaryPageEnabled, Type: Boolean) – Used to enable and disable the summary page.

  13. Live Widget URL (ID: opttyLiveWidgetURL, Type: String) – Widget URL for live mode.

  14. Sandbox Widget URL (ID: opttySandboxWidgetURL, Type: String) – Widget URL for preview mode.

  15. Scope (ID: opttyScope, Type: String) – Scope of Optty.

  16. Live Widget Configuration (ID: opttyLiveWidgetConfiguration, Type: Text) – Configuration data of live widget.

  17. Default Checkout (ID: opttyDefaultCheckout, Type: Boolean) – Used to enable and disable Optty default checkout.

  18. Custom Checkout Button (ID: opttyCustomCheckoutButton, Type: Boolean) – Used to enable and disable the Optty custom checkout button.

  19. Use Default Locale(ID: opttySetDefaultLocale, Type: String) – Used to set locale value for a site that has selected ‘Default’ as the default locale.

  20. Orders Created Time(in Minutes)(ID: opttyOrdersCreatedTime, Type: String) – Used to find the orders behind this given time. Set time in minutes.

3.2.5 Payment Methods

Under Merchant Tools > Ordering > Payment Methods, check that the payment method with ID ‘OPTTY’ is created.

3.2.6 Payment Processor

Under Merchant Tools > Ordering > Payment Processors, check those payment processors with IDs ‘OPTTY’ and ‘OPTTY_PROVIDER’ are created.

3.2.7 HTTP Services

Under Administration > Operations > Services, check that services with IDs ‘optty.http.auth’ and ‘optty.http.generic’ are created.

3.2.8 Jobs

Under Administration > Operations > Jobs, check that job with ID ‘OpttyMerchantData’ and ‘OpttyOrders’ is created.

3.3 Custom Code

To integrate Optty into the store few changes should be made to the default Site Genesis cartridge code.

3.3.1 SiteGenesis controllers cartridge changes

Below are the changes that you have to implement in the storefront controller code, for each file. To find these files go to (SiteGenesis Storefront Controllers cartridge) > cartridge.

  • Move the file from ‘int_optty_controllers/reference/cartridge/scripts/payment/processor/OPTTY.js’ to <SiteGenesis controllers cartridge>/ cartridge/scripts/payment/processor/OPTTY.js

  • Move the file from ‘int_optty_controllers/reference/cartridge/scripts/payment/processor/OPTTY_PROVIDER.js’ to <SiteGenesis controllers cartridge>/ cartridge/scripts/payment/processor/OPTTY_PROVIDER.js

scripts/hooks.json

Inside the ‘hooks’ array, add a new hook definition for the Optty processor under the specified line

	{
		"name": "app.payment.processor.VERISIGN_CREDIT",
		"script": "./payment/processor/VERISIGN_CREDIT"
	},
 
-------------------------- ADD THE BELOW CODE ---------------------------------
	{
		"name": "app.payment.processor.OPTTY",
		"script": "./payment/processor/OPTTY"
	},
	{
		"name": "app.payment.processor.OPTTY_PROVIDER",
		"script": "./payment/processor/OPTTY_PROVIDER"
	}

controllers/COBilling.js

a. In the resetPaymentForms function, add below lines and else if condition under specified lines.

 var status = Transaction.wrap(function () {
 if (app.getForm('billing').object.paymentMethods.selectedPaymentMethodID.value.equals('PayPal')) {
 app.getForm('billing').object.paymentMethods.creditCard.clearFormElement();
 app.getForm('billing').object.paymentMethods.bml.clearFormElement();
 cart.removePaymentInstruments(cart.getPaymentInstruments(PaymentInstrument.METHOD_CREDIT_CARD));
 cart.removePaymentInstruments(cart.getPaymentInstruments(PaymentInstrument.METHOD_BML));

--------------------------- ADD THE FOLLOWING LINE --------------------------------------
// remove Optty PaymentInstrument
 cart.removePaymentInstruments(cart.getPaymentInstruments('OPTTY'));
 } else if (app.getForm('billing').object.paymentMethods.selectedPaymentMethodID.value.equals(PaymentInstrument.METHOD_CREDIT_CARD)) {
 app.getForm('billing').object.paymentMethods.bml.clearFormElement(); cart.removePaymentInstruments(cart.getPaymentInstruments(PaymentInstrument.METHOD_BML));
 cart.removePaymentInstruments(cart.getPaymentInstruments('PayPal'));
 
--------------------------- ADD THE FOLLOWING LINE --------------------------------------
// remove Optty PaymentInstrument
cart.removePaymentInstruments(cart.getPaymentInstruments('OPTTY'));
 } else if (app.getForm('billing').object.paymentMethods.selectedPaymentMethodID.value.equals(PaymentInstrument.METHOD_BML)) {
 app.getForm('billing').object.paymentMethods.creditCard.clearFormElement();
 if (!app.getForm('billing').object.paymentMethods.bml.ssn.valid) {
 return false;
 } cart.removePaymentInstruments(cart.getPaymentInstruments(PaymentInstrument.METHOD_CREDIT_CARD));
 cart.removePaymentInstruments(cart.getPaymentInstruments('PayPal'));
 
--------------------------- ADD THE FOLLOWING LINE --------------------------------------
// remove Optty PaymentInstrument
 cart.removePaymentInstruments(cart.getPaymentInstruments('OPTTY'));
 
--------------------- ADD THE FOLLOWING LINE AND ELSE IF CONDITION ----------------------
 } else if (app.getForm('billing').object.paymentMethods.selectedPaymentMethodID.value.equals('OPTTY')) {
 app.getForm('billing').object.paymentMethods.creditCard.clearFormElement();
 app.getForm('billing').object.paymentMethods.bml.clearFormElement();
 cart.removePaymentInstruments(cart.getPaymentInstruments(PaymentInstrument.METHOD_CREDIT_CARD));
 cart.removePaymentInstruments(cart.getPaymentInstruments(PaymentInstrument.METHOD_BML));
 cart.removePaymentInstruments(cart.getPaymentInstruments('PayPal'));
 }

 return true;
 });

b. In the billing function, find the function save: function (). Replace the existing function with the below code.

 save: function () {
 var cart = app.getModel('Cart').get();
 if (!cart) {
 app.getController('Cart').Show();
 return {};
 }
 Transaction.wrap(function () {
 if (!resetPaymentForms() || !validateBilling() || !handleBillingAddress(cart) // Performs validation steps, based upon the entered billing address
 // and address options.
 ) {// Performs payment method specific checks, such as credit card verification.
 returnToForm(cart);
 }
 var paymentSelection = handlePaymentSelection(cart);
 if (paymentSelection.error){// Performs payment method specific checks, such as credit card verification.
 returnToForm(cart);
 } else {
 if (customer.authenticated && app.getForm('billing').object.billingAddress.addToAddressBook.value) {
 app.getModel('Profile').get(customer.profile).addAddressToAddressBook(cart.getBillingAddress());
 }
// Mark step as fulfilled
app.getForm('billing').object.fulfilled.value = true;
 var utils = require('*/cartridge/scripts/utils/opttyUtils');
 var isOpttyDefaultCheckout = utils.getConfiguration().isOpttyDefaultCheckout;
 var isOpttySummaryPageEnabled = utils.getConfiguration().isOpttySummaryPageEnabled;
 var isCustomCheckoutButton = utils.getConfiguration().isCustomCheckoutButton;
 if ((isOpttyDefaultCheckout || isCustomCheckoutButton) && !isOpttySummaryPageEnabled && request.httpParameterMap.format.stringValue === 'ajax') {
 let r = require('~/cartridge/scripts/util/Response');
 r.renderJSON({
 status: 'success'
 });
 } else if (!isOpttyDefaultCheckout && !isOpttySummaryPageEnabled && paymentSelection.redirectUrl) {
 response.redirect(paymentSelection.redirectUrl);
 } else {
 // A successful billing page will jump to the next checkout step.
 app.getController('COSummary').Start();
 }
 return;
 }
 });
 }

3.3.2 SiteGenesis core Cartridge changes

Below are the changes that you have to implement in the storefront core code, for each file. To find these files, (Sitegenesis core cartridge)> cartridge.

Scripts

  1. scripts/util/Resource.ds

a. In ResourceHelper.getUrls function, add ‘opttyCheckout’ key in var urls

 opttyCheckout : URLUtils.url('OpttyCheckout-Redirect').toString()

b. In ResourceHelper.getPreferences function, add OPTTY_ENABLE and SUMMARY_PAGE_ENABLE keys in the return object.

OPTTY_ENABE: 
Site.getCurrent().getCustomPreferenceValue('isOpttyEnabled'),
SUMMARY_PAGE_ENABLE: 
Site.getCurrent().getCustomPreferenceValue('isOpttySummaryPageEnabled'),
DEFAULT_OPTTY_CHECKOUT: 
Site.getCurrent().getCustomPreferenceValue('opttyDefaultCheckout')

Templates

1. templates/default/components/footer/footer.isml

Add the code under the specified line.

 <div class="footer-item">
 <iscontentasset aid="footer-about"/>
 </div>
 ------------------- ADD THE CODE BELOW -----------------------------
 <iscomment>Optty Widget</iscomment>
 <isinclude template="widget/opttyfooterwidget"/>

2. templates/default/checkout/cart/minicart.isml

Add the code under the specified line.

<div class="mini-cart-totals">
 <div class="mini-cart-subtotals">
 <span class="label">${Resource.msg('order.ordersummary.ordersubtotal','order',null)}</span>
 <span class="value"><isprint value="${pdict.Basket.getAdjustedMerchandizeTotalPrice(false).add(pdict.Basket.giftCertificateTotalPrice)}"/></span>
 </div>
------------------- ADD THE CODE BELOW -----------------------------
 <iscomment>Optty Widget</iscomment>
 <isinclude template="widget/opttyminicartwidget"/>

3. templates/default/checkout/cart/cart.isml

Add the code under the specified line.

<iselseif condition="${pdict.CouponStatus != null && pdict.CouponStatus.error}">
 <div class="error">
 ${Resource.msgf('cart.' + pdict.CouponStatus.code,'checkout', null, pdict.CurrentForms.cart.couponCode.htmlValue)}
 </div>
 </isif>
 </div>
</div>
 <input type="hidden" name="${dw.web.CSRFProtection.getTokenName()}" value="${dw.web.CSRFProtection.generateToken()}"/>
 </fieldset>
</form>
---------------------- ADD THE CODE BELOW -----------------------------
<iscomment>Optty Widget</iscomment>
<isinclude template="widget/opttycartwidget"/>

4. default/rendering/category/categoryproducthits.isml

Add the code under the specified line.

 <iscomment>
 Render promotional content at the top of search results as global slot.
 This content is only displayed if the search result is refined by a category.
 If the search result is not refined by a category a global default is displayed.
 </iscomment>
---------------------- ADD THE CODE BELOW -----------------------------
 <iscomment>Optty Widget</iscomment>
 <isinclude template="widget/opttyproductlistingwidget"/>

5. templates/default/product/producttile.isml

Add the code under the specified line.

 
<iscomment>Rating</iscomment>
<iscomment>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++</iscomment>
<isif condition="${showrating && !Product.productSet}">
	<isinclude template="product/components/reviewsmini"/>
</isif>
 
---------------------- ADD THE CODE BELOW -----------------------------
 
 
<iscomment>Optty Widget</iscomment>
<isinclude template="widget/opttyproductlistingwidgetdiv"/>

6. templates/default/slots/product/product_listing.isml

Add the code under the specified line.

<isinclude template="util/modules"/>
<div class="product-slot product-listing">
---------------------- ADD THE CODE BELOW ------------------
 <iscomment>Optty Widget</iscomment>
 <isinclude template="widget/opttyproductlistingwidget"/>

7. templates/default/product/productcontent.isml

Add the code under the specified line.

<isset name="showTieredPrice" value="${true}" scope="page"/>
 <isinclude template="product/components/pricing"/>
 ----------------- ADD THE CODE BELOW ------------------------
 <iscomment>Optty Widget</iscomment>
 <isinclude template="widget/opttyproductdetailswidget"/>

8. templates/default/product/producttopcontentPS.isml

Add the code under the specified line.

<label>${Resource.msg('product.setpricelabel','product',null)}</label>
 <isinclude template="product/components/pricing"/>
 ----------------- ADD THE CODE BELOW ---------------------------
 <iscomment>Optty Widget</iscomment>
<isinclude template="widget/opttyproductsetwidget"/>

9. default/product/components/productsetproduct.isml

Add the code under the specified line.

<iscomment>
 product pricing
 =============================================================
 </iscomment>
 <isinclude template="product/components/pricing"/>
 ----------------- ADD THE CODE BELOW ---------------------------
 <iscomment>Optty Widget</iscomment>
 <isif condition="${pdict.isSet}">
 <isinclude template="widget/opttyproductdetailswidget"/>
 </isif>

10. default/checkout/billing/billing.isml

a. Replace the below code

<iscomment>payment method area</iscomment>
<isinclude template="checkout/billing/paymentmethods"/>

With

 <iscomment>payment method area</iscomment>
 <isif condition="${dw.system.Site.current.getCustomPreferenceValue('opttyDefaultCheckout') === false}">
 <isinclude template="customcheckout/billing/paymentmethods"/>
 <iselse/>
 <isinclude template="checkout/billing/paymentmethods"/>
 </isif>

b. Add the code under the specified line.

<isbonusdiscountlineitem p_alert_text="${Resource.msg('billing.bonusproductalert','checkout',null)}" p_discount_line_item="${pdict.BonusDiscountLineItem}"/>
 ----------------- ADD THE CODE BELOW ----------------------
 <iscomment>Optty Widget </iscomment>
 <isinclude template="widget/opttybillingcheckoutwidget"/>

c. Replace the below code

<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

<isif condition="${(dw.system.Site.current.getCustomPreferenceValue('opttyDefaultCheckout') === true) || (dw.system.Site.current.getCustomPreferenceValue('opttyDefaultCheckout') === false && dw.system.Site.current.getCustomPreferenceValue('opttyCustomCheckoutButton') === false)}">
 <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>
</isif>

11. default/checkout/billing/paymentmethods.isml

a. Add the code under the specified line.

<iscomment>Ignore GIFT_CERTIFICATE method, GCs are handled separately before other payment methods.</iscomment>
 <isif condition="${paymentMethodType.value.equals(dw.order.PaymentInstrument.METHOD_GIFT_CERTIFICATE)}"><iscontinue/></isif>
 ----------------- ADD THE CODE BELOW ----------------------
<isset name="isOptty" value="${paymentMethodType.value.equals('OPTTY') ? true : false}" scope="page" />
<isset name="opttyDefaultCheckout" value="${dw.system.Site.current.getCustomPreferenceValue('opttyDefaultCheckout')}" scope="page" />
<iscomment>Ignore OPTTY method, if it is not supposed to be displayed</iscomment>
<isif condition="${isOptty && (opttyDefaultCheckout === false || dw.system.Site.current.getCustomPreferenceValue('isOpttyEnabled') === false || dw.system.Site.current.getCustomPreferenceValue('opttyEnableCheckoutWidget') === false)}">
 <iscontinue/>
</isif>
<iscomment>Ignore OPTTY payment providers, if it is not supposed to be displayed</iscomment>
<isif condition="${isOpttyProvider && (opttyDefaultCheckout === true || dw.system.Site.current.getCustomPreferenceValue('isOpttyEnabled') === false || dw.system.Site.current.getCustomPreferenceValue('opttyEnableCheckoutWidget') === false)}">
 <iscontinue/>
</isif>

b. Replace the below line,

<div class="form-row label-inline">
<isset name="radioID" value="${paymentMethodType.value}" scope="page"/>
<div class="field-wrapper">
<input id="is-${radioID}" type="radio" class="input-radio" name="${pdict.CurrentForms.billing.paymentMethods.selectedPaymentMethodID.htmlName}" value="${paymentMethodType.htmlValue}" <isif condition="${paymentMethodType.value == pdict.CurrentForms.billing.paymentMethods.selectedPaymentMethodID.htmlValue}">checked="checked"</isif> />
</div>
<label for="is-${radioID}"><isprint value="${Resource.msg(paymentMethodType.label,'forms',null)}"/></label>
</div>

With:

<div class="form-row label-inline">
 <isset name="radioID" value="${paymentMethodType.value}" scope="page"/>
 <div class="field-wrapper">
 <input id="is-${radioID}" type="radio" class="input-radio" name="${pdict.CurrentForms.billing.paymentMethods.selectedPaymentMethodID.htmlName}" value="${paymentMethodType.htmlValue}" <isif condition="${paymentMethodType.value == pdict.CurrentForms.billing.paymentMethods.selectedPaymentMethodID.htmlValue}">checked="checked"</isif> />
 </div>
 <isif condition="${isOptty}">
 <img width="90" class="optty-payment-icon" src="https://widgets.dev.optty.com/images/optty/black/optty-sub.svg" alt="Optty Logo">
 <iselseif condition="${isOpttyProvider && logoImageUrl}">
 <img width="90" class="optty-payment-provider-icon" src="${logoImageUrl}" alt="${paymentMethodType.value} Logo">
 <iselse/>
 <label for="is-${radioID}"><isprint value="${Resource.msg(paymentMethodType.label,'forms',null)}"/></label>
 </isif>
</div>

c. Add the code under specified line.

<iscomment>
 Custom processor
 --------------------------------------------------------------
 </iscomment>
 ----------------- ADD THE CODE BELOW ----------------------
 <div class="payment-method <isif condition="${!empty(pdict.selectedPaymentID) && pdict.selectedPaymentID=='OPTTY'}">payment-method-expanded</isif>" data-method="OPTTY">
 <iscomment>Optty Widget</iscomment>
 <isinclude template="widget/opttypaymentoptionswidget"/>
 </div>

12. templates/default/checkout/summary/summary.isml

a. Replace the below code block,

<form action="${URLUtils.https('COSummary-Submit')}" method="post" class="submit-order">
 <fieldset>
 <div class="form-row">
 <a class="back-to-cart" href="${URLUtils.url('Cart-Show')}">
 <isprint value="${Resource.msg('summary.editcart','checkout',null)}" encoding="off" />
 </a>
 <button class="button-fancy-large" type="submit" name="submit" value="${Resource.msg('global.submitorder', 'locale',null)}">
 ${Resource.msg('global.submitorder','locale',null)}
 </button>
 </div>
 <input type="hidden" name="${dw.web.CSRFProtection.getTokenName()}" value="${dw.web.CSRFProtection.generateToken()}"/>
 </fieldset>
</form>

With:

<iscomment>Optty Place order button</iscomment>
<isinclude template="widget/opttysummarycheckoutwidget"/>

Client-side JavaScript

1. js/pages/checkout/billing.js

a. Add the following function.

/**
 * @function
 * @description Redirected to optty bnpl provider page
 */
function opttyPlaceOrder(bnplProvider) {
 var url = Urls.opttyCheckout;
 var postData = {bnplProvider: bnplProvider};
 $.post(url, postData, function (data) {
 var result = data ? data : {};
 if (!result.error && result.redirectUrl) {
 window.location.href = result.redirectUrl;
 } else {
 window.location.href = result.redirectUrl;
 }
 });
}

b. Add code to the exports.init function.

$giftCertCode.on('keydown', function (e) {
 if (e.which === 13) {
 e.preventDefault();
 $addGiftCert.click();
 }
 });
 ----------------- ADD THE CODE BELOW----------------------
 // Optty redirect from billing page
 $checkoutForm.on('click','button[name$="_billing_save"]', function(e){
 if (SitePreferences.OPTTY_ENABLE && SitePreferences.SUMMARY_PAGE_ENABLE === false && $('input[name$=_paymentMethods_selectedPaymentMethodID]:checked').val() == 'OPTTY'){
 e.preventDefault();
 var $this = $(this);
 var url = util.appendParamsToUrl($this.closest('form').attr('action'), {format: 'ajax'});
 $.ajax({
 url: url,
 type: 'post',
 data: $this.closest('form').serialize(),
 success: function(data){
 if (data.status === 'success') {
 window.postMessage({type: 'modal-checkout-box'});
 }
 }
 });
 } else {
 $checkoutForm.submit();
 }
 });
 // Open optty popup
 $('.optty-place-order-button').click(function () {
 window.postMessage({type: 'modal-checkout-box'});
 });
 // Receive events from optty popup
 window.addEventListener('message', function (event) {
 if (event.data.type === 'continue_click_checkout') {
 var bnplProvider = event.data.name;
 opttyPlaceOrder(bnplProvider);
 } else if (event.data.type === 'demo-checkout-btn-click') {
 if (SitePreferences.SUMMARY_PAGE_ENABLE) {
 $checkoutForm.submit();
 } else {
 if (!$checkoutForm.valid()) {
 $checkoutForm.data().validator.errorList[0].element.focus();
 return;
 }
 var url = util.appendParamsToUrl($checkoutForm.attr('action'), {format: 'ajax'});
 $.ajax({
 url: url,
 type: 'post',
 data: $checkoutForm.serialize(),
 success: function (data) {
 if (data.status === 'success') {
 opttyPlaceOrder(event.data.provider);
 }
 }
 });
 }
 }
 })

SCSS

  • Move the file from ‘int_optty_core/cartridge/scss/default/_optty.scss’ to ‘<SiteGenesis core cartridge> /cartridge/scss/default/_optty.scss’.

  • scss/default/style.scss

Add the code under the specified line.
@import "responsive";
@import "print";
----------------- ADD THE CODE BELOW----------------------
@import "optty";

3.4 Testing

  1. In Business Manager, navigate to Merchant Tools > Site Preferences > Custom Preferences. A custom site preference group with the ID ‘Optty Settings’ is available. Please click on the group ID and set the respective data obtained from Optty.

  2. In Business Manager, navigate to Administration > Operations > Services. Then click on the ‘Credentials’ tab. Set the service URL to the relevant environment for ‘optty.auth.credentials’ and ‘optty.generic.credentials’.

  3. In Business Manager, navigate to Administration > Operations > Jobs. Find the job ‘OpttyMerchantData’ and run the job.

  4. A merchant needs to set up a return callback URL for Optty. The return call-back URL is https://<Host name>/on/demandware.store/Sites-<Site ID>-Site/<Site Locale ID>/OpttyCheckout-HandleResponse

  5. When the service is unavailable, Optty API will provide the industry-wide and expected HTTP 500 response error and the user cannot see the live widget in the storefront and is unable to checkout using ‘Optty’ payment method.

Last updated