Skip to content

Commit 0bf7b61

Browse files
Merge pull request #21 from CyberSource/release-25.3.0
Implemented Payer Auth for GooglePay
2 parents f18b44f + c588a45 commit 0bf7b61

File tree

17 files changed

+356
-283
lines changed

17 files changed

+356
-283
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
- **Description:** Cybersource, a Visa solution, is the only global, modular payment management platform built on secure Visa infrastructure with the payment reach and fraud insights of a massive $500B+ global processing network. You can find out more about what Cybersource does [here](https://www.cybersource.com/en-gb.html)
44
- **Categories:** Payment Processing, Fraud Detection, Address Validation, Tax Computation
5-
- **Version:** 25.2.0
6-
- **Last Certification Date:** March 2025
5+
- **Version:** 25.3.0
6+
- **Last Certification Date:** May 2025
77
- **Supports SFRA v7.0**
88
- **JavaScript Controllers Friendly:** **YES**
99

cartridges/int_cybs_sfra/cartridge/client/default/js/googlePay.js

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ var baseCardPaymentMethod = {
3030
type: 'CARD',
3131
parameters: {
3232
allowedAuthMethods: allowedCardAuthMethods,
33-
allowedCardNetworks: allowedCardNetworks
33+
allowedCardNetworks: allowedCardNetworks,
34+
assuranceDetailsRequired: true
3435
}
3536
};
3637

@@ -144,16 +145,30 @@ function addGooglePayButton() {
144145
}
145146
}
146147

148+
149+
// Function to format money based on input
150+
function formatInputMoney(input) {
151+
var standardNumber = input;
152+
if (input.indexOf(",") > input.indexOf(".") || (input.indexOf(",") !== -1 && input.indexOf(".") === -1)) {
153+
standardNumber = parseFloat(input.replace(".", "").replace(",", ".").replace(/[^0-9.]/g, ''));
154+
} else {
155+
standardNumber = parseFloat(input.replace(/[^0-9.]/g, ''));
156+
}
157+
return standardNumber;
158+
}
159+
147160
/**
148161
* @returns {*} *
149162
*/
150163
function getGoogleTransactionInfo() {
164+
var totalPriceRaw = $('body').find('.row.grand-total').find('.grand-total-sum').text();
165+
var totalPrice = formatInputMoney(totalPriceRaw);
166+
151167
return {
152-
countryCode: 'US',
153-
currencyCode: 'USD',
168+
countryCode: window.googlepayval.countryCode,
169+
currencyCode: window.googlepayval.currencyCode,
154170
totalPriceStatus: 'FINAL',
155-
totalPrice: $('body').find('.row.grand-total').find('.grand-total-sum').text()
156-
.replace('$', '')
171+
totalPrice: totalPrice.toString()
157172
};
158173
}
159174
/**
@@ -162,7 +177,7 @@ function prefetchGooglePaymentData() {
162177
var paymentDataRequest = getGooglePaymentDataRequest();
163178
paymentDataRequest.transactionInfo = {
164179
totalPriceStatus: 'NOT_CURRENTLY_KNOWN',
165-
currencyCode: 'USD'
180+
currencyCode: window.googlepayval.currencyCode
166181
};
167182
// eslint-disable-next-line no-shadow
168183
var paymentsClient = getGooglePaymentsClient();

cartridges/int_cybs_sfra/cartridge/client/default/js/googlePayBilling.js

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ var baseCardPaymentMethod = {
3131
parameters: {
3232
allowedAuthMethods: allowedCardAuthMethods,
3333
allowedCardNetworks: allowedCardNetworks,
34+
assuranceDetailsRequired: true,
3435
billingAddressRequired: true,
3536
billingAddressParameters: {
3637
format: 'FULL',
@@ -45,15 +46,29 @@ var cardPaymentMethod = {
4546
};
4647
var paymentsClient = null;
4748

49+
// Function to format money based on input
50+
function formatInputMoney(input) {
51+
var standardNumber = input;
52+
if (input.indexOf(",") > input.indexOf(".") || (input.indexOf(",") !== -1 && input.indexOf(".") === -1)) {
53+
standardNumber = parseFloat(input.replace(".", "").replace(",", ".").replace(/[^0-9.]/g, ''));
54+
} else {
55+
standardNumber = parseFloat(input.replace(/[^0-9.]/g, ''));
56+
}
57+
return standardNumber;
58+
}
59+
4860
/**
4961
* @returns {*} *
5062
*/
5163
function getGoogleTransactionInfo() {
64+
var totalPrice = '';
65+
var totalPriceRaw = $('.checkout-continue').find('#carttotal').val() != null ? $('.checkout-continue').find('#carttotal').val().replace('$', '') : '';
66+
totalPrice = formatInputMoney(totalPriceRaw);
5267
return {
53-
countryCode: 'US',
54-
currencyCode: 'USD',
68+
countryCode: window.googlepayval.countryCode,
69+
currencyCode: window.googlepayval.currencyCode,
5570
totalPriceStatus: 'FINAL',
56-
totalPrice: $('.checkout-continue').find('#carttotal').val() != null ? $('.checkout-continue').find('#carttotal').val().replace('$', '') : ''
71+
totalPrice: totalPrice.toString()
5772
};
5873
}
5974

@@ -112,7 +127,7 @@ function prefetchGooglePaymentData() {
112127
var paymentDataRequest = getGooglePaymentDataRequest();
113128
paymentDataRequest.transactionInfo = {
114129
totalPriceStatus: 'NOT_CURRENTLY_KNOWN',
115-
currencyCode: 'USD'
130+
currencyCode: window.googlepayval.currencyCode
116131
};
117132
// eslint-disable-next-line no-shadow
118133
var paymentsClient = getGooglePaymentsClient();

cartridges/int_cybs_sfra/cartridge/templates/default/common/layout/page.isml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<isinclude template="/components/modules" sf-toolkit="off" />
33
<isset name="enableGooglePayOnMiniCart" value="${require('*/cartridge/configuration/index').enableGooglePayOnMiniCart}" scope="page" />
44
<isset name="enableGooglePayOnCart" value="${require('*/cartridge/configuration/index').enableGooglePayOnCart}" scope="page" />
5+
<isset name="countryCode" value="${require('dw/util/Locale').getLocale(request.getLocale()).getCountry()}" scope="page" />
56

67
<!DOCTYPE html>
78
<html lang="${require('dw/util/Locale').getLocale(request.getLocale()).getLanguage()}">
@@ -41,11 +42,11 @@
4142
<script>
4243
var googlePayVariables = {
4344
currencyCode: "${session.getCurrency().getCurrencyCode()}",
45+
countryCode: "${countryCode}",
4446
totalPriceStatus: 'FINAL',
4547
sessionCallBack : "${dw.web.URLUtils.url('CheckoutServices-GetGooglePayToken')}",
4648
returnURL : "${dw.web.URLUtils.https('Checkout-Begin', 'stage', 'placeOrder')}",
4749
cartURL : "${dw.web.URLUtils.https('Checkout-Begin', 'stage', 'payment','payerAuthError', Resource.msg('message.payerAuthError', 'error', null))}"
48-
//"${dw.web.URLUtils.https('Cart-Show')}",
4950
}
5051
window.googlepayval = googlePayVariables;
5152
</script>

cartridges/int_cybs_sfra/cartridge/templates/default/common/scripts.isml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<isset name="merchantIDPref" value="${require('*/cartridge/configuration/index').merchantID}" scope="page" />
1515
<isset name="googlePayEnabled" value="${require('*/cartridge/configuration/index').googlePayEnabled}" scope="page" />
1616
<isset name="googlePayEnvironmentPref" value="${require('*/cartridge/configuration/index').googlePayEnvironment}" scope="page" />
17+
<isset name="countryCode" value="${require('dw/util/Locale').getLocale(request.getLocale()).getCountry()}" scope="page" />
1718

1819
<input type="hidden" name="googlePayMerchantID" id="googlePayMerchantID" value="${googlePayMerchantIdPref}"/>
1920
<input type="hidden" name="googlePaygatewayMerchantId" id="googlePaygatewayMerchantId" value="${merchantIDPref}"/>
@@ -26,13 +27,12 @@
2627

2728
var googlePayVariables = {
2829
currencyCode: "${session.getCurrency().getCurrencyCode()}",
30+
countryCode: "${countryCode}",
2931
totalPriceStatus: 'FINAL',
3032
sessionCallBack : "${dw.web.URLUtils.url('CheckoutServices-SubmitPaymentGP')}",
3133
submitURL : "${dw.web.URLUtils.https('Checkout-Begin', 'stage', 'placeOrder')}"
3234
}
3335

34-
 
35-
                   
3636
window.googlepayval = googlePayVariables;
3737

3838
</script>

cartridges/int_cybs_sfra_base/cartridge/apiClient/constants.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,13 @@ module.exports = {
3131
SANDBOX_RUN_ENV: "cybersource.environment.sandbox",
3232
PRODUCTION_RUN_ENV: "cybersource.environment.production",
3333
APPLICATION_NAME: "Salesforce B2C(REST)",
34-
APPLICATION_VERSION: "25.2.0",
35-
34+
APPLICATION_VERSION: "25.3.0",
35+
3636
/* Digest Constants*/
3737
SIGNATURE_ALGORITHAM: "SHA-256=",
3838
HmacSHA256: "HmacSHA256",
3939

4040
/* Flex microform constants */
41-
ENCRYPTION_TYPE: "RsaOaep256",
4241
CLIENT_VERSION : "v2",
4342

4443

cartridges/int_cybs_sfra_base/cartridge/configuration/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ var LogfileMaxSize = '5242880'; // 10 MB In Bytes
2323
* Send this value in all requests that are sent through the partner solution. CyberSource assigns the ID to the partner.
2424
* Note When you see a partner ID of 999 in reports, the partner ID that was submitted is incorrect.
2525
*/
26-
var SolutionId = 'GTIWK1VH';
26+
var SolutionId = 'I1YMGX8S';
2727

2828
var CruiseDDCEndPoint = {
2929
Stage: 'https://centinelapistag.cardinalcommerce.com/V1/Cruise/Collect',

cartridges/int_cybs_sfra_base/cartridge/controllers/Checkout.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ server.prepend(
2424
return next();
2525
}
2626
session.custom.Flag3ds = false;
27+
session.custom.scaTokenFlag = false;
2728
// eslint-disable-next-line no-undef
2829
if (session.getCustomer().getProfile() !== null) {
2930
// eslint-disable-next-line no-undef

cartridges/int_cybs_sfra_base/cartridge/controllers/CheckoutServices.js

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@ var currentBasket = BasketMgr.getCurrentBasket();
1212
var paymentMethod = currentBasket && currentBasket.paymentInstrument && currentBasket.paymentInstrument.paymentMethod;
1313
var isVisaSRC = paymentMethod && paymentMethod === 'CLICK_TO_PAY';
1414

15+
var isGPay_PayerAuthEnabled = false;
16+
if(!empty(session.privacy.encryptedDataGP) && session.custom.isGpayCardHolderAuthenticated == false && configObject.payerAuthenticationEnabled) {
17+
isGPay_PayerAuthEnabled = true;
18+
}
1519
// eslint-disable-next-line no-undef
16-
if (configObject.payerAuthenticationEnabled && configObject.cartridgeEnabled && empty(session.privacy.encryptedDataGP)
17-
&& !isVisaSRC
18-
) {
20+
if (((configObject.payerAuthenticationEnabled && empty(session.privacy.encryptedDataGP)) || isGPay_PayerAuthEnabled) && configObject.cartridgeEnabled && !isVisaSRC) {
21+
1922
// eslint-disable-next-line consistent-return
2023
server.prepend('PlaceOrder', server.middleware.https, function (req, res, next) {
2124

@@ -193,10 +196,10 @@ if (configObject.payerAuthenticationEnabled && configObject.cartridgeEnabled &&
193196
jwttoken: billingForm.creditCardFields.flexresponse.value,
194197
securityCode: billingForm.creditCardFields.securityCode.value,
195198
fluidData: paymentInstrument.custom.fluidData,
199+
googlePayFluidData: session.privacy.encryptedDataGP,
196200
callId: paymentInstrument.custom.callID
197201
};
198202

199-
200203
var setupResponse = payerAuthentication.paSetup(billingForm, session.privacy.orderID, card);
201204
var accessToken = setupResponse.consumerAuthenticationInformation.accessToken;
202205
session.privacy.deviceDataCollectionUrl = setupResponse.consumerAuthenticationInformation.deviceDataCollectionUrl;
@@ -299,6 +302,7 @@ server.post('getResponse', server.middleware.https, function (req, res, next) {
299302
jwttoken: billingForm.creditCardFields.flexresponse.value,
300303
securityCode: billingForm.creditCardFields.securityCode.value,
301304
fluidData: paymentInstrument.custom.fluidData,
305+
googlePayFluidData: session.privacy.encryptedDataGP,
302306
callId: paymentInstrument.custom.callID
303307
};
304308
}
@@ -342,6 +346,8 @@ server.post('getResponse', server.middleware.https, function (req, res, next) {
342346
session.privacy.orderID = '';
343347
// eslint-disable-next-line no-undef
344348
session.privacy.orderToken = '';
349+
delete session.privacy.encryptedDataGP;
350+
delete session.custom.isGpayCardHolderAuthenticated;
345351
}
346352
// eslint-disable-next-line
347353
else if (enrollResponse.errorInformation.reason === 'CUSTOMER_AUTHENTICATION_REQUIRED' && session.custom.Flag3ds === false) {
@@ -362,6 +368,8 @@ server.post('getResponse', server.middleware.https, function (req, res, next) {
362368
session.privacy.orderID = '';
363369
// eslint-disable-next-line no-undef
364370
session.privacy.orderToken = '';
371+
delete session.privacy.encryptedDataGP;
372+
delete session.custom.isGpayCardHolderAuthenticated;
365373
}
366374

367375
res.render('payerAuthentication/checkoutRedirect', {
@@ -411,6 +419,7 @@ server.post('handlingConsumerAuthResponse', server.middleware.https, function (r
411419
jwttoken: billingForm.creditCardFields.flexresponse.value,
412420
securityCode: billingForm.creditCardFields.securityCode.value,
413421
fluidData: paymentInstrument.custom.fluidData,
422+
googlePayFluidData: session.privacy.encryptedDataGP,
414423
callId: paymentInstrument.custom.callID
415424
};
416425
}
@@ -436,6 +445,8 @@ server.post('handlingConsumerAuthResponse', server.middleware.https, function (r
436445
session.privacy.orderID = '';
437446
// eslint-disable-next-line no-undef
438447
session.privacy.orderToken = '';
448+
delete session.privacy.encryptedDataGP;
449+
delete session.custom.isGpayCardHolderAuthenticated;
439450
}
440451

441452
// eslint-disable-next-line
@@ -458,6 +469,8 @@ server.post('handlingConsumerAuthResponse', server.middleware.https, function (r
458469
session.privacy.orderID = '';
459470
// eslint-disable-next-line no-undef
460471
session.privacy.orderToken = '';
472+
delete session.privacy.encryptedDataGP;
473+
delete session.custom.isGpayCardHolderAuthenticated;
461474
}
462475
res.render('payerAuthentication/checkoutRedirect', {
463476
redirect: redirect,
@@ -469,6 +482,7 @@ server.post('handlingConsumerAuthResponse', server.middleware.https, function (r
469482
return next();
470483
});
471484

485+
// for Gpay on checkout page
472486
server.post('SubmitPaymentGP', function (req, res, next) {
473487
var COHelpers = require('*/cartridge/scripts/checkout/checkoutHelpers');
474488
var Encoding = require('dw/crypto/Encoding');
@@ -493,6 +507,7 @@ server.post('SubmitPaymentGP', function (req, res, next) {
493507
// eslint-disable-next-line no-undef
494508
var paymentData = JSON.parse(request.httpParameterMap.googletoken);
495509
var GPtoken = paymentData.paymentMethodData.tokenizationData.token;
510+
session.custom.isGpayCardHolderAuthenticated = paymentData.paymentMethodData.info.assuranceDetails.cardHolderAuthenticated;
496511
// eslint-disable-next-line no-undef
497512
session.privacy.encryptedDataGP = Encoding.toBase64(new dw.util.Bytes(GPtoken));
498513

@@ -689,6 +704,7 @@ function shippingUpdate(cart, shippingdetails) {
689704
}
690705
}
691706

707+
//for Gapy on cart and minicart
692708
// eslint-disable-next-line consistent-return
693709
server.post('GetGooglePayToken', function (req, res, next) {
694710
var Encoding = require('dw/crypto/Encoding');
@@ -720,6 +736,7 @@ server.post('GetGooglePayToken', function (req, res, next) {
720736
ShippingHelper.selectShippingMethod(cart.defaultShipment, null);
721737
});
722738
var GPtoken = response.paymentMethodData.tokenizationData.token;
739+
session.custom.isGpayCardHolderAuthenticated = response.paymentMethodData.info.assuranceDetails.cardHolderAuthenticated;
723740
// eslint-disable-next-line no-undef
724741
session.privacy.encryptedDataGP = Encoding.toBase64(new dw.util.Bytes(GPtoken));
725742
} else {

cartridges/int_cybs_sfra_base/cartridge/scripts/hooks/payment/processor/payments_credit.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,8 @@ function Authorize(orderNumber, paymentInstrument, paymentProcessor) {
264264
gPayToken: session.privacy.encryptedDataGP
265265
};
266266
// eslint-disable-next-line no-undef
267-
session.privacy.encryptedDataGP = '';
267+
delete session.privacy.encryptedDataGP;
268+
delete session.custom.isGpayCardHolderAuthenticated;
268269
var customerEmail = order.customerEmail;
269270
var currencyCode = order.currencyCode.toUpperCase();
270271
try {

0 commit comments

Comments
 (0)