Skip to content

Commit

Permalink
Afterpay v23.3.0
Browse files Browse the repository at this point in the history
- Added support for currency localisation for eligible merchants to offer Afterpay/Clearpay in multiple currencies.

- Added support for restricted products, where multiple products can be excluded from Afterpay/Clearpay.

- Fixed a defect where a shipping method wasn’t pre-selected for express checkout.

- Other minor fixes and improvements.
  • Loading branch information
ghatamehta-afterpay committed Jul 12, 2023
1 parent 0b53bd2 commit c3f9689
Show file tree
Hide file tree
Showing 76 changed files with 19,099 additions and 335 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ cartridges/int_afterpay_sfra_6/cartridge/static/default/js/cashappCheckoutMobile
dw.json
.DS_Store
.vscode/system-objecttype-extensions.d.ts
*.zip
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<iscontent type="text/html" charset="UTF-8" compact="true">
<isinclude template="pagecomponents/htmlheadinclude">
<isinclude url="${URLUtils.url('SiteNavigationBar-IncludeFrameTop','SelectedMenuItem',pdict.SelectedMenuItem,'CurrentMenuItemId',pdict.CurrentMenuItemId)}">
<iscontent type="text/html" charset="UTF-8" compact="true" />
<isinclude template="pagecomponents/htmlheadinclude" />
<isinclude url="${URLUtils.url('SiteNavigationBar-IncludeFrameTop','SelectedMenuItem',pdict.SelectedMenuItem,'CurrentMenuItemId',pdict.CurrentMenuItemId)}" />
<div class="afterpay-module">
<isreplace/>
<isreplace/>
</div>
<isinclude url="${URLUtils.url('SiteNavigationBar-IncludeFrameBottom')}">
<isinclude url="${URLUtils.url('SiteNavigationBar-IncludeFrameBottom')}" />
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<!--- TEMPLATENAME: afterpayorder.isml --->
<isdecorate template="application/MenuFrame">
<iscontent type="text/html" charset="UTF-8">
<iscontent type="text/html" charset="UTF-8" />
<isinclude template="custom/modules" />
<isinclude template="inc/Modules">
<isinclude template="inc/Modules" />
<isset name="orderNo" value="${pdict.CurrentHttpParameterMap.OrderNo.stringValue}" scope ="page"/>
<isbreadcrumbs bcurl1="${URLUtils.url('AfterPay-OrderList')}"
bctext1="${Resource.msg('order.list.label','afterpay',null)}"
Expand Down Expand Up @@ -172,5 +172,5 @@
</isif>

<script src="${URLUtils.staticURL('/js/transactions.js')}"></script>
<script type="text/javascript"><isinclude template="application/appresources"/></script>
<script><isinclude template="application/appresources"/></script>
</isdecorate>
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<!--- TEMPLATENAME: homelanding.isml --->
<isdecorate template="application/MenuFrame">

<iscontent type="text/html" charset="UTF-8">
<iscontent type="text/html" charset="UTF-8" />
<isinclude template="custom/modules" />
<isinclude template="inc/Modules">
<isinclude template="inc/Modules" />
<isbreadcrumbs bcurl1="${URLUtils.url('AfterPay-OrderList')}"
bctext1="${Resource.msg('order.list.label','afterpay',null)}" />

Expand Down Expand Up @@ -76,7 +76,6 @@
</tbody>
</table>
<isinclude template="application/orderlistpagination" />

</isif>
<script type="text/javascript"><isinclude template="application/appresources"/></script>
</isif>
<script><isinclude template="application/appresources"/></script>
</isdecorate>
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ var checkoutTools = {

if (basket && basket.getAllProductLineItems().length > 0) {
var orderTotal = basket.totalGrossPrice.available ? basket.totalGrossPrice : basket.getAdjustedMerchandizeTotalPrice(true).add(basket.giftCertificateTotalPrice);
withinTheshold = thresholdUtilities.checkThreshold(orderTotal).status;
withinTheshold = thresholdUtilities.checkThreshold(orderTotal).status && !this.checkRestrictedCart();
}

return withinTheshold;
Expand All @@ -171,7 +171,7 @@ var checkoutTools = {
}
var orderTotal = basket.totalGrossPrice.available ? basket.totalGrossPrice : basket.getAdjustedMerchandizeTotalPrice(true).add(basket.giftCertificateTotalPrice);

return thresholdUtilities.checkThreshold(orderTotal).status;
return thresholdUtilities.checkThreshold(orderTotal).status && !this.checkRestrictedCart();
},
// compute a checksum from the Afterpay Response
// if anything changed
Expand All @@ -191,6 +191,47 @@ var checkoutTools = {
}
Logger.debug('Final Checksum' + cksum);
return cksum;
},
checkRestrictedCart: function () {
var currentBasket = BasketMgr.getCurrentBasket();
if (currentBasket && currentBasket.getAllProductLineItems().length > 0) {
var productLineItems = currentBasket.getAllProductLineItems().iterator();
var ProductMgr = require('dw/catalog/ProductMgr');
while (productLineItems.hasNext()) {
var productLineItem = productLineItems.next();
var product = productLineItem.product;

if (!product) {
var parentProductID = productLineItem.parent.productID;
product = ProductMgr.getProduct(parentProductID);
}

if (product) {
var reqProductID = product.ID;
if (this.checkRestrictedProducts(reqProductID)) {
return true;
}
}
}
}
return false;
},
checkRestrictedProducts: function (reqProductID) {
var apSitePreferences = require('*/cartridge/scripts/util/afterpayUtilities').sitePreferencesUtilities;
var afterpayRestrictedProducts = apSitePreferences.getRestrictedProducts();
var ProductMgr = require('dw/catalog/ProductMgr');
var product = ProductMgr.getProduct(reqProductID);

if (product && product.isVariant()) {
if (product.masterProduct.ID && afterpayRestrictedProducts.indexOf(product.masterProduct.ID) > '-1') {
return true;
}
}

if (reqProductID && afterpayRestrictedProducts.indexOf(reqProductID) > '-1') {
return true;
}
return false;
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ function getPaymentStatus(order, paymentStatus, expressCheckoutModel, isCashAppP
var paymentResult;
try {
paymentResult = baseUpdateOrderService.handleOrder(order, parsedPaymentStatus, expressCheckoutModel, isCashAppPayment);
if (paymentResult && paymentResult.status === 'DECLINED') {
if (paymentResult && paymentResult.status === PAYMENT_STATUS.DECLINED) {
parsedPaymentStatus = paymentResult.status;
}
afterpayUpdateOrder.handleUpdateOrder(order, paymentResult, sitePreferencesUtilities.getPaymentMode().value, isCashAppPayment);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';

var Site = require('dw/system/Site');

var PAYMENT_STATUS = require('*/cartridge/scripts/util/afterpayConstants').PAYMENT_STATUS;
var LogUtils = require('*/cartridge/scripts/util/afterpayLogUtils');
var Logger = LogUtils.getLogger('afterpayIdempotency');

Expand Down Expand Up @@ -43,7 +43,7 @@ function delayPayment(Order, initialStatus, expressCheckoutModel) {
sleep(Site.getCurrent().getCustomPreferenceValue('apDelayRetry'));
Logger.debug('After 5 secs time delay : ' + new Date());
paymentStatus = require('*/cartridge/scripts/checkout/afterpayHandlePaymentOrder').getPaymentStatus(Order, initialStatus, expressCheckoutModel);
if (paymentStatus === 'APPROVED') {
if (paymentStatus == PAYMENT_STATUS.APPROVED) {
break;
}
Logger.debug('Final Payment Status : ' + paymentStatus);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,11 @@ var afterpayUpdateOrder = {

if (paymentMode === afterpayConstants.PAYMENT_MODE.DIRECT_CAPTURE) {
payTrans.custom.apDirectPaymentStatus = paymentResult.status;
amount = empty(paymentResult.originalAmount) ? null : new Money(parseFloat(paymentResult.originalAmount.amount), paymentResult.originalAmount.currency);
} else {
payTrans.custom.apAuthoriseStatus = paymentResult.status;
amount = empty(paymentResult.openToCaptureAmount) ? null : new Money(parseFloat(paymentResult.openToCaptureAmount.amount), paymentResult.openToCaptureAmount.currency);
}

amount = empty(paymentResult.originalAmount) ? null : new Money(parseFloat(paymentResult.originalAmount.amount), paymentResult.originalAmount.currency);
if (paymentResult.status === afterpayConstants.PAYMENT_STATUS.ACTIVE && amount === null) {
amount = empty(paymentResult.amount) ? null : new Money(parseFloat(paymentResult.amount.amount), paymentResult.amount.currency);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ var Context = function () {
this.actionEndpointMap = {
getPayment: 'payments/{0}',
directCapturePayment: 'payments/capture',
getConfiguration: 'configuration',
getConfiguration: 'configuration?include=cbt',
createRefund: 'payments/{0}/refund',
authorise: 'payments/auth',
createOrders: 'checkouts',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ var getUpdateOrderService = function () {
var paymentTransaction = AfterpayCheckoutUtilities.getPaymentTransaction(order);

Transaction.wrap(function () {
if (paymentMode === PAYMENT_MODE.AUTHORISE) {
if (paymentMode == PAYMENT_MODE.AUTHORISE) {
paymentTransaction.custom.apAuthoriseStatus = status;
} else {
paymentTransaction.custom.apDirectPaymentStatus = status;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,21 +47,33 @@ function getAfterpayHttpService() {
service.setRequestMethod(requestBody.requestMethod);
service.addHeader('Content-Type', 'application/json');

var afterpayCartridge = 'AfterpayCartridge/23.2.0-rc1';
var afterpayCartridge = 'AfterpayCartridge/23.3.0';
var merchantID = service.configuration.credential.user;
var siteURL = URLUtils.httpsHome().toString();
var storeFront = Site.getCurrent().getID();
var hostURL = siteURL.substring(0, siteURL.indexOf('/', 14));
var compatibilityMode = dw.system.System.getCompatibilityMode();
var cashAppEnabled = apSitePreferencesUtilities.isCashAppEnabled() ? '1' : '0';
var storefrontVersion = '';
if (storeFront.includes('SiteGenesis')) {
if (storeFront.indexOf('SiteGenesis') >= 0) {
storefrontVersion = Resource.msg('revisioninfo.revisionnumber', 'revisioninfo', null);
} else if (storeFront.includes('RefArch')) {
} else if (storeFront.indexOf('RefArch') >= 0) {
storefrontVersion = Resource.msg('global.version.number', 'version', null);
}

var userAgent = afterpayCartridge + ' (SalesforceCommmerceCloud; ' + storeFront + '/' + storefrontVersion + '; CompatibilityMode/' + compatibilityMode + '; Merchant/' + merchantID + '; CashAppEnabled/' + cashAppEnabled + ') ' + hostURL;
var uaAdditionalInfo = [
'SalesforceCommerceCloud',
storeFront + '/' + storefrontVersion,
'CompatibilityMode/' + compatibilityMode,
'Merchant/' + merchantID,
'CashAppEnabled/' + cashAppEnabled
].join('; ');

var userAgent = [
afterpayCartridge,
'(' + uaAdditionalInfo + ')',
hostURL
].join(' ');

service.addHeader('User-Agent', userAgent);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ var UpdateOrderService = {

getAuthoriseDirectCaptureService: function () {
var paymentMode = apSitePreferencesUtilities.getPaymentMode();
if (paymentMode === PAYMENT_MODE.AUTHORISE) {
if (paymentMode == PAYMENT_MODE.AUTHORISE) {
return afterpayAuthoriseService;
}
return afterpayDirectCaptureService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ OrderRequestBuilder.prototype.buildRequest = function (params) {
.buildRequestMethod(requestMethod)
.buildMerchantReference(merchantReference)
.buildShiptoStore(store)
.buildExpressMode();
.buildExpressMode()
.buildShippingOptionIdentifier(basket);
};

/**
Expand Down Expand Up @@ -225,4 +226,14 @@ OrderRequestBuilder.prototype.buildShiptoStore = function (store) {
return this;
};

OrderRequestBuilder.prototype.buildShippingOptionIdentifier = function (basket) {
var shipment = basket.getDefaultShipment();

if (shipment.shippingMethod && shipment.shippingMethod.ID) {
this.context.shippingOptionIdentifier = shipment.shippingMethod.ID;
}

return this;
};

module.exports = OrderRequestBuilder;
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ var sitePreferencesUtilities = {
var expressSuppportedLocales = ['AU', 'US', 'GB', 'NZ', 'CA'];
// eslint-disable-next-line no-use-before-define
var currentLocale = brandUtilities.getCountryCode();
var isLocaleSupported = expressSuppportedLocales.includes(currentLocale);
var isLocaleSupported = expressSuppportedLocales.indexOf(currentLocale) >= 0;
return Site.getCurrent().getCustomPreferenceValue('apEnableExpressCheckout') && isLocaleSupported;
},

Expand All @@ -79,6 +79,18 @@ var sitePreferencesUtilities = {

isExpressCheckoutPdpEnabled: function () {
return Site.getCurrent().getCustomPreferenceValue('apEnableExpressCheckoutPdp');
},

getRestrictedProducts: function () {
var excludedProducts = Site.getCurrent().getCustomPreferenceValue('apRestrictedProducts');
var afterpayRestrictedProducts = [];

if (excludedProducts != null) {
afterpayRestrictedProducts = excludedProducts.split(',').map(function (item) {
return item.trim();
});
}
return afterpayRestrictedProducts;
}
};

Expand Down Expand Up @@ -190,14 +202,6 @@ var checkoutUtilities = {
return paymentTransaction.custom.apPaymentMode;
},

getPaymentMode: function (order) {
var paymentMode = this.getPaymentModeFromOrder(order);
if (empty(paymentMode)) {
paymentMode = sitePreferencesUtilities.getPaymentMode().value;
}
return paymentMode;
},

getPaymentResponseCode: function (callResult) {
var response = (callResult.errorMessage) ? callResult.errorMessage : callResult;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,29 @@ var thresholdUtilities = {
maxAmount: 0
};

if (thresholdResponse) {
var minThresholdObj = thresholdResponse.minimumAmount;
var maxThresholdObj = thresholdResponse.maximumAmount;
var minThresholdObj;
var maxThresholdObj;

if (minThresholdObj) {
configuration.minAmount = parseFloat(minThresholdObj.amount, 10);
var currentCurrency = session.currency.getCurrencyCode();
if (thresholdResponse && thresholdResponse.minimumAmount.currency !== currentCurrency) {
if (('CBT' in thresholdResponse) && thresholdResponse.CBT.enabled && thresholdResponse.CBT.limits) {
var cbtLimits = thresholdResponse.CBT.limits;
if (Object.keys(cbtLimits).length >= 1 && currentCurrency in cbtLimits) {
minThresholdObj = cbtLimits[currentCurrency].minimumAmount;
maxThresholdObj = cbtLimits[currentCurrency].maximumAmount;
}
}
} else {
minThresholdObj = thresholdResponse.minimumAmount;
maxThresholdObj = thresholdResponse.maximumAmount;
}

if (maxThresholdObj) {
configuration.maxAmount = parseFloat(maxThresholdObj.amount, 10);
}
if (minThresholdObj) {
configuration.minAmount = parseFloat(minThresholdObj.amount, 10);
}

if (maxThresholdObj) {
configuration.maxAmount = parseFloat(maxThresholdObj.amount, 10);
}

return configuration;
Expand Down Expand Up @@ -58,6 +70,7 @@ var thresholdUtilities = {
}

thresholdResult = this.parseConfigurationResponse(thresholdResponse);
this.saveThresholds(brand, thresholdResult);
}

return thresholdResult;
Expand Down Expand Up @@ -92,11 +105,8 @@ var thresholdUtilities = {

if (price) {
var threshold = this.getThresholdAmounts(afterpayBrand);
this.saveThresholds(afterpayBrand, threshold);
var isApplicable = brandUtilities.isAfterpayApplicable();
if (isApplicable) {
result.belowThreshold = price <= threshold.minAmount;
result.aboveThreshold = price >= threshold.maxAmount;
result.minThresholdAmount = threshold.minAmount;
result.maxThresholdAmount = threshold.maxAmount;

Expand Down
Loading

0 comments on commit c3f9689

Please sign in to comment.