diff --git a/README.md b/README.md index 029f9bd..70373a3 100755 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ * **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) * **Categories:** Payment Processing, Fraud Detection, Address Validation, Tax Computation -* **Version:** 21.1.0 -* **Last Certification Date:** July-2021 -* **Supports SFRA v5.3.0** +* **Version:** 24.1.0 +* **Last Certification Date:** February-2024 +* **Supports SFRA v6.3.0** * **JavaScript Controllers Friendly:** **YES** ### Contact ### diff --git a/cartridges/int_cybs_sfra/cartridge/client/default/js/checkout/billing.js b/cartridges/int_cybs_sfra/cartridge/client/default/js/checkout/billing.js index 162ecb6..5b3fe49 100644 --- a/cartridges/int_cybs_sfra/cartridge/client/default/js/checkout/billing.js +++ b/cartridges/int_cybs_sfra/cartridge/client/default/js/checkout/billing.js @@ -62,9 +62,9 @@ var baseUpdatePaymentInformation = base.methods.updatePaymentInformation; // eslint-disable-next-line consistent-return base.methods.updatePaymentInformation = function (order, customer) { // eslint-disable-line no-unused-vars - if ($(".tab-pane.active [name$='paymentMethod']").val() === 'VISA_SRC') { + if ($(".tab-pane.active [name$='paymentMethod']").val() === 'CLICK_TO_PAY') { var $paymentSummary = $('.payment-details'); - var htmlToAppend = 'VISA SRC'; + var htmlToAppend = 'Click to Pay'; $paymentSummary.empty().append(htmlToAppend); } else { return baseUpdatePaymentInformation(order, customer); diff --git a/cartridges/int_cybs_sfra/cartridge/templates/default/cart/RedirectToConformation.isml b/cartridges/int_cybs_sfra/cartridge/templates/default/cart/RedirectToConformation.isml new file mode 100644 index 0000000..2d03558 --- /dev/null +++ b/cartridges/int_cybs_sfra/cartridge/templates/default/cart/RedirectToConformation.isml @@ -0,0 +1,12 @@ + + + This template the use to redirect to the conformation page + + +
+ + +
+ \ No newline at end of file diff --git a/cartridges/int_cybs_sfra/cartridge/templates/default/cart/checkoutButtons.isml b/cartridges/int_cybs_sfra/cartridge/templates/default/cart/checkoutButtons.isml index 688f47a..c88e64d 100755 --- a/cartridges/int_cybs_sfra/cartridge/templates/default/cart/checkoutButtons.isml +++ b/cartridges/int_cybs_sfra/cartridge/templates/default/cart/checkoutButtons.isml @@ -2,9 +2,10 @@
- - ${Resource.msg('button.checkout','cart',null)} - + + ${Resource.msg('button.checkout', 'cart', null)} +
diff --git a/cartridges/int_cybs_sfra/cartridge/templates/default/checkout/billing/paymentOptions/paymentOptionsContent.isml b/cartridges/int_cybs_sfra/cartridge/templates/default/checkout/billing/paymentOptions/paymentOptionsContent.isml index bf3b863..da31346 100755 --- a/cartridges/int_cybs_sfra/cartridge/templates/default/checkout/billing/paymentOptions/paymentOptionsContent.isml +++ b/cartridges/int_cybs_sfra/cartridge/templates/default/checkout/billing/paymentOptions/paymentOptionsContent.isml @@ -4,7 +4,7 @@ - + diff --git a/cartridges/int_cybs_sfra/cartridge/templates/default/checkout/billing/paymentOptions/paymentOptionsSummary.isml b/cartridges/int_cybs_sfra/cartridge/templates/default/checkout/billing/paymentOptions/paymentOptionsSummary.isml index 4964dfe..6af0e11 100755 --- a/cartridges/int_cybs_sfra/cartridge/templates/default/checkout/billing/paymentOptions/paymentOptionsSummary.isml +++ b/cartridges/int_cybs_sfra/cartridge/templates/default/checkout/billing/paymentOptions/paymentOptionsSummary.isml @@ -1,6 +1,6 @@
- + diff --git a/cartridges/int_cybs_sfra/cartridge/templates/default/checkout/billing/paymentOptions/paymentOptionsTabs.isml b/cartridges/int_cybs_sfra/cartridge/templates/default/checkout/billing/paymentOptions/paymentOptionsTabs.isml index c47f413..25daa0d 100755 --- a/cartridges/int_cybs_sfra/cartridge/templates/default/checkout/billing/paymentOptions/paymentOptionsTabs.isml +++ b/cartridges/int_cybs_sfra/cartridge/templates/default/checkout/billing/paymentOptions/paymentOptionsTabs.isml @@ -8,7 +8,7 @@ - + diff --git a/cartridges/int_cybs_sfra/cartridge/templates/default/checkout/billing/paymentOptions/visaCheckout.isml b/cartridges/int_cybs_sfra/cartridge/templates/default/checkout/billing/paymentOptions/visaCheckout.isml index 0cf0a06..55344b3 100644 --- a/cartridges/int_cybs_sfra/cartridge/templates/default/checkout/billing/paymentOptions/visaCheckout.isml +++ b/cartridges/int_cybs_sfra/cartridge/templates/default/checkout/billing/paymentOptions/visaCheckout.isml @@ -9,7 +9,7 @@
+ value="CLICK_TO_PAY">
diff --git a/cartridges/int_cybs_sfra/cartridge/templates/default/secureAcceptanceFlexMicroformContent.isml b/cartridges/int_cybs_sfra/cartridge/templates/default/secureAcceptanceFlexMicroformContent.isml index 7e5a48c..246ddb2 100644 --- a/cartridges/int_cybs_sfra/cartridge/templates/default/secureAcceptanceFlexMicroformContent.isml +++ b/cartridges/int_cybs_sfra/cartridge/templates/default/secureAcceptanceFlexMicroformContent.isml @@ -50,8 +50,8 @@ Secure Acceptance Flex Microform Scripts - + - + \ No newline at end of file diff --git a/cartridges/int_cybs_sfra/cartridge/templates/resources/visaSRC.properties b/cartridges/int_cybs_sfra/cartridge/templates/resources/visaSRC.properties index 7f2a1fe..68a7246 100755 --- a/cartridges/int_cybs_sfra/cartridge/templates/resources/visaSRC.properties +++ b/cartridges/int_cybs_sfra/cartridge/templates/resources/visaSRC.properties @@ -1 +1,2 @@ -msg.paid.using.visa.src=Paid using VISA SRC +msg.paid.using.visa.src=Paid using Click to Pay +msg.click.to.pay=Click to Pay diff --git a/cartridges/int_cybs_sfra_base/cartridge/apiClient/ApiClient.js b/cartridges/int_cybs_sfra_base/cartridge/apiClient/ApiClient.js index 58b97d9..ae9cc0e 100644 --- a/cartridges/int_cybs_sfra_base/cartridge/apiClient/ApiClient.js +++ b/cartridges/int_cybs_sfra_base/cartridge/apiClient/ApiClient.js @@ -123,17 +123,17 @@ _exports.prototype.getHttpSignature = function (resource, method, merchantKeyId, // Headers - list is choosen based on HTTP method. // Digest is not required for GET Method if (method === "get" || method === "delete") { - var headersForGetMethod = "host date (request-target) v-c-merchant-id"; + var headersForGetMethod = "host date request-target v-c-merchant-id"; signatureHeader += ", headers=\"" + headersForGetMethod + "\""; } else if (method === "post" || method === "patch") { - var headersForPostMethod = "host date (request-target) digest v-c-merchant-id"; + var headersForPostMethod = "host date request-target digest v-c-merchant-id"; signatureHeader += ", headers=\"" + headersForPostMethod + "\""; } var signatureString = 'host: ' + requestHost; signatureString += '\ndate: ' + new Date(Date.now()).toUTCString(); - signatureString += '\n(request-target): '; + signatureString += '\nrequest-target: '; if (method === "get" || method === "delete") { var targetUrlForGet = method + " " + resource; diff --git a/cartridges/int_cybs_sfra_base/cartridge/configuration/index.js b/cartridges/int_cybs_sfra_base/cartridge/configuration/index.js index 1eca455..3e69ed9 100644 --- a/cartridges/int_cybs_sfra_base/cartridge/configuration/index.js +++ b/cartridges/int_cybs_sfra_base/cartridge/configuration/index.js @@ -23,7 +23,7 @@ var LogfileMaxSize = '5242880'; // 10 MB In Bytes * Send this value in all requests that are sent through the partner solution. CyberSource assigns the ID to the partner. * Note When you see a partner ID of 999 in reports, the partner ID that was submitted is incorrect. */ -var SolutionId = '3VKKRVBF'; +var SolutionId = 'J3P4XU2P'; var CruiseDDCEndPoint = { Stage: 'https://centinelapistag.cardinalcommerce.com/V1/Cruise/Collect', @@ -120,7 +120,6 @@ function getConfig(config) { deviceFingerprintThreadMatrixUrl: config.deviceFingerprintThreadMatrixUrl || customPreferences.DeviceFingerprint.Preferences.ThreadMatrixUrl.getValue(), deviceFingerprintTimeToLive: config.deviceFingerprintTimeToLive || customPreferences.DeviceFingerprint.Preferences.TimeToLive.getValue(), - // Future enhancement enableCapture: config.EnableCapture || false, // PayerAuthentication @@ -138,9 +137,8 @@ function getConfig(config) { enableGooglePayOnCart: config.enableGooglePayOnCart || customPreferences.GooglePay.Preferences.EnableGooglePayOnCart.getValue(), // DecisionManager - visaSRCEnabled: config.vscCheckoutEnabled || customPreferences.VisaSRC.Preferences.VisaSRCEnabled.getValue(), - visaSRCKey: config.visaSRCKey || customPreferences.VisaSRC.Preferences.VisaSRCKey.getValue(), - VisaSRCProduction: config.VisaSRCProduction || customPreferences.VisaSRC.Preferences.VisaSRCProduction.getValue() - }; + visaSRCEnabled: config.vscCheckoutEnabled || customPreferences.ClicktoPay.Preferences.ClicktoPayEnabled.getValue(), + visaSRCKey: config.visaSRCKey || customPreferences.ClicktoPay.Preferences.ClicktoPayKey.getValue(), + VisaSRCProduction: config.VisaSRCProduction || customPreferences.ClicktoPay.Preferences.ClicktoPayProduction.getValue() }; } module.exports = getConfig(); diff --git a/cartridges/int_cybs_sfra_base/cartridge/configuration/preferences/customPreferences.js b/cartridges/int_cybs_sfra_base/cartridge/configuration/preferences/customPreferences.js index 48b4b85..cc15a53 100644 --- a/cartridges/int_cybs_sfra_base/cartridge/configuration/preferences/customPreferences.js +++ b/cartridges/int_cybs_sfra_base/cartridge/configuration/preferences/customPreferences.js @@ -590,12 +590,12 @@ module.exports = { } }, - VisaSRC: { - id: 'Cybersource_VisaSRC', + ClicktoPay: { + id: 'Cybersource_ClicktoPay', display_name: '', Preferences: { - VisaSRCProduction: { - id: 'Cybersource_VisaSRCProduction', + ClicktoPayProduction: { + id: 'Cybersource_ClicktoPayProduction', display_name: 'True for production', description: '', type: Types.boolean, @@ -604,9 +604,9 @@ module.exports = { mandatory: false } }, - VisaSRCEnabled: { - id: 'Cybersource_VisaSRCEnabled', - display_name: 'Enable Visa SRC', + ClicktoPayEnabled: { + id: 'Cybersource_ClicktoPayEnabled', + display_name: 'Enable Click to Pay', description: '', type: Types.boolean, default: false, @@ -614,9 +614,9 @@ module.exports = { mandatory: false } }, - VisaSRCKey: { - id: 'Cybersource_VisaSRCKey', - display_name: 'Visa SRC Key', + ClicktoPayKey: { + id: 'Cybersource_ClicktoPayKey', + display_name: 'Click to Pay Key', description: '', type: Types.string, default: false, diff --git a/cartridges/int_cybs_sfra_base/cartridge/controllers/COPlaceOrder.js b/cartridges/int_cybs_sfra_base/cartridge/controllers/COPlaceOrder.js index fea4676..98aa847 100644 --- a/cartridges/int_cybs_sfra_base/cartridge/controllers/COPlaceOrder.js +++ b/cartridges/int_cybs_sfra_base/cartridge/controllers/COPlaceOrder.js @@ -9,6 +9,7 @@ var checkoutHelper = require('*/cartridge/scripts/checkout/checkoutHelpers'); var OrderModel = require('*/cartridge/models/order'); var hooksHelper = require('*/cartridge/scripts/helpers/hooks'); var configObject = require('../configuration/index'); +var csrfProtection = require('*/cartridge/scripts/middleware/csrf'); if (configObject.cartridgeEnabled) { server.post('Submit', function (req, res, next) { @@ -64,4 +65,14 @@ if (configObject.cartridgeEnabled) { }); } +server.get('SubmitOrderConformation', csrfProtection.generateToken, function (req, res, next) { + var orderId = req.querystring.ID; + var token = req.querystring.token; + res.render('cart/RedirectToConformation', { + orderId: orderId, + orderToken: token + }); + return next(); +}); + module.exports = server.exports(); diff --git a/cartridges/int_cybs_sfra_base/cartridge/controllers/CheckoutServices.js b/cartridges/int_cybs_sfra_base/cartridge/controllers/CheckoutServices.js index 109589f..10ee1b9 100644 --- a/cartridges/int_cybs_sfra_base/cartridge/controllers/CheckoutServices.js +++ b/cartridges/int_cybs_sfra_base/cartridge/controllers/CheckoutServices.js @@ -10,7 +10,7 @@ var configObject = require('~/cartridge/configuration/index'); server.extend(page); var currentBasket = BasketMgr.getCurrentBasket(); var paymentMethod = currentBasket && currentBasket.paymentInstrument && currentBasket.paymentInstrument.paymentMethod; -var isVisaSRC = paymentMethod && paymentMethod === 'VISA_SRC'; +var isVisaSRC = paymentMethod && paymentMethod === 'CLICK_TO_PAY'; // eslint-disable-next-line no-undef if (configObject.payerAuthenticationEnabled && configObject.cartridgeEnabled && empty(session.privacy.encryptedDataGP) && !isVisaSRC @@ -210,7 +210,15 @@ server.append('PlaceOrder', server.middleware.https, function (req, res, next) { }); // eslint-disable-next-line no-undef delete session.privacy.AuthorizeErrors; + }else { + res.json({ + error: false, + ID: session.privacy.orderID, + token: session.privacy.orderToken, + continueUrl: URLUtils.url('COPlaceOrder-SubmitOrderConformation').toString() + }); } + return next(); }); /** @@ -267,7 +275,7 @@ server.post('getResponse', server.middleware.https, function (req, res, next) { try { // eslint-disable-next-line block-scoped-var, no-undef - var enrollResponse = payerAuthentication.paEnroll(billingForm, shippingAddress, session.privacy.orderID, totalAmount, currencyCode, referenceId, card, lineItems, order.customer.registered); + var enrollResponse = payerAuthentication.paEnroll(billingForm, shippingAddress, session.privacy.orderID, totalAmount, currencyCode, referenceId, card, lineItems, order); if (enrollResponse.status === 'PENDING_AUTHENTICATION' && enrollResponse.errorInformation.reason === 'CONSUMER_AUTHENTICATION_REQUIRED') { if (enrollResponse.consumerAuthenticationInformation.acsUrl && enrollResponse.consumerAuthenticationInformation.stepUpUrl @@ -321,7 +329,7 @@ server.post('getResponse', server.middleware.https, function (req, res, next) { errorMessage: Resource.msg('message.payerAuthError', 'error', null), orderID: order.orderNo, orderToken: order.orderToken, - continueUrl: URLUtils.url('Order-Confirm').toString() + continueUrl: URLUtils.url('COPlaceOrder-SubmitOrderConformation').toString() }); } catch (e) { if (!order) { @@ -350,6 +358,7 @@ server.post('handlingConsumerAuthResponse', server.middleware.https, function (r var OrderMgr = require('dw/order/OrderMgr'); var Resource = require('dw/web/Resource'); var redirect; + var scaEnabled = dw.system.Site.getCurrent().getCustomPreferenceValue('Cybersource_IsSCAEnabled'); var billingForm = server.forms.getForm('billing'); var order = getOrder(); @@ -368,8 +377,9 @@ server.post('handlingConsumerAuthResponse', server.middleware.https, function (r } var mapper = require('~/cartridge/scripts/util/mapper.js'); var lineItems = mapper.MapOrderLineItems(order.allLineItems, true); + session.custom.SCA = true; // eslint-disable-next-line no-undef, block-scoped-var - var authenticateResponse = payerAuthentication.paConsumerAuthenticate(billingForm, session.privacy.orderID, totalAmount, currencyCode, session.privacy.transactionId, card, lineItems); + var authenticateResponse = payerAuthentication.paConsumerAuthenticate(billingForm, session.privacy.orderID, totalAmount, currencyCode, session.privacy.transactionId, card, lineItems, order); if (authenticateResponse.status === 'AUTHORIZED' || authenticateResponse.status === 'AUTHORIZED_PENDING_REVIEW') { var fraudDetectionStatus = hooksHelper('app.fraud.detection', 'fraudDetection', currentBasket, require('*/cartridge/scripts/hooks/fraudDetection').fraudDetection); @@ -384,6 +394,15 @@ server.post('handlingConsumerAuthResponse', server.middleware.https, function (r } // Sending Email Confirmation sendConfirmationEmail(); + } + // eslint-disable-next-line + else if(authenticateResponse.status === '201' && scaEnabled === true){ + session.custom.SCA = false; + var response = payerAuthentication.paConsumerAuthenticate(billingForm, session.privacy.orderID, totalAmount, currencyCode, session.privacy.transactionId, card, lineItems, order); + redirect = true; + Transaction.wrap(function () { + OrderMgr.failOrder(order); + }); } else { redirect = true; Transaction.wrap(function () { @@ -395,7 +414,7 @@ server.post('handlingConsumerAuthResponse', server.middleware.https, function (r errorMessage: Resource.msg('message.payerAuthError', 'error', null) + ' ' + authenticateResponse.status, orderID: order.orderNo, orderToken: order.orderToken, - continueUrl: URLUtils.url('Order-Confirm').toString() + continueUrl: URLUtils.url('COPlaceOrder-SubmitOrderConformation').toString() }); // eslint-disable-next-line no-undef session.privacy.orderID = ''; @@ -486,7 +505,7 @@ server.post('SubmitPaymentGP', function (req, res, next) { }; viewData.email = { - value: paymentForm.contactInfoFields.email.value + value: cart.customerEmail }; viewData.phone = { diff --git a/cartridges/int_cybs_sfra_base/cartridge/scripts/hooks/payment/processor/applePay.js b/cartridges/int_cybs_sfra_base/cartridge/scripts/hooks/payment/processor/applePay.js index ae242cb..3d5c1c8 100644 --- a/cartridges/int_cybs_sfra_base/cartridge/scripts/hooks/payment/processor/applePay.js +++ b/cartridges/int_cybs_sfra_base/cartridge/scripts/hooks/payment/processor/applePay.js @@ -23,7 +23,11 @@ exports.authorizeOrderPayment = function (order, response) { var base64Encoded = Encoding.toBase64(byteData); var mapper = require('~/cartridge/scripts/util/mapper.js'); var configObject = require('~/cartridge/configuration/index'); + var enableCaptureForApplePay = false; + if (dw.system.Site.getCurrent().getCustomPreferenceValue('Cybersource_ApplePayTransactionType').value === 'sale' ){ + enableCaptureForApplePay = true; + } var restRequest = { clientReferenceInformation: { code: order.currentOrderNo, @@ -33,7 +37,8 @@ exports.authorizeOrderPayment = function (order, response) { } }, processingInformation: { - paymentSolution: '001' + paymentSolution: '001', + capture: enableCaptureForApplePay }, paymentInformation: { fluidData: { diff --git a/cartridges/int_cybs_sfra_base/cartridge/scripts/hooks/payment/processor/visa_checkout.js b/cartridges/int_cybs_sfra_base/cartridge/scripts/hooks/payment/processor/visa_checkout.js index bde6d5d..086b176 100644 --- a/cartridges/int_cybs_sfra_base/cartridge/scripts/hooks/payment/processor/visa_checkout.js +++ b/cartridges/int_cybs_sfra_base/cartridge/scripts/hooks/payment/processor/visa_checkout.js @@ -23,7 +23,7 @@ function Handle(basket, paymentInformation) { currentBasket.removeAllPaymentInstruments(); var paymentInstruments = currentBasket.getPaymentInstruments( - 'VISA_SRC' + 'CLICK_TO_PAY' ); collections.forEach(paymentInstruments, function (item) { @@ -31,7 +31,7 @@ function Handle(basket, paymentInformation) { }); var paymentInstrument = currentBasket.createPaymentInstrument( - 'VISA_SRC', currentBasket.totalGrossPrice + 'CLICK_TO_PAY', currentBasket.totalGrossPrice ); paymentInstrument.setCreditCardHolder(currentBasket.billingAddress.fullName); diff --git a/cartridges/int_cybs_sfra_base/cartridge/scripts/http/payerAuthentication.js b/cartridges/int_cybs_sfra_base/cartridge/scripts/http/payerAuthentication.js index bc9b2c4..3a105f2 100644 --- a/cartridges/int_cybs_sfra_base/cartridge/scripts/http/payerAuthentication.js +++ b/cartridges/int_cybs_sfra_base/cartridge/scripts/http/payerAuthentication.js @@ -48,7 +48,7 @@ function setPaymentProcessorDetails(result) { * @param {*} lineItems * * @returns {*} * */ -function paEnroll(billingDetails, shippingAddress, referenceInformationCode, total, currency, referenceId, cardData, lineItems) { +function paEnroll(billingDetails, shippingAddress, referenceInformationCode, total, currency, referenceId, cardData, lineItems, order) { var instance = new cybersourceRestApi.PaymentsApi(configObject); var clientReferenceInformation = new cybersourceRestApi.Ptsv2paymentsClientReferenceInformation(); @@ -59,6 +59,11 @@ function paEnroll(billingDetails, shippingAddress, referenceInformationCode, tot processingInformation.actionList = []; processingInformation.actionList.push('CONSUMER_AUTHENTICATION'); + //Capture service call if Payer Authentication is enabled + if (dw.system.Site.getCurrent().getCustomPreferenceValue('Cybersource_CardTransactionType').value === 'sale' ) { + processingInformation.capture = true; + } + if (!configObject.fmeDmEnabled) { processingInformation.actionList.push('DECISION_SKIP'); } @@ -72,7 +77,7 @@ function paEnroll(billingDetails, shippingAddress, referenceInformationCode, tot amountDetails.currency = currency; var billTo = new cybersourceRestApi.Ptsv2paymentsOrderInformationBillTo(); - billTo.email = billingDetails.contactInfoFields.email.htmlValue; + billTo.email = order.getCustomerEmail(); billTo.country = billingDetails.addressFields.country.htmlValue; billTo.firstName = billingDetails.addressFields.firstName.htmlValue; billTo.lastName = billingDetails.addressFields.lastName.htmlValue; @@ -83,7 +88,7 @@ function paEnroll(billingDetails, shippingAddress, referenceInformationCode, tot billTo.locality = billingDetails.addressFields.city.htmlValue; var shipTo = new cybersourceRestApi.Ptsv2paymentsOrderInformationShipTo(); - shipTo.email = billingDetails.contactInfoFields.email.htmlValue; + shipTo.email = order.getCustomerEmail(); shipTo.country = shippingAddress.countryCode.toString().toUpperCase(); shipTo.firstName = shippingAddress.firstName; shipTo.lastName = shippingAddress.lastName; @@ -181,7 +186,7 @@ function paEnroll(billingDetails, shippingAddress, referenceInformationCode, tot * @param {*} lineItems * * @returns {*} * */ -function paConsumerAuthenticate(billingDetails, referenceInformationCode, total, currency, transactionId, cardData, lineItems) { +function paConsumerAuthenticate(billingDetails, referenceInformationCode, total, currency, transactionId, cardData, lineItems, order) { var instance = new cybersourceRestApi.PaymentsApi(configObject); var clientReferenceInformation = new cybersourceRestApi.Ptsv2paymentsClientReferenceInformation(); @@ -192,6 +197,11 @@ function paConsumerAuthenticate(billingDetails, referenceInformationCode, total, processingInformation.actionList = []; processingInformation.actionList.push('VALIDATE_CONSUMER_AUTHENTICATION'); + //Capture service call if Payer Authentication is enabled + if (configObject.enableCapture === true) { + processingInformation.capture = true; + } + if (!configObject.fmeDmEnabled) { processingInformation.actionList.push('DECISION_SKIP'); } @@ -201,7 +211,7 @@ function paConsumerAuthenticate(billingDetails, referenceInformationCode, total, amountDetails.currency = currency; var billTo = new cybersourceRestApi.Ptsv2paymentsOrderInformationBillTo(); - billTo.email = billingDetails.contactInfoFields.email.htmlValue; + billTo.email = order.getCustomerEmail(); billTo.country = billingDetails.addressFields.country.htmlValue; billTo.firstName = billingDetails.addressFields.firstName.htmlValue; billTo.lastName = billingDetails.addressFields.lastName.htmlValue; @@ -221,16 +231,16 @@ function paConsumerAuthenticate(billingDetails, referenceInformationCode, total, var paymentInformation = new cybersourceRestApi.Ptsv2paymentsPaymentInformation(); var request = new cybersourceRestApi.CreatePaymentRequest(); - - Cipher = new Cipher(); - // eslint-disable-next-line no-undef - var encryptedSessionID = Cipher.encrypt(session.sessionID, session.privacy.key, 'AES/CBC/PKCS5Padding', session.privacy.iv, 0); - - var deviceSessionId = new cybersourceRestApi.Ptsv2paymentsDeviceInformation(); - deviceSessionId.fingerprintSessionId = encryptedSessionID; - - if (configObject.deviceFingerprintEnabled) { - request.deviceInformation = deviceSessionId; + if (session.custom.SCA === true) { + Cipher = new Cipher(); + // eslint-disable-next-line no-undef + var encryptedSessionID = Cipher.encrypt(session.sessionID, session.privacy.key, 'AES/CBC/PKCS5Padding', session.privacy.iv, 0); + var deviceSessionId = new cybersourceRestApi.Ptsv2paymentsDeviceInformation(); + deviceSessionId.fingerprintSessionId = encryptedSessionID; + + if (configObject.deviceFingerprintEnabled) { + request.deviceInformation = deviceSessionId; + } } if (cardData.token != null) { @@ -269,7 +279,9 @@ function paConsumerAuthenticate(billingDetails, referenceInformationCode, total, request.paymentInformation = paymentInformation; request.consumerAuthenticationInformation = consumerAuthenticationInformation; - + if (session.custom.SCA === false) { + request.consumerAuthenticationInformation.challendeCode = '04'; + } var result = ''; instance.createPayment(request, function (data, error, response) { // eslint-disable-line no-unused-vars if (!error) { diff --git a/cartridges/int_cybs_sfra_base/cartridge/scripts/http/payments.js b/cartridges/int_cybs_sfra_base/cartridge/scripts/http/payments.js index a238e9d..0b00f43 100644 --- a/cartridges/int_cybs_sfra_base/cartridge/scripts/http/payments.js +++ b/cartridges/int_cybs_sfra_base/cartridge/scripts/http/payments.js @@ -94,8 +94,12 @@ function httpAuthorizeWithToken(cardData, customerEmail, referenceInformationCod request.deviceInformation = deviceSessionId; } - if (configObject.enableCapture === true) { - request.processingInformation.capture = true; + var OrderMgr = require('dw/order/OrderMgr'); + var order = OrderMgr.getOrder(referenceInformationCode); + if (order.paymentInstruments[0].paymentMethod === 'DW_GOOGLE_PAY') { + if (dw.system.Site.getCurrent().getCustomPreferenceValue('Cybersource_GooglePayTransactionType').value === 'sale' ){ + request.processingInformation.capture = true; + } } if (cardData.token) { // Token created in handle function (subscription ON or save CC) @@ -608,7 +612,7 @@ function httpAuthorizeWithVisaSrc(encPaymentData, callID, customerEmail, referen requestBody.deviceInformation = deviceSessionId; } - if (configObject.enableCapture === true) { + if (dw.system.Site.getCurrent().getCustomPreferenceValue('Cybersource_ClicktoPayTransactionType').value === 'sale' ) { requestBody.processingInformation.capture = true; } diff --git a/documentation/Storefront Reference Architecture Quick Launch Cartridge.pdf b/documentation/Storefront Reference Architecture Quick Launch Cartridge.pdf index fb4dcec..3c1cbf9 100644 Binary files a/documentation/Storefront Reference Architecture Quick Launch Cartridge.pdf and b/documentation/Storefront Reference Architecture Quick Launch Cartridge.pdf differ diff --git a/documentation/markdown/Configure-cartridge.md b/documentation/markdown/Configure-cartridge.md index 7af2c48..f281bee 100644 --- a/documentation/markdown/Configure-cartridge.md +++ b/documentation/markdown/Configure-cartridge.md @@ -41,6 +41,7 @@ Cybersource MerchantID | Cybersource Merchant ID Cybersource REST KeyId | Cybersource REST Key ID Cybersource REST Secret Key | Cybersource REST Secret Key Developer ID | Unique identifier generated by Cybersource for System Integrator +Credit/Debit card transaction Type | Select Sale/Auth transaction type #### Services (Required) diff --git a/documentation/markdown/Configure-features.md b/documentation/markdown/Configure-features.md index df04eb3..b064e45 100644 --- a/documentation/markdown/Configure-features.md +++ b/documentation/markdown/Configure-features.md @@ -9,7 +9,7 @@ Step 2: Go to **Merchant Tools > Custom Preferences > Cybersource_Tokenization** Field Name | Description ------------ | ------------- -Enable Tokenization Services | Enable or Disable the Tokenization Service saving Credit Card on "My Account" page +Enable Tokenization Services | Enable or Disable the Tokenization Service saving Credit/Debit Card on "My Account" page Enable limiting Saved Card | Enable or Disable limiting Saved Card on My Account page Saved Card Allowed | Number of Cards that can be added in a defined interval on My Account page Reset Interval (in Hours) | Number of hours that saved card attempts are counted diff --git a/documentation/markdown/Configure-payment-method.md b/documentation/markdown/Configure-payment-method.md index 5497c31..a397f29 100644 --- a/documentation/markdown/Configure-payment-method.md +++ b/documentation/markdown/Configure-payment-method.md @@ -154,6 +154,20 @@ Step 1: Upload Cybersource metadata in Business Manager. If not follow "Step 2: 1. In the Business Manager, go to **Merchant Tools > Ordering > Payment Methods** and select **DW_APPLE_PAY**. And in **DW_APPLE_PAY details**, double check if **Payment Processor** = **"PAYMENTS_CREDIT"** --- + + #### Site Preferences: + Step 1: Upload Cybersource metadata in Business Manager. If not follow "Step 2: Upload metadata" or import **"metadata/sfra_meta/meta/ApplePay.xml"** in Business Manager (**Administration > Site Development > Import & Export**) + + Step 3: Go to **Merchant Tools > Custom Preferences > Apple Pay** + and set values for the following parameters: + + Field | Description + ------------ | ------------- + ApplePayTransactionType | Select Sale/Auth transaction type + + +---- + #### 3. Google Pay #### Step 1: Create custom preferences for google pay 1. Upload Cybersource metadata in Business Manager. If not follow “Step 2: Upload metadata” or import **metadata/payment_metadata/meta/GooglePay.xml** in Business Manager **(Administration > Site Development > Import & Export)** diff --git a/documentation/markdown/Release-notes.md b/documentation/markdown/Release-notes.md index 02cad00..12e11de 100644 --- a/documentation/markdown/Release-notes.md +++ b/documentation/markdown/Release-notes.md @@ -1,5 +1,15 @@ ## Release Notes +**Version 24.1.0 (February 2023)** + +**New Features** +• Upgrade the cartridge to support SFRA v6.3. +• Updated cartridge to make it compatible with Salesforce B2C Commerce Release 22.7 . +• Added Strong Customer Authentication for Credit Card. +• Implemented Sale functionality for Credit Card, Google Pay, Visa SRC and Apple Pay. +• Updated API header in Http Signature Authentication. + + **Version 21.1.0 (July 2021)** **New Features** diff --git a/metadata/payments_metadata/meta/ApplePay.xml b/metadata/payments_metadata/meta/ApplePay.xml new file mode 100644 index 0000000..09c94c7 --- /dev/null +++ b/metadata/payments_metadata/meta/ApplePay.xml @@ -0,0 +1,29 @@ + + + + + + Apple Pay Transaction Type + enum-of-string + true + false + + + Auth + auth + + + Sale + sale + + + + + + + Apple Pay Configuration + + + + + \ No newline at end of file diff --git a/metadata/payments_metadata/meta/Core.xml b/metadata/payments_metadata/meta/Core.xml index 07cb427..409448a 100644 --- a/metadata/payments_metadata/meta/Core.xml +++ b/metadata/payments_metadata/meta/Core.xml @@ -33,6 +33,22 @@ string false + + Credit/Debit Card Transaction Type + enum-of-string + true + false + + + Auth + auth + + + Sale + sale + + + @@ -42,6 +58,7 @@ + diff --git a/metadata/payments_metadata/meta/GooglePay.xml b/metadata/payments_metadata/meta/GooglePay.xml index 830dfcc..6493975 100644 --- a/metadata/payments_metadata/meta/GooglePay.xml +++ b/metadata/payments_metadata/meta/GooglePay.xml @@ -9,6 +9,22 @@ false false + + Google Pay Transaction Type + enum-of-string + true + false + + + Auth + auth + + + Sale + sale + + + Enable Google Pay On Mini Cart Enable/Disable google pay on mini cart @@ -50,6 +66,7 @@ + diff --git a/metadata/payments_metadata/meta/PayerAuthentication.xml b/metadata/payments_metadata/meta/PayerAuthentication.xml index cdbcc92..fa44337 100644 --- a/metadata/payments_metadata/meta/PayerAuthentication.xml +++ b/metadata/payments_metadata/meta/PayerAuthentication.xml @@ -43,6 +43,13 @@ + + Enable SCA + Enable or Disable Strong Customer Authentication + boolean + false + false + @@ -52,6 +59,7 @@ + diff --git a/metadata/payments_metadata/meta/Tokenization.xml b/metadata/payments_metadata/meta/Tokenization.xml index 3b51578..9871f37 100644 --- a/metadata/payments_metadata/meta/Tokenization.xml +++ b/metadata/payments_metadata/meta/Tokenization.xml @@ -4,7 +4,7 @@ Enable Tokenization Services - Enable or Disable the Tokenization Service saving Credit Card on My Account page + Enable or Disable the Tokenization Service saving Credit/Debit Card on My Account page boolean false true diff --git a/metadata/payments_metadata/meta/VisaSRC.xml b/metadata/payments_metadata/meta/VisaSRC.xml index c5b7840..7825336 100644 --- a/metadata/payments_metadata/meta/VisaSRC.xml +++ b/metadata/payments_metadata/meta/VisaSRC.xml @@ -2,21 +2,37 @@ - - Enable Visa SRC - Enable/Disable Enable Visa SRC on checkout page + + Enable Click to Pay + Enable/Disable Enable Click to Pay on checkout page boolean false false - - Visa SRC Key - Visa SRC Key Id obtained through EBC Digital payments + + Click to Pay Transaction Type + enum-of-string + true + false + + + Auth + auth + + + Sale + sale + + + + + Click to Pay Key + Click to Pay Key Id obtained through EBC Digital payments string false false - + True for production Set to Yes for Production boolean @@ -25,11 +41,12 @@ - + - - - + + + + diff --git a/metadata/payments_metadata/meta/merged.xml b/metadata/payments_metadata/meta/merged.xml index bbae84a..b74ae71 100644 --- a/metadata/payments_metadata/meta/merged.xml +++ b/metadata/payments_metadata/meta/merged.xml @@ -33,6 +33,22 @@ string false + + Credit/Debit Card Transaction Type + enum-of-string + true + false + + + Auth + auth + + + Sale + sale + + + Enable Delivery Address Verification Services Enable or Disable Delivery Address Verification for Cybersource Cartridge @@ -161,7 +177,7 @@ Enable Tokenization Services - Enable or Disable the Tokenization Service saving Credit Card on My Account page + Enable or Disable the Tokenization Service saving Credit/Debit Card on My Account page boolean false true @@ -302,22 +318,22 @@ string false - + True for production boolean false false - - Enable Visa SRC + + Enable Click to pay boolean false false - - Visa SRC Key + + Click to Pay Key string false @@ -332,6 +348,7 @@ + Delivery Address Verification Configuration @@ -396,11 +413,11 @@ - + - - - + + + diff --git a/metadata/payments_metadata/sites/yourSiteID/payment-methods.xml b/metadata/payments_metadata/sites/yourSiteID/payment-methods.xml index d3be082..1197074 100644 --- a/metadata/payments_metadata/sites/yourSiteID/payment-methods.xml +++ b/metadata/payments_metadata/sites/yourSiteID/payment-methods.xml @@ -1,7 +1,7 @@ - - Visa SRC + + Click to Pay false PAYMENTS_VISA_SRC diff --git a/test/mocks/CybersourceConstants.js b/test/mocks/CybersourceConstants.js index e429f5b..d65a0b1 100644 --- a/test/mocks/CybersourceConstants.js +++ b/test/mocks/CybersourceConstants.js @@ -9,7 +9,7 @@ CybersourceConstants.METHOD_PAYPAL_CREDIT = 'PAYPAL_CREDIT'; CybersourceConstants.METHOD_SA_REDIRECT = 'SA_REDIRECT'; CybersourceConstants.METHOD_SA_IFRAME = 'SA_IFRAME'; CybersourceConstants.METHOD_SA_SILENTPOST = 'SA_SILENTPOST'; -CybersourceConstants.METHOD_VISA_SRC = 'VISA_SRC'; +CybersourceConstants.METHOD_VISA_SRC = 'CLICK_TO_PAY'; CybersourceConstants.METHOD_ApplePay = 'DW_APPLE_PAY'; CybersourceConstants.METHOD_AndroidPay = 'DW_ANDROID_PAY'; CybersourceConstants.METHOD_Ideal_BankTransfer = 'IDEAL';