Skip to content

Commit 34e5089

Browse files
feat(payment): PAYPAL-5724 add bcp customer app switch
1 parent 3f3ebb7 commit 34e5089

File tree

4 files changed

+88
-6
lines changed

4 files changed

+88
-6
lines changed

packages/bigcommerce-payments-integration/src/bigcommerce-payments-types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ export interface BigCommercePaymentsInitializationData {
263263
shouldRenderFields?: boolean;
264264
shouldRunAcceleratedCheckout?: boolean;
265265
paymentButtonStyles?: Record<string, PayPalButtonStyleOptions>;
266+
isAppSwitchEnabled?: boolean;
266267
}
267268

268269
/**
@@ -357,6 +358,8 @@ export interface BigCommercePaymentsButtons {
357358
render(id: string): void;
358359
close(): void;
359360
isEligible(): boolean;
361+
hasReturned?(): boolean;
362+
resume?(): void;
360363
}
361364

362365
export interface BigCommercePaymentsButtonsOptions {

packages/bigcommerce-payments-integration/src/bigcommerce-payments/bigcommerce-payments-customer-strategy.spec.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,62 @@ describe('BigCommercePaymentsCustomerStrategy', () => {
333333
expect(bigCommercePaymentsSdkRenderMock).toHaveBeenCalled();
334334
});
335335

336+
it('render button with appSwitch flag', async () => {
337+
jest.spyOn(
338+
paymentIntegrationService.getState(),
339+
'getPaymentMethodOrThrow',
340+
).mockReturnValue({
341+
...paymentMethod,
342+
initializationData: {
343+
...paymentMethod.initializationData,
344+
isAppSwitchEnabled: true,
345+
},
346+
});
347+
348+
await strategy.initialize(initializationOptions);
349+
350+
expect(paypalSdk.Buttons).toHaveBeenCalledWith({
351+
appSwitchWhenAvailable: true,
352+
fundingSource: paypalSdk.FUNDING.PAYPAL,
353+
style: {
354+
height: DefaultCheckoutButtonHeight,
355+
color: StyleButtonColor.silver,
356+
label: 'checkout',
357+
},
358+
createOrder: expect.any(Function),
359+
onApprove: expect.any(Function),
360+
onClick: expect.any(Function),
361+
});
362+
});
363+
364+
it('calls resume when appSwitch enabled and returned from app', async () => {
365+
jest.spyOn(
366+
paymentIntegrationService.getState(),
367+
'getPaymentMethodOrThrow',
368+
).mockReturnValue({
369+
...paymentMethod,
370+
initializationData: {
371+
...paymentMethod.initializationData,
372+
isAppSwitchEnabled: true,
373+
},
374+
});
375+
376+
const resumeMock = jest.fn();
377+
const bigCommercePaymentsSdkRenderMock = jest.fn();
378+
379+
jest.spyOn(paypalSdk, 'Buttons').mockImplementation(() => ({
380+
close: jest.fn(),
381+
isEligible: jest.fn(() => true),
382+
render: bigCommercePaymentsSdkRenderMock,
383+
hasReturned: jest.fn(() => true),
384+
resume: resumeMock,
385+
}));
386+
387+
await strategy.initialize(initializationOptions);
388+
389+
expect(resumeMock).toHaveBeenCalled();
390+
});
391+
336392
it('does not render PayPal button if it is not eligible', async () => {
337393
const bigCommercePaymentsSdkRenderMock = jest.fn();
338394

packages/bigcommerce-payments-integration/src/bigcommerce-payments/bigcommerce-payments-customer-strategy.ts

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,14 @@ export default class BigCommercePaymentsCustomerStrategy implements CustomerStra
119119
const state = this.paymentIntegrationService.getState();
120120
const paymentMethod =
121121
state.getPaymentMethodOrThrow<BigCommercePaymentsInitializationData>(methodId);
122-
const { isHostedCheckoutEnabled, paymentButtonStyles } =
122+
const { isHostedCheckoutEnabled, paymentButtonStyles, isAppSwitchEnabled } =
123123
paymentMethod.initializationData || {};
124124
const { checkoutTopButtonStyles } = paymentButtonStyles || {};
125125

126126
const defaultCallbacks = {
127+
...(this.isPaypalCommerceAppSwitchEnabled(methodId) && {
128+
appSwitchWhenAvailable: true,
129+
}),
127130
createOrder: () =>
128131
this.bigCommercePaymentsIntegrationService.createOrder('bigcommerce_payments'),
129132
onApprove: ({ orderID }: ApproveCallbackPayload) =>
@@ -132,10 +135,12 @@ export default class BigCommercePaymentsCustomerStrategy implements CustomerStra
132135
};
133136

134137
const hostedCheckoutCallbacks = {
135-
onShippingAddressChange: (data: ShippingAddressChangeCallbackPayload) =>
136-
this.onShippingAddressChange(data),
137-
onShippingOptionsChange: (data: ShippingOptionChangeCallbackPayload) =>
138-
this.onShippingOptionsChange(data),
138+
...(!isAppSwitchEnabled && {
139+
onShippingAddressChange: (data: ShippingAddressChangeCallbackPayload) =>
140+
this.onShippingAddressChange(data),
141+
onShippingOptionsChange: (data: ShippingOptionChangeCallbackPayload) =>
142+
this.onShippingOptionsChange(data),
143+
}),
139144
onApprove: (data: ApproveCallbackPayload, actions: ApproveCallbackActions) =>
140145
this.onHostedCheckoutApprove(data, actions, methodId, onComplete),
141146
};
@@ -153,7 +158,11 @@ export default class BigCommercePaymentsCustomerStrategy implements CustomerStra
153158
const paypalButton = paypalSdk.Buttons(buttonRenderOptions);
154159

155160
if (paypalButton.isEligible()) {
156-
paypalButton.render(`#${container}`);
161+
if (paypalButton.hasReturned?.() && this.isPaypalCommerceAppSwitchEnabled(methodId)) {
162+
paypalButton.resume?.();
163+
} else {
164+
paypalButton.render(`#${container}`);
165+
}
157166
} else {
158167
this.bigCommercePaymentsIntegrationService.removeElement(container);
159168
}
@@ -249,4 +258,17 @@ export default class BigCommercePaymentsCustomerStrategy implements CustomerStra
249258
throw error;
250259
}
251260
}
261+
262+
/**
263+
*
264+
* PayPal AppSwitch enabling handling
265+
*
266+
*/
267+
private isPaypalCommerceAppSwitchEnabled(methodId: string): boolean {
268+
const state = this.paymentIntegrationService.getState();
269+
const paymentMethod =
270+
state.getPaymentMethodOrThrow<BigCommercePaymentsInitializationData>(methodId);
271+
272+
return paymentMethod.initializationData?.isAppSwitchEnabled ?? false;
273+
}
252274
}

packages/bigcommerce-payments-integration/src/mocks/get-bigcommerce-payments-payment-method.mock.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export default function getBigCommercePaymentsPaymentMethod(): PaymentMethod {
7272
},
7373
},
7474
],
75+
isAppSwitchEnabled: false,
7576
},
7677
skipRedirectConfirmationAlert: false,
7778
type: 'PAYMENT_TYPE_API',

0 commit comments

Comments
 (0)