From 662b96683d6cff1dc4c12e9ee7a4e9e97359e0db Mon Sep 17 00:00:00 2001 From: bc-nick Date: Wed, 4 Jun 2025 12:46:43 +0200 Subject: [PATCH] feat(payment): added canMakePayments method as additional verification of payment capability --- .../src/apple-pay-button-strategy.spec.ts | 12 ++++++++++++ .../src/apple-pay-button-strategy.ts | 6 ++++++ .../src/apple-pay-customer-strategy.spec.ts | 12 ++++++++++++ .../src/apple-pay-customer-strategy.ts | 6 ++++++ .../src/apple-pay-session-factory.ts | 6 ++++++ .../src/mocks/apple-pay-payment.mock.ts | 2 +- 6 files changed, 43 insertions(+), 1 deletion(-) diff --git a/packages/apple-pay-integration/src/apple-pay-button-strategy.spec.ts b/packages/apple-pay-integration/src/apple-pay-button-strategy.spec.ts index 8b553287a4..81ab0bce1f 100644 --- a/packages/apple-pay-integration/src/apple-pay-button-strategy.spec.ts +++ b/packages/apple-pay-integration/src/apple-pay-button-strategy.spec.ts @@ -154,6 +154,18 @@ describe('ApplePayButtonStrategy', () => { ).rejects.toThrow(MissingDataError); }); + it('throws error if canMakePayments returns false', async () => { + jest.spyOn(console, 'error').mockImplementation(jest.fn()); + + MockApplePaySession.canMakePayments = jest.fn().mockReturnValue(false); + + await strategy.initialize(getApplePayButtonInitializationOptions()); + + expect(console.error).toHaveBeenCalled(); + + MockApplePaySession.canMakePayments = jest.fn().mockReturnValue(true); + }); + it('throws error when params object is empty', async () => { await expect( strategy.initialize({ diff --git a/packages/apple-pay-integration/src/apple-pay-button-strategy.ts b/packages/apple-pay-integration/src/apple-pay-button-strategy.ts index 7d1556a28f..79a98627e8 100644 --- a/packages/apple-pay-integration/src/apple-pay-button-strategy.ts +++ b/packages/apple-pay-integration/src/apple-pay-button-strategy.ts @@ -125,6 +125,12 @@ export default class ApplePayButtonStrategy implements CheckoutButtonStrategy { assertApplePayWindow(window); + if (!this._sessionFactory.canMakePayment()) { + console.error('This device is not capable of making Apple Pay payments'); + + return; + } + if (!methodId || !applepay) { throw new MissingDataError(MissingDataErrorType.MissingPaymentMethod); } diff --git a/packages/apple-pay-integration/src/apple-pay-customer-strategy.spec.ts b/packages/apple-pay-integration/src/apple-pay-customer-strategy.spec.ts index 78b310980e..2ab4586c1e 100644 --- a/packages/apple-pay-integration/src/apple-pay-customer-strategy.spec.ts +++ b/packages/apple-pay-integration/src/apple-pay-customer-strategy.spec.ts @@ -157,6 +157,18 @@ describe('ApplePayCustomerStrategy', () => { await expect(strategy.initialize({})).rejects.toThrow(MissingDataError); }); + it('throws error if canMakePayments returns false', async () => { + jest.spyOn(console, 'error').mockImplementation(jest.fn()); + + MockApplePaySession.canMakePayments = jest.fn().mockReturnValue(false); + + await strategy.initialize(getApplePayCustomerInitializationOptions()); + + expect(console.error).toHaveBeenCalled(); + + MockApplePaySession.canMakePayments = jest.fn().mockReturnValue(true); + }); + it('sets up request for digital items', async () => { const cart = getCart(); diff --git a/packages/apple-pay-integration/src/apple-pay-customer-strategy.ts b/packages/apple-pay-integration/src/apple-pay-customer-strategy.ts index 624a97a1ca..674a2da9fd 100644 --- a/packages/apple-pay-integration/src/apple-pay-customer-strategy.ts +++ b/packages/apple-pay-integration/src/apple-pay-customer-strategy.ts @@ -92,6 +92,12 @@ export default class ApplePayCustomerStrategy implements CustomerStrategy { assertApplePayWindow(window); + if (!this._sessionFactory.canMakePayment()) { + console.error('This device is not capable of making Apple Pay payments'); + + return; + } + try { this._paymentMethod = state.getPaymentMethodOrThrow(methodId); } catch (_e) { diff --git a/packages/apple-pay-integration/src/apple-pay-session-factory.ts b/packages/apple-pay-integration/src/apple-pay-session-factory.ts index fa033fc2d4..80d8eae768 100644 --- a/packages/apple-pay-integration/src/apple-pay-session-factory.ts +++ b/packages/apple-pay-integration/src/apple-pay-session-factory.ts @@ -18,4 +18,10 @@ export default class ApplePaySessionFactory { return new ApplePaySession(1, request); } + + canMakePayment(): boolean { + assertApplePayWindow(window); + + return ApplePaySession.canMakePayments(); + } } diff --git a/packages/apple-pay-integration/src/mocks/apple-pay-payment.mock.ts b/packages/apple-pay-integration/src/mocks/apple-pay-payment.mock.ts index 58df1f3b0e..d344535cd0 100644 --- a/packages/apple-pay-integration/src/mocks/apple-pay-payment.mock.ts +++ b/packages/apple-pay-integration/src/mocks/apple-pay-payment.mock.ts @@ -1,6 +1,6 @@ export class MockApplePaySession { static supportsVersion: () => boolean; - static canMakePayments: () => boolean; + static canMakePayments: () => boolean = jest.fn().mockReturnValue(true); addEventListener = jest.fn(); dispatchEvent = jest.fn();