diff --git a/packages/offline-integration/src/offline-payment-strategy.spec.ts b/packages/offline-integration/src/offline-payment-strategy.spec.ts index d6b2900784..a8bcb1cfbe 100644 --- a/packages/offline-integration/src/offline-payment-strategy.spec.ts +++ b/packages/offline-integration/src/offline-payment-strategy.spec.ts @@ -45,6 +45,70 @@ describe('OfflinePaymentStrategy', () => { ); }); + it('includes only purchaseOrderNumber in paymentData when methodId is purchaseorder', async () => { + const payload = { + ...getOrderRequestBody(), + payment: { + methodId: 'purchaseorder', + paymentData: { + purchaseOrderNumber: '1111111', + shouldCreateAccount: true, + shouldSaveInstrument: false, + terms: false, + }, + }, + }; + + await strategy.execute(payload, undefined); + + expect(paymentIntegrationService.submitOrder).toHaveBeenCalledWith( + { + ...payload, + payment: { + methodId: 'purchaseorder', + paymentData: { + purchaseOrderNumber: '1111111', + }, + }, + }, + undefined, + ); + }); + + it('does not include paymentData when methodId is purchaseorder but paymentData is absent', async () => { + const payload = { + ...getOrderRequestBody(), + payment: { + methodId: 'purchaseorder', + }, + }; + + await strategy.execute(payload, undefined); + + expect(paymentIntegrationService.submitOrder).toHaveBeenCalledWith( + { + ...payload, + payment: { + methodId: 'purchaseorder', + }, + }, + undefined, + ); + }); + + it('does not include paymentData for non-purchaseorder offline methods', async () => { + await strategy.execute(getOrderRequestBody(), undefined); + + expect(paymentIntegrationService.submitOrder).toHaveBeenCalledWith( + expect.objectContaining({ + payment: { + methodId: 'authorizenet', + }, + }), + undefined, + ); + }); + it('passes the options to submitOrder', async () => { const options = { myOptions: 'option1', methodId: 'testgateway' }; diff --git a/packages/offline-integration/src/offline-payment-strategy.ts b/packages/offline-integration/src/offline-payment-strategy.ts index 6ac32e36cf..2586a436cc 100644 --- a/packages/offline-integration/src/offline-payment-strategy.ts +++ b/packages/offline-integration/src/offline-payment-strategy.ts @@ -1,4 +1,5 @@ import { + HostedInstrument, OrderFinalizationNotRequiredError, OrderRequestBody, PaymentIntegrationService, @@ -6,14 +7,41 @@ import { PaymentStrategy, } from '@bigcommerce/checkout-sdk/payment-integration-api'; +interface PurchaseOrderPaymentData extends HostedInstrument { + purchaseOrderNumber?: string; +} + +function isPurchaseOrderPaymentData(data: unknown): data is PurchaseOrderPaymentData { + return typeof data === 'object' && data !== null && 'purchaseOrderNumber' in data; +} + export default class OfflinePaymentStrategy implements PaymentStrategy { constructor(private _paymentIntegrationService: PaymentIntegrationService) {} async execute(payload: OrderRequestBody, options?: PaymentRequestOptions): Promise { + const { payment } = payload; + let purchaseOrderPaymentData: PurchaseOrderPaymentData | undefined; + + if ( + payment?.methodId === 'purchaseorder' && + isPurchaseOrderPaymentData(payment.paymentData) + ) { + purchaseOrderPaymentData = { + purchaseOrderNumber: payment.paymentData.purchaseOrderNumber, + }; + } + await this._paymentIntegrationService.submitOrder( { ...payload, - payment: payload.payment ? { methodId: payload.payment.methodId } : undefined, + payment: payment + ? { + methodId: payment.methodId, + ...(purchaseOrderPaymentData && { + paymentData: purchaseOrderPaymentData, + }), + } + : undefined, }, options, );