diff --git a/jest/sfccCartridgeMocks.js b/jest/sfccCartridgeMocks.js index 162b335f5..ad191a2a0 100644 --- a/jest/sfccCartridgeMocks.js +++ b/jest/sfccCartridgeMocks.js @@ -240,6 +240,7 @@ jest.mock('*/cartridge/adyen/utils/adyenHelper', () => ({ })), isAdyenGivingAvailable: jest.fn(() => true), isApplePay: jest.fn(() => true), + isPayPalExpress: jest.fn(() => false), getAdyenGivingConfig: jest.fn(() => true), getApplicationInfo: jest.fn(() => ({ externalPlatform: { version: 'SFRA' }, diff --git a/metadata/site_import/meta/system-objecttype-extensions.xml b/metadata/site_import/meta/system-objecttype-extensions.xml index 1705975a4..02ec72f76 100644 --- a/metadata/site_import/meta/system-objecttype-extensions.xml +++ b/metadata/site_import/meta/system-objecttype-extensions.xml @@ -44,6 +44,14 @@ false 0 + + Adyen PayPal Express Response + PayPal Express response used to render the confirmation form + text + false + false + 0 + @@ -53,6 +61,7 @@ + diff --git a/src/cartridges/app_adyen_SFRA/cartridge/client/default/js/paypalExpress.js b/src/cartridges/app_adyen_SFRA/cartridge/client/default/js/paypalExpress.js index 82c636f1a..ff37755af 100644 --- a/src/cartridges/app_adyen_SFRA/cartridge/client/default/js/paypalExpress.js +++ b/src/cartridges/app_adyen_SFRA/cartridge/client/default/js/paypalExpress.js @@ -19,8 +19,6 @@ function callPaymentFromComponent(data, component) { data: JSON.stringify(data), }, success(response) { - helpers.createShowConfirmationForm(window.showConfirmationAction); - helpers.setOrderFormData(response); handlePaypalResponse(response, component); }, }); @@ -43,6 +41,10 @@ function makeExpressPaymentDetailsCall(data) { data: JSON.stringify({ data }), contentType: 'application/json; charset=utf-8', async: false, + success(response) { + helpers.createShowConfirmationForm(window.showConfirmationAction); + helpers.setOrderFormData(response); + }, }); } @@ -79,6 +81,9 @@ async function mountPaypalComponent() { }, onAdditionalDetails: (state) => { makeExpressPaymentDetailsCall(state.data); + document.querySelector('#additionalDetailsHidden').value = + JSON.stringify(state.data); + document.querySelector('#showConfirmationForm').submit(); }, }; diff --git a/src/cartridges/int_adyen_SFRA/cartridge/adyen/scripts/expressPayments/paypal/makeExpressPaymentDetailsCall.js b/src/cartridges/int_adyen_SFRA/cartridge/adyen/scripts/expressPayments/paypal/makeExpressPaymentDetailsCall.js index 7495632e7..61e7ba209 100644 --- a/src/cartridges/int_adyen_SFRA/cartridge/adyen/scripts/expressPayments/paypal/makeExpressPaymentDetailsCall.js +++ b/src/cartridges/int_adyen_SFRA/cartridge/adyen/scripts/expressPayments/paypal/makeExpressPaymentDetailsCall.js @@ -2,7 +2,6 @@ const URLUtils = require('dw/web/URLUtils'); const OrderMgr = require('dw/order/OrderMgr'); const Transaction = require('dw/system/Transaction'); const BasketMgr = require('dw/order/BasketMgr'); -const AdyenHelper = require('*/cartridge/adyen/utils/adyenHelper'); const adyenCheckout = require('*/cartridge/adyen/scripts/payments/adyenCheckout'); const AdyenLogs = require('*/cartridge/adyen/logs/adyenCustomLogs'); const COHelpers = require('*/cartridge/scripts/checkout/checkoutHelpers'); @@ -60,25 +59,26 @@ function makeExpressPaymentDetailsCall(req, res, next) { const request = JSON.parse(req.body); const currentBasket = BasketMgr.getCurrentBasket(); - const paymentsDetailsResponse = adyenCheckout.doPaymentsDetailsCall( - request.data, - ); + const response = adyenCheckout.doPaymentsDetailsCall(request.data); setBillingAndShippingAddress(currentBasket); - const order = OrderMgr.createOrder(currentBasket); + const order = OrderMgr.createOrder( + currentBasket, + session.privacy.paypalExpressOrderNo, + ); const fraudDetectionStatus = { status: 'success' }; const placeOrderResult = COHelpers.placeOrder(order, fraudDetectionStatus); if (placeOrderResult.error) { AdyenLogs.error_log('Failed to place the PayPal express order'); } - const response = AdyenHelper.createAdyenCheckoutResponse( - paymentsDetailsResponse, - ); - response.orderNo = order.orderNo; response.orderToken = order.orderToken; - res.json(response); + // Storing the paypal express response to make use of show confirmation logic + Transaction.wrap(() => { + order.custom.Adyen_paypalExpressResponse = JSON.stringify(response); + }); + res.json({ orderNo: response.orderNo, orderToken: response.orderToken }); return next(); } catch (e) { AdyenLogs.error_log( diff --git a/src/cartridges/int_adyen_SFRA/cartridge/adyen/scripts/payments/adyenCheckout.js b/src/cartridges/int_adyen_SFRA/cartridge/adyen/scripts/payments/adyenCheckout.js index 35f862290..c90adca4f 100644 --- a/src/cartridges/int_adyen_SFRA/cartridge/adyen/scripts/payments/adyenCheckout.js +++ b/src/cartridges/int_adyen_SFRA/cartridge/adyen/scripts/payments/adyenCheckout.js @@ -155,9 +155,9 @@ function createPaymentRequest(args) { paymentRequest = AdyenHelper.add3DS2Data(paymentRequest); const paymentMethodType = paymentRequest.paymentMethod.type; - const isPayPalExpress = - paymentRequest.paymentMethod.type === 'paypal' && - paymentRequest.paymentMethod.subtype === 'express'; + const isPayPalExpress = AdyenHelper.isPayPalExpress( + paymentRequest.paymentMethod, + ); // Add Risk data if (AdyenConfigs.getAdyenBasketFieldsEnabled()) { diff --git a/src/cartridges/int_adyen_SFRA/cartridge/adyen/scripts/showConfirmation/handlePaymentFromComponent.js b/src/cartridges/int_adyen_SFRA/cartridge/adyen/scripts/showConfirmation/handlePaymentFromComponent.js index 30785110a..fbcc4d9dd 100644 --- a/src/cartridges/int_adyen_SFRA/cartridge/adyen/scripts/showConfirmation/handlePaymentFromComponent.js +++ b/src/cartridges/int_adyen_SFRA/cartridge/adyen/scripts/showConfirmation/handlePaymentFromComponent.js @@ -49,11 +49,14 @@ function handleAuthorisedPayment( ) { // custom fraudDetection const fraudDetectionStatus = { status: 'success' }; + const isPayPalExpress = order.custom.Adyen_paypalExpressResponse; - // Places the order - const placeOrderResult = COHelpers.placeOrder(order, fraudDetectionStatus); - if (placeOrderResult.error) { - return handlePaymentError(order, adyenPaymentInstrument, { res, next }); + // Places the order, for PayPal express the order is placed from makeExpressPaymentDetailsCall.js + if (!isPayPalExpress) { + const placeOrderResult = COHelpers.placeOrder(order, fraudDetectionStatus); + if (placeOrderResult.error) { + return handlePaymentError(order, adyenPaymentInstrument, { res, next }); + } } Transaction.wrap(() => { @@ -101,6 +104,7 @@ function handlePaymentResult(result, order, adyenPaymentInstrument, options) { Transaction.wrap(() => { order.custom.Adyen_pspReference = result.pspReference; order.custom.Adyen_eventCode = result.resultCode; + order.custom.Adyen_paypalExpressResponse = null; }); return handlePaymentError(order, adyenPaymentInstrument, options); } @@ -135,15 +139,25 @@ function handlePayment(stateData, order, options) { return handlePaymentError(order, adyenPaymentInstrument, options); } } - - const detailsCall = hasStateData - ? handlePaymentsDetailsCall(stateData, adyenPaymentInstrument) - : null; + const paymentData = JSON.parse( + adyenPaymentInstrument.custom.adyenPaymentData, + ); + const isPayPalExpress = AdyenHelper.isPayPalExpress( + paymentData.paymentMethod, + ); + const detailsCall = + hasStateData && !isPayPalExpress + ? handlePaymentsDetailsCall(stateData, adyenPaymentInstrument) + : null; + if (isPayPalExpress) { + finalResult = JSON.parse(order.custom.Adyen_paypalExpressResponse); + } else { + finalResult = finalResult || detailsCall?.result; + } Transaction.wrap(() => { adyenPaymentInstrument.custom.adyenPaymentData = null; }); - finalResult = finalResult || detailsCall?.result; return handlePaymentResult( finalResult, diff --git a/src/cartridges/int_adyen_SFRA/cartridge/adyen/utils/adyenHelper.js b/src/cartridges/int_adyen_SFRA/cartridge/adyen/utils/adyenHelper.js index 44a7e601b..5575ea4da 100644 --- a/src/cartridges/int_adyen_SFRA/cartridge/adyen/utils/adyenHelper.js +++ b/src/cartridges/int_adyen_SFRA/cartridge/adyen/utils/adyenHelper.js @@ -32,6 +32,7 @@ const collections = require('*/cartridge/scripts/util/collections'); const ShippingMgr = require('dw/order/ShippingMgr'); const ShippingMethodModel = require('*/cartridge/models/shipping/shippingMethod'); const PaymentInstrument = require('dw/order/PaymentInstrument'); +const OrderMgr = require('dw/order/OrderMgr'); const StringUtils = require('dw/util/StringUtils'); //script includes const AdyenLogs = require('*/cartridge/adyen/logs/adyenCustomLogs'); @@ -339,6 +340,13 @@ let adyenHelperObj = { return false; }, + isPayPalExpress(paymentMethod){ + if (paymentMethod.type === 'paypal' && paymentMethod.subtype === 'express'){ + return true; + } + return false; + }, + // Get stored card token of customer saved card based on matched cardUUID getCardToken(cardUUID, customer) { let token = ''; @@ -504,6 +512,13 @@ let adyenHelperObj = { orderToken = order.getOrderToken(); } + // creates order number to be utilized for PayPal express + if (adyenHelperObj.isPayPalExpress(stateData.paymentMethod)){ + const paypalExpressOrderNo = OrderMgr.createOrderNo(); + session.privacy.paypalExpressOrderNo = paypalExpressOrderNo; + reference = paypalExpressOrderNo; + } + let signature = ''; //Create signature to verify returnUrl if there is an order if (order && order.getUUID()) {