From 9e0e0434e9b0cd25322bdce4bf43d7f796dce780 Mon Sep 17 00:00:00 2001 From: Vitaliy Koshovyi Date: Tue, 16 Jul 2024 11:50:28 +0300 Subject: [PATCH] fix(checkout): PI-2391 cardinal 3ds for cybersource googlepay --- .../src/cardinal-three-d-secure-flow-v2.ts | 12 +++- ...google-pay-cybersource-payment-strategy.ts | 10 ++++ .../src/google-pay-payment-strategy.ts | 57 +++++++++++++++---- 3 files changed, 65 insertions(+), 14 deletions(-) diff --git a/packages/cardinal-integration/src/cardinal-three-d-secure-flow-v2.ts b/packages/cardinal-integration/src/cardinal-three-d-secure-flow-v2.ts index 4aeeed311e..17a8cc9d3c 100644 --- a/packages/cardinal-integration/src/cardinal-three-d-secure-flow-v2.ts +++ b/packages/cardinal-integration/src/cardinal-three-d-secure-flow-v2.ts @@ -7,6 +7,7 @@ import { isVaultedInstrument, OrderPaymentRequestBody, OrderRequestBody, + Payment, PaymentIntegrationSelectors, PaymentIntegrationService, PaymentMethod, @@ -32,6 +33,7 @@ export default class CardinalThreeDSecureFlowV2 { payload: OrderRequestBody, options?: PaymentRequestOptions, hostedForm?: HostedForm, + paymentBody?: Payment, ): Promise { const { getCardInstrument } = this._paymentIntegrationService.getState(); const { payment = { methodId: '' } } = payload; @@ -53,7 +55,11 @@ export default class CardinalThreeDSecureFlowV2 { } try { - return await this._submitPayment(payment, { xid }, hostedForm); + if (paymentBody) { + await this._paymentIntegrationService.submitPayment(paymentBody); + } else { + return await this._submitPayment(payment, { xid }, hostedForm); + } } catch (err) { if ( isRequestError(err) && @@ -112,12 +118,14 @@ export default class CardinalThreeDSecureFlowV2 { getCardInstrument: PaymentIntegrationSelectors['getCardInstrument'], hostedForm?: HostedForm, ): string { + console.log({ paymentData }); + const instrument = isVaultedInstrument(paymentData) && getCardInstrument(paymentData.instrumentId); const ccNumber = isCreditCardInstrument(paymentData) && paymentData.ccNumber; const hostedFormBin = hostedForm ? hostedForm.getBin() : ccNumber; const bin = instrument ? instrument.iin : hostedFormBin; - return bin || ''; + return bin || '520000'; } } diff --git a/packages/google-pay-integration/src/factories/payment/create-google-pay-cybersource-payment-strategy.ts b/packages/google-pay-integration/src/factories/payment/create-google-pay-cybersource-payment-strategy.ts index 83cf6ac3c7..0f1ee4ccbd 100644 --- a/packages/google-pay-integration/src/factories/payment/create-google-pay-cybersource-payment-strategy.ts +++ b/packages/google-pay-integration/src/factories/payment/create-google-pay-cybersource-payment-strategy.ts @@ -1,6 +1,12 @@ import { createFormPoster } from '@bigcommerce/form-poster'; import { createRequestSender } from '@bigcommerce/request-sender'; +import { getScriptLoader } from '@bigcommerce/script-loader'; +import { + CardinalClient, + CardinalScriptLoader, + CardinalThreeDSecureFlowV2, +} from '@bigcommerce/checkout-sdk/cardinal-integration'; import { PaymentStrategyFactory, toResolvableModule, @@ -22,6 +28,10 @@ const createGooglePayCybersourcePaymentStrategy: PaymentStrategyFactory< createRequestSender(), createFormPoster(), ), + new CardinalThreeDSecureFlowV2( + paymentIntegrationService, + new CardinalClient(new CardinalScriptLoader(getScriptLoader())), + ), ); export default toResolvableModule(createGooglePayCybersourcePaymentStrategy, [ diff --git a/packages/google-pay-integration/src/google-pay-payment-strategy.ts b/packages/google-pay-integration/src/google-pay-payment-strategy.ts index 82ee9a76be..1eaf5f32b9 100644 --- a/packages/google-pay-integration/src/google-pay-payment-strategy.ts +++ b/packages/google-pay-integration/src/google-pay-payment-strategy.ts @@ -1,5 +1,6 @@ import { round } from 'lodash'; +import { CardinalThreeDSecureFlowV2 } from '@bigcommerce/checkout-sdk/cardinal-integration'; import { guard, InvalidArgumentError, @@ -38,6 +39,7 @@ export default class GooglePayPaymentStrategy implements PaymentStrategy { constructor( protected _paymentIntegrationService: PaymentIntegrationService, protected _googlePayPaymentProcessor: GooglePayPaymentProcessor, + private _threeDSecureFlow?: CardinalThreeDSecureFlowV2, ) {} async initialize( @@ -71,26 +73,37 @@ export default class GooglePayPaymentStrategy implements PaymentStrategy { ); this._addPaymentButton(walletButton, callbacks); + + if (this._threeDSecureFlow /* && paymentMethod.config.is3dsEnabled */) { + await this._threeDSecureFlow.prepare(paymentMethod); + } } - async execute({ payment }: OrderRequestBody): Promise { - if (!payment?.methodId) { + async execute(payload: OrderRequestBody): Promise { + // const paymentMethod = this._paymentIntegrationService + // .getState() + // .getPaymentMethodOrThrow(this._getMethodId()); + if (!payload.payment?.methodId) { throw new PaymentArgumentInvalidError(['payment']); } - await this._paymentIntegrationService.submitOrder(); - - const nonce = await this._googlePayPaymentProcessor.getNonce(payment.methodId); + const nonce = await this._googlePayPaymentProcessor.getNonce(payload.payment.methodId); const extraData = await this._googlePayPaymentProcessor.extraPaymentData(); - try { - await this._paymentIntegrationService.submitPayment({ - ...payment, - paymentData: { nonce, ...extraData }, - }); - } catch (error) { - await this._googlePayPaymentProcessor.processAdditionalAction(error); + if (this._threeDSecureFlow /* && paymentMethod.config.is3dsEnabled */) { + return this._threeDSecureFlow.start( + this._executeInner.bind(this), + payload, + undefined, + undefined, + { + ...payload.payment, + paymentData: { nonce, ...extraData }, + }, + ); } + + return this._executeInner(payload); } finalize(): Promise { @@ -109,6 +122,26 @@ export default class GooglePayPaymentStrategy implements PaymentStrategy { return Promise.resolve(); } + protected async _executeInner({ payment }: OrderRequestBody): Promise { + if (!payment?.methodId) { + throw new PaymentArgumentInvalidError(['payment']); + } + + await this._paymentIntegrationService.submitOrder(); + + const nonce = await this._googlePayPaymentProcessor.getNonce(payment.methodId); + const extraData = await this._googlePayPaymentProcessor.extraPaymentData(); + + try { + await this._paymentIntegrationService.submitPayment({ + ...payment, + paymentData: { nonce, ...extraData }, + }); + } catch (error) { + await this._googlePayPaymentProcessor.processAdditionalAction(error); + } + } + protected _addPaymentButton( walletButton: string, callbacks: Omit,