diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index f696dbfd45..e9491649f2 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -10,10 +10,8 @@ ## Integrations team /packages/core/src/checkout-buttons/strategies/amazon-pay-v2 @bigcommerce/team-integrations -/packages/core/src/checkout-buttons/strategies/masterpass @bigcommerce/team-integrations /packages/core/src/customer/strategies/amazon-pay-v2 @bigcommerce/team-integrations /packages/core/src/customer/strategies/chasepay @bigcommerce/team-integrations -/packages/core/src/customer/strategies/masterpass @bigcommerce/team-integrations /packages/core/src/customer/strategies/square @bigcommerce/team-integrations /packages/core/src/shipping/strategies/amazon-pay-v2 @bigcommerce/team-integrations /packages/core/src/shipping/strategies/stripe-upe @bigcommerce/team-integrations @@ -33,7 +31,6 @@ /packages/core/src/payment/strategies/humm @bigcommerce/team-integrations /packages/core/src/payment/strategies/klarna @bigcommerce/team-integrations /packages/core/src/payment/strategies/klarnav2 @bigcommerce/team-integrations -/packages/core/src/payment/strategies/masterpass @bigcommerce/team-integrations /packages/core/src/payment/strategies/moneris @bigcommerce/team-integrations /packages/core/src/payment/strategies/ppsdk @bigcommerce/team-integrations /packages/core/src/payment/strategies/quadpay @bigcommerce/team-integrations diff --git a/docs/README.md b/docs/README.md index 8900d1269b..28e1a5c1bd 100644 --- a/docs/README.md +++ b/docs/README.md @@ -321,8 +321,6 @@ - [LineItemSocialData](interfaces/LineItemSocialData.md) - [LinkStyles](interfaces/LinkStyles.md) - [Locales](interfaces/Locales.md) -- [MasterpassCustomerInitializeOptions](interfaces/MasterpassCustomerInitializeOptions.md) -- [MasterpassPaymentInitializeOptions](interfaces/MasterpassPaymentInitializeOptions.md) - [MolliePaymentInitializeOptions](interfaces/MolliePaymentInitializeOptions.md) - [MutationObeserverCreator](interfaces/MutationObeserverCreator.md) - [MutationObserverWindow](interfaces/MutationObserverWindow.md) diff --git a/docs/enums/CheckoutButtonMethodType.md b/docs/enums/CheckoutButtonMethodType.md index 17fbe120f2..8c98999168 100644 --- a/docs/enums/CheckoutButtonMethodType.md +++ b/docs/enums/CheckoutButtonMethodType.md @@ -22,7 +22,6 @@ - [GOOGLEPAY_STRIPE](CheckoutButtonMethodType.md#googlepay_stripe) - [GOOGLEPAY_STRIPEUPE](CheckoutButtonMethodType.md#googlepay_stripeupe) - [GOOGLEPAY_WORLDPAYACCESS](CheckoutButtonMethodType.md#googlepay_worldpayaccess) -- [MASTERPASS](CheckoutButtonMethodType.md#masterpass) - [PAYPALEXPRESS](CheckoutButtonMethodType.md#paypalexpress) ## Enumeration Members @@ -123,12 +122,6 @@ ___ ___ -### MASTERPASS - -• **MASTERPASS** - -___ - ### PAYPALEXPRESS • **PAYPALEXPRESS** diff --git a/docs/interfaces/BaseCustomerInitializeOptions.md b/docs/interfaces/BaseCustomerInitializeOptions.md index b9f3191d1f..1f6acddee5 100644 --- a/docs/interfaces/BaseCustomerInitializeOptions.md +++ b/docs/interfaces/BaseCustomerInitializeOptions.md @@ -25,7 +25,6 @@ information in order to initialize the customer step of checkout. ### Properties - [integrations](BaseCustomerInitializeOptions.md#integrations) -- [masterpass](BaseCustomerInitializeOptions.md#masterpass) - [methodId](BaseCustomerInitializeOptions.md#methodid) - [params](BaseCustomerInitializeOptions.md#params) - [timeout](BaseCustomerInitializeOptions.md#timeout) @@ -40,15 +39,6 @@ information in order to initialize the customer step of checkout. ___ -### masterpass - -• `Optional` **masterpass**: [`MasterpassCustomerInitializeOptions`](MasterpassCustomerInitializeOptions.md) - -The options that are required to initialize the Masterpass payment method. -They can be omitted unless you need to support Masterpass. - -___ - ### methodId • `Optional` **methodId**: `string` diff --git a/docs/interfaces/BasePaymentInitializeOptions.md b/docs/interfaces/BasePaymentInitializeOptions.md index c55a8dc264..af8beb7638 100644 --- a/docs/interfaces/BasePaymentInitializeOptions.md +++ b/docs/interfaces/BasePaymentInitializeOptions.md @@ -18,7 +18,6 @@ current checkout flow. - [creditCard](BasePaymentInitializeOptions.md#creditcard) - [gatewayId](BasePaymentInitializeOptions.md#gatewayid) - [integrations](BasePaymentInitializeOptions.md#integrations) -- [masterpass](BasePaymentInitializeOptions.md#masterpass) - [methodId](BasePaymentInitializeOptions.md#methodid) - [params](BasePaymentInitializeOptions.md#params) - [timeout](BasePaymentInitializeOptions.md#timeout) @@ -58,15 +57,6 @@ ___ ___ -### masterpass - -• `Optional` **masterpass**: [`MasterpassPaymentInitializeOptions`](MasterpassPaymentInitializeOptions.md) - -The options that are required to initialize the Masterpass payment method. -They can be omitted unless you need to support Masterpass. - -___ - ### methodId • **methodId**: `string` diff --git a/docs/interfaces/CheckoutButtonState.md b/docs/interfaces/CheckoutButtonState.md index 12b641963f..ff384f4d97 100644 --- a/docs/interfaces/CheckoutButtonState.md +++ b/docs/interfaces/CheckoutButtonState.md @@ -36,7 +36,6 @@ | `googlepaystripe` | `undefined` \| [`CheckoutButtonDataState`](CheckoutButtonDataState.md) | | `googlepaystripeupe` | `undefined` \| [`CheckoutButtonDataState`](CheckoutButtonDataState.md) | | `googlepayworldpayaccess` | `undefined` \| [`CheckoutButtonDataState`](CheckoutButtonDataState.md) | -| `masterpass` | `undefined` \| [`CheckoutButtonDataState`](CheckoutButtonDataState.md) | | `paypalexpress` | `undefined` \| [`CheckoutButtonDataState`](CheckoutButtonDataState.md) | ___ @@ -65,7 +64,6 @@ ___ | `googlepaystripe` | `undefined` \| [`CheckoutButtonErrorsState`](CheckoutButtonErrorsState.md) | | `googlepaystripeupe` | `undefined` \| [`CheckoutButtonErrorsState`](CheckoutButtonErrorsState.md) | | `googlepayworldpayaccess` | `undefined` \| [`CheckoutButtonErrorsState`](CheckoutButtonErrorsState.md) | -| `masterpass` | `undefined` \| [`CheckoutButtonErrorsState`](CheckoutButtonErrorsState.md) | | `paypalexpress` | `undefined` \| [`CheckoutButtonErrorsState`](CheckoutButtonErrorsState.md) | ___ @@ -94,5 +92,4 @@ ___ | `googlepaystripe` | `undefined` \| [`CheckoutButtonStatusesState`](CheckoutButtonStatusesState.md) | | `googlepaystripeupe` | `undefined` \| [`CheckoutButtonStatusesState`](CheckoutButtonStatusesState.md) | | `googlepayworldpayaccess` | `undefined` \| [`CheckoutButtonStatusesState`](CheckoutButtonStatusesState.md) | -| `masterpass` | `undefined` \| [`CheckoutButtonStatusesState`](CheckoutButtonStatusesState.md) | | `paypalexpress` | `undefined` \| [`CheckoutButtonStatusesState`](CheckoutButtonStatusesState.md) | diff --git a/docs/interfaces/MasterpassCustomerInitializeOptions.md b/docs/interfaces/MasterpassCustomerInitializeOptions.md deleted file mode 100644 index db24f99592..0000000000 --- a/docs/interfaces/MasterpassCustomerInitializeOptions.md +++ /dev/null @@ -1,17 +0,0 @@ -[@bigcommerce/checkout-sdk](../README.md) / MasterpassCustomerInitializeOptions - -# Interface: MasterpassCustomerInitializeOptions - -## Table of contents - -### Properties - -- [container](MasterpassCustomerInitializeOptions.md#container) - -## Properties - -### container - -• **container**: `string` - -The ID of a container which the checkout button should be inserted into. diff --git a/docs/interfaces/MasterpassPaymentInitializeOptions.md b/docs/interfaces/MasterpassPaymentInitializeOptions.md deleted file mode 100644 index a0c29773c1..0000000000 --- a/docs/interfaces/MasterpassPaymentInitializeOptions.md +++ /dev/null @@ -1,35 +0,0 @@ -[@bigcommerce/checkout-sdk](../README.md) / MasterpassPaymentInitializeOptions - -# Interface: MasterpassPaymentInitializeOptions - -A set of options that are required to initialize the Masterpass payment method. - -```html - -
-``` - -```js -service.initializePayment({ - methodId: 'masterpass', - masterpass: { - walletButton: 'wallet-button' - }, -}); -``` - -## Table of contents - -### Properties - -- [walletButton](MasterpassPaymentInitializeOptions.md#walletbutton) - -## Properties - -### walletButton - -• `Optional` **walletButton**: `string` - -This walletButton is used to set an event listener, provide an element ID if you want -users to be able to launch the Masterpass wallet modal by clicking on a button. -It should be an HTML element. diff --git a/packages/core/src/checkout-buttons/checkout-button-initializer.spec.ts b/packages/core/src/checkout-buttons/checkout-button-initializer.spec.ts index e3501f43c5..7e4c7e2809 100644 --- a/packages/core/src/checkout-buttons/checkout-button-initializer.spec.ts +++ b/packages/core/src/checkout-buttons/checkout-button-initializer.spec.ts @@ -25,7 +25,7 @@ describe('CheckoutButtonInitializer', () => { store = createCheckoutStore(); buttonActionCreator = new CheckoutButtonStrategyActionCreator( - createCheckoutButtonRegistry(store, createRequestSender(), createFormPoster(), 'en'), + createCheckoutButtonRegistry(store, createRequestSender(), createFormPoster()), createCheckoutButtonRegistryV2(createPaymentIntegrationService(store), {}), new PaymentMethodActionCreator(new PaymentMethodRequestSender(createRequestSender())), ); diff --git a/packages/core/src/checkout-buttons/checkout-button-strategy-action-creator.spec.ts b/packages/core/src/checkout-buttons/checkout-button-strategy-action-creator.spec.ts index 535f0b67b9..1244eb31b3 100644 --- a/packages/core/src/checkout-buttons/checkout-button-strategy-action-creator.spec.ts +++ b/packages/core/src/checkout-buttons/checkout-button-strategy-action-creator.spec.ts @@ -49,7 +49,7 @@ describe('CheckoutButtonStrategyActionCreator', () => { strategy = new MockButtonStrategy(); store = createCheckoutStore(); registryV2 = createCheckoutButtonRegistryV2(createPaymentIntegrationService(store), {}); - registry.register(CheckoutButtonMethodType.MASTERPASS, () => strategy); + registry.register(CheckoutButtonMethodType.PAYPALEXPRESS, () => strategy); jest.spyOn(paymentMethodActionCreator, 'loadPaymentMethod').mockReturnValue(() => // TODO: remove ts-ignore and update test with related type (PAYPAL-4383) @@ -64,7 +64,7 @@ describe('CheckoutButtonStrategyActionCreator', () => { ); options = { - methodId: CheckoutButtonMethodType.MASTERPASS, + methodId: CheckoutButtonMethodType.PAYPALEXPRESS, containerId: 'checkout-button', }; @@ -79,14 +79,14 @@ describe('CheckoutButtonStrategyActionCreator', () => { await from(strategyActionCreator.initialize(options)(store)).pipe(toArray()).toPromise(); expect(paymentMethodActionCreator.loadPaymentMethod).toHaveBeenCalledWith( - CheckoutButtonMethodType.MASTERPASS, + CheckoutButtonMethodType.PAYPALEXPRESS, { useCache: true }, ); }); it('loads required payment method for provided currency', async () => { const optionsMock = { - methodId: CheckoutButtonMethodType.MASTERPASS, + methodId: CheckoutButtonMethodType.PAYPALEXPRESS, containerId: 'checkout-button', currencyCode: 'USD', }; @@ -103,7 +103,7 @@ describe('CheckoutButtonStrategyActionCreator', () => { }; expect(paymentMethodActionCreator.loadPaymentMethod).toHaveBeenCalledWith( - CheckoutButtonMethodType.MASTERPASS, + CheckoutButtonMethodType.PAYPALEXPRESS, expectedPaymentMethodOptions, ); }); @@ -114,7 +114,7 @@ describe('CheckoutButtonStrategyActionCreator', () => { await from(strategyActionCreator.initialize(options)(store)).pipe(toArray()).toPromise(); - expect(registry.get).toHaveBeenCalledWith(CheckoutButtonMethodType.MASTERPASS); + expect(registry.get).toHaveBeenCalledWith(CheckoutButtonMethodType.PAYPALEXPRESS); expect(strategy.initialize).toHaveBeenCalledWith(options); }); @@ -138,12 +138,12 @@ describe('CheckoutButtonStrategyActionCreator', () => { await from(strategyActionCreator.initialize(options)(store)).pipe(toArray()).toPromise(); - expect(registry.get).not.toHaveBeenCalledWith(CheckoutButtonMethodType.MASTERPASS); + expect(registry.get).not.toHaveBeenCalledWith(CheckoutButtonMethodType.PAYPALEXPRESS); expect(strategy.initialize).not.toHaveBeenCalledWith(options); }); it('emits actions indicating initialization progress', async () => { - const methodId = CheckoutButtonMethodType.MASTERPASS; + const methodId = CheckoutButtonMethodType.PAYPALEXPRESS; const containerId = 'checkout-button'; const actions = await from( strategyActionCreator.initialize({ methodId, containerId })(store), @@ -169,7 +169,7 @@ describe('CheckoutButtonStrategyActionCreator', () => { }); it('throws error if unable to load required payment method', async () => { - const methodId = CheckoutButtonMethodType.MASTERPASS; + const methodId = CheckoutButtonMethodType.PAYPALEXPRESS; const containerId = 'checkout-button'; const expectedError = new Error('Unable to load payment method'); @@ -207,7 +207,7 @@ describe('CheckoutButtonStrategyActionCreator', () => { }); it('throws error if unable to initialize strategy', async () => { - const methodId = CheckoutButtonMethodType.MASTERPASS; + const methodId = CheckoutButtonMethodType.PAYPALEXPRESS; const containerId = 'checkout-button'; const expectedError = new Error('Unable to initialize strategy'); @@ -260,7 +260,7 @@ describe('CheckoutButtonStrategyActionCreator', () => { await from(strategyActionCreator.deinitialize(options)(store)).pipe(toArray()).toPromise(); - expect(registry.get).toHaveBeenCalledWith(CheckoutButtonMethodType.MASTERPASS); + expect(registry.get).toHaveBeenCalledWith(CheckoutButtonMethodType.PAYPALEXPRESS); expect(strategy.deinitialize).toHaveBeenCalled(); }); diff --git a/packages/core/src/checkout-buttons/create-checkout-button-initializer.ts b/packages/core/src/checkout-buttons/create-checkout-button-initializer.ts index 9fdce0e492..b202da6993 100644 --- a/packages/core/src/checkout-buttons/create-checkout-button-initializer.ts +++ b/packages/core/src/checkout-buttons/create-checkout-button-initializer.ts @@ -39,7 +39,7 @@ import createCheckoutButtonRegistryV2 from './create-checkout-button-registry-v2 export default function createCheckoutButtonInitializer( options?: CheckoutButtonInitializerOptions, ): CheckoutButtonInitializer { - const { host, locale = 'en' } = options ?? {}; + const { host } = options ?? {}; const config: ConfigState = { meta: { @@ -64,7 +64,7 @@ export default function createCheckoutButtonInitializer( return new CheckoutButtonInitializer( store, new CheckoutButtonStrategyActionCreator( - createCheckoutButtonRegistry(store, requestSender, formPoster, locale, host), + createCheckoutButtonRegistry(store, requestSender, formPoster, host), registryV2, new PaymentMethodActionCreator(new PaymentMethodRequestSender(requestSender)), ), diff --git a/packages/core/src/checkout-buttons/create-checkout-button-registry.spec.ts b/packages/core/src/checkout-buttons/create-checkout-button-registry.spec.ts index 66a5447b01..ab48aedc6d 100644 --- a/packages/core/src/checkout-buttons/create-checkout-button-registry.spec.ts +++ b/packages/core/src/checkout-buttons/create-checkout-button-registry.spec.ts @@ -6,7 +6,6 @@ import { Registry } from '../common/registry'; import createCheckoutButtonRegistry from './create-checkout-button-registry'; import { CheckoutButtonStrategy } from './strategies'; -import { MasterpassButtonStrategy } from './strategies/masterpass'; import { PaypalButtonStrategy } from './strategies/paypal'; describe('createCheckoutButtonRegistry', () => { @@ -15,19 +14,10 @@ describe('createCheckoutButtonRegistry', () => { beforeEach(() => { const store = createCheckoutStore(); - registry = createCheckoutButtonRegistry( - store, - createRequestSender(), - createFormPoster(), - 'en', - ); + registry = createCheckoutButtonRegistry(store, createRequestSender(), createFormPoster()); }); it('returns registry with PayPal Express registered', () => { expect(registry.get('paypalexpress')).toEqual(expect.any(PaypalButtonStrategy)); }); - - it('returns registry with Masterpass registered', () => { - expect(registry.get('masterpass')).toEqual(expect.any(MasterpassButtonStrategy)); - }); }); diff --git a/packages/core/src/checkout-buttons/create-checkout-button-registry.ts b/packages/core/src/checkout-buttons/create-checkout-button-registry.ts index a333b1c695..ead8fc8fb6 100644 --- a/packages/core/src/checkout-buttons/create-checkout-button-registry.ts +++ b/packages/core/src/checkout-buttons/create-checkout-button-registry.ts @@ -6,18 +6,15 @@ import { CheckoutActionCreator, CheckoutRequestSender, CheckoutStore } from '../ import { Registry } from '../common/registry'; import { ConfigActionCreator, ConfigRequestSender } from '../config'; import { FormFieldsActionCreator, FormFieldsRequestSender } from '../form'; -import { MasterpassScriptLoader } from '../payment/strategies/masterpass'; import { PaypalScriptLoader } from '../payment/strategies/paypal'; import { CheckoutButtonMethodType, CheckoutButtonStrategy } from './strategies'; -import { MasterpassButtonStrategy } from './strategies/masterpass'; import { PaypalButtonStrategy } from './strategies/paypal'; export default function createCheckoutButtonRegistry( store: CheckoutStore, requestSender: RequestSender, formPoster: FormPoster, - locale: string, host?: string, ): Registry { const registry = new Registry(); @@ -29,17 +26,6 @@ export default function createCheckoutButtonRegistry( new FormFieldsActionCreator(new FormFieldsRequestSender(requestSender)), ); - registry.register( - CheckoutButtonMethodType.MASTERPASS, - () => - new MasterpassButtonStrategy( - store, - checkoutActionCreator, - new MasterpassScriptLoader(scriptLoader), - locale, - ), - ); - registry.register( CheckoutButtonMethodType.PAYPALEXPRESS, () => diff --git a/packages/core/src/checkout-buttons/strategies/checkout-button-method-type.ts b/packages/core/src/checkout-buttons/strategies/checkout-button-method-type.ts index 6009a0e012..eecc7bb35f 100644 --- a/packages/core/src/checkout-buttons/strategies/checkout-button-method-type.ts +++ b/packages/core/src/checkout-buttons/strategies/checkout-button-method-type.ts @@ -16,6 +16,5 @@ export enum BaseCheckoutButtonMethodType { GOOGLEPAY_STRIPE = 'googlepaystripe', GOOGLEPAY_STRIPEUPE = 'googlepaystripeupe', GOOGLEPAY_WORLDPAYACCESS = 'googlepayworldpayaccess', - MASTERPASS = 'masterpass', PAYPALEXPRESS = 'paypalexpress', } diff --git a/packages/core/src/checkout-buttons/strategies/masterpass/index.ts b/packages/core/src/checkout-buttons/strategies/masterpass/index.ts deleted file mode 100644 index 2c07959a64..0000000000 --- a/packages/core/src/checkout-buttons/strategies/masterpass/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as MasterpassButtonStrategy } from './masterpass-button-strategy'; diff --git a/packages/core/src/checkout-buttons/strategies/masterpass/masterpass-button-strategy.spec.ts b/packages/core/src/checkout-buttons/strategies/masterpass/masterpass-button-strategy.spec.ts deleted file mode 100644 index 295e2150ac..0000000000 --- a/packages/core/src/checkout-buttons/strategies/masterpass/masterpass-button-strategy.spec.ts +++ /dev/null @@ -1,300 +0,0 @@ -import { createRequestSender, RequestSender } from '@bigcommerce/request-sender'; -import { createScriptLoader } from '@bigcommerce/script-loader'; - -import { CheckoutButtonInitializeOptions } from '../..'; -import { getCartState } from '../../../cart/carts.mock'; -import { - Checkout, - CheckoutActionCreator, - CheckoutRequestSender, - CheckoutStore, - createCheckoutStore, -} from '../../../checkout'; -import { getCheckout, getCheckoutState } from '../../../checkout/checkouts.mock'; -import { InvalidArgumentError, MissingDataError } from '../../../common/error/errors'; -import { ConfigActionCreator, ConfigRequestSender } from '../../../config'; -import { getConfig } from '../../../config/configs.mock'; -import { FormFieldsActionCreator, FormFieldsRequestSender } from '../../../form'; -import { PaymentMethod } from '../../../payment'; -import { getMasterpass, getPaymentMethodsState } from '../../../payment/payment-methods.mock'; -import { Masterpass, MasterpassScriptLoader } from '../../../payment/strategies/masterpass'; -import { getMasterpassScriptMock } from '../../../payment/strategies/masterpass/masterpass.mock'; -import CheckoutButtonMethodType from '../checkout-button-method-type'; -import CheckoutButtonStrategy from '../checkout-button-strategy'; - -import MasterpassButtonStrategy from './masterpass-button-strategy'; - -describe('MasterpassButtonStrategy', () => { - let container: HTMLDivElement; - let containerFoo: HTMLDivElement; - let masterpass: Masterpass; - let masterpassScriptLoader: MasterpassScriptLoader; - let checkoutActionCreator: CheckoutActionCreator; - let paymentMethodMock: PaymentMethod; - let checkoutMock: Checkout; - let requestSender: RequestSender; - let store: CheckoutStore; - let strategy: CheckoutButtonStrategy; - - beforeEach(() => { - paymentMethodMock = { - ...getMasterpass(), - initializationData: { - checkoutId: 'checkoutId', - allowedCardTypes: ['visa', 'amex', 'mastercard'], - isMasterpassSrcEnabled: false, - }, - }; - - checkoutMock = getCheckout(); - - store = createCheckoutStore({ - checkout: getCheckoutState(), - cart: getCartState(), - paymentMethods: getPaymentMethodsState(), - }); - - jest.spyOn(store, 'dispatch').mockReturnValue(Promise.resolve(store.getState())); - - jest.spyOn(store.getState().paymentMethods, 'getPaymentMethod').mockReturnValue( - paymentMethodMock, - ); - - jest.spyOn(store.getState().config, 'getStoreConfig').mockReturnValue( - getConfig().storeConfig, - ); - - jest.spyOn(store.getState().checkout, 'getCheckout').mockReturnValue(checkoutMock); - - requestSender = createRequestSender(); - - masterpass = getMasterpassScriptMock(); - - masterpassScriptLoader = new MasterpassScriptLoader(createScriptLoader()); - - jest.spyOn(masterpassScriptLoader, 'load').mockReturnValue(Promise.resolve(masterpass)); - - checkoutActionCreator = new CheckoutActionCreator( - new CheckoutRequestSender(requestSender), - new ConfigActionCreator(new ConfigRequestSender(requestSender)), - new FormFieldsActionCreator(new FormFieldsRequestSender(requestSender)), - ); - - strategy = new MasterpassButtonStrategy( - store, - checkoutActionCreator, - masterpassScriptLoader, - 'en-US', - ); - - container = document.createElement('div'); - container.setAttribute('id', 'login'); - document.body.appendChild(container); - - containerFoo = document.createElement('div'); - containerFoo.setAttribute('id', 'foo'); - document.body.appendChild(containerFoo); - }); - - afterEach(() => { - document.body.removeChild(container); - document.body.removeChild(containerFoo); - }); - - describe('#initialize()', () => { - let masterpassOptions: CheckoutButtonInitializeOptions; - const methodId = CheckoutButtonMethodType.MASTERPASS; - const masterpassScriptLoaderParams = { - useMasterpassSrc: false, - language: 'en_us', - testMode: true, - checkoutId: 'checkoutId', - }; - - beforeEach(() => { - masterpassOptions = { methodId, containerId: 'login' }; - }); - - it('loads masterpass script in test mode if enabled', async () => { - paymentMethodMock.config.testMode = true; - - await strategy.initialize(masterpassOptions); - - expect(masterpassScriptLoader.load).toHaveBeenLastCalledWith( - masterpassScriptLoaderParams, - ); - }); - - it('loads masterpass without test mode if disabled', async () => { - paymentMethodMock.config.testMode = false; - masterpassScriptLoaderParams.testMode = false; - - await strategy.initialize(masterpassOptions); - - expect(masterpassScriptLoader.load).toHaveBeenLastCalledWith( - masterpassScriptLoaderParams, - ); - }); - - it('fails to initialize the strategy if no container is supplied', async () => { - masterpassOptions = { methodId, containerId: '' }; - - try { - await strategy.initialize(masterpassOptions); - } catch (e) { - expect(e).toBeInstanceOf(InvalidArgumentError); - } - }); - - it('fails to initialize the strategy if no checkoutId is supplied', async () => { - paymentMethodMock.initializationData.checkoutId = undefined; - - try { - await strategy.initialize(masterpassOptions); - } catch (e) { - expect(e).toBeInstanceOf(MissingDataError); - } - }); - - it('fails to initialize the strategy if no container is supplied', async () => { - document.body.removeChild(container); - - try { - await strategy.initialize(masterpassOptions); - } catch (e) { - expect(e).toBeInstanceOf(Error); - - document.body.appendChild(container); - } - }); - - it('fails to initialize the strategy if no payment method is supplied', async () => { - jest.spyOn(store.getState().paymentMethods, 'getPaymentMethod').mockReturnValueOnce( - // TODO: remove ts-ignore and update test with related type (PAYPAL-4383) - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - null, - ); - - try { - await strategy.initialize(masterpassOptions); - } catch (e) { - expect(e).toBeInstanceOf(MissingDataError); - } - }); - - it('proceeds to checkout if masterpass button is clicked', async () => { - jest.spyOn(masterpass, 'checkout'); - await strategy.initialize(masterpassOptions); - - const masterpassButton = document.getElementById(masterpassOptions.containerId); - - if (masterpassButton) { - const btn = masterpassButton.firstChild as HTMLElement; - - if (btn) { - btn.click(); - - expect(masterpass.checkout).toHaveBeenCalled(); - } - } - }); - - it('loads masterpass script with correct locale when locale contains "-" character', async () => { - await strategy.initialize(masterpassOptions); - - expect(masterpassScriptLoader.load).toHaveBeenLastCalledWith( - masterpassScriptLoaderParams, - ); - }); - - it('loads masterpass script with correct locale', async () => { - strategy = new MasterpassButtonStrategy( - store, - checkoutActionCreator, - masterpassScriptLoader, - 'FR', - ); - masterpassScriptLoaderParams.language = 'fr_fr'; - - await strategy.initialize(masterpassOptions); - - expect(masterpassScriptLoader.load).toHaveBeenLastCalledWith( - masterpassScriptLoaderParams, - ); - }); - - it('loads masterpass script with default locale for unsupported country code', async () => { - strategy = new MasterpassButtonStrategy( - store, - checkoutActionCreator, - masterpassScriptLoader, - 'es_fr', - ); - masterpassScriptLoaderParams.language = 'es_es'; - - await strategy.initialize(masterpassOptions); - - expect(masterpassScriptLoader.load).toHaveBeenLastCalledWith( - masterpassScriptLoaderParams, - ); - }); - - it('loads masterpass script with default locale for unsupported language', async () => { - strategy = new MasterpassButtonStrategy( - store, - checkoutActionCreator, - masterpassScriptLoader, - 'tr', - ); - masterpassScriptLoaderParams.language = 'en_us'; - - await strategy.initialize(masterpassOptions); - - expect(masterpassScriptLoader.load).toHaveBeenLastCalledWith( - masterpassScriptLoaderParams, - ); - }); - - it('loads masterpass script with correct locale for supported language and country', async () => { - strategy = new MasterpassButtonStrategy( - store, - checkoutActionCreator, - masterpassScriptLoader, - 'zh_hk', - ); - masterpassScriptLoaderParams.language = 'zh_hk'; - - await strategy.initialize(masterpassOptions); - - expect(masterpassScriptLoader.load).toHaveBeenLastCalledWith( - masterpassScriptLoaderParams, - ); - }); - }); - - describe('#deinitialize()', () => { - let masterpassOptions: CheckoutButtonInitializeOptions; - const methodId = CheckoutButtonMethodType.MASTERPASS; - - beforeEach(() => { - masterpassOptions = { methodId, containerId: 'login' }; - }); - - it('succesfully deinitializes the strategy', async () => { - jest.spyOn(masterpass, 'checkout'); - await strategy.initialize(masterpassOptions); - strategy.deinitialize(); - - const masterpassButton = document.getElementById(masterpassOptions.containerId); - - if (masterpassButton) { - expect(masterpassButton.firstChild).toBeNull(); - } - - // Prevent "After Each" failure - container = document.createElement('div'); - document.body.appendChild(container); - }); - }); -}); diff --git a/packages/core/src/checkout-buttons/strategies/masterpass/masterpass-button-strategy.ts b/packages/core/src/checkout-buttons/strategies/masterpass/masterpass-button-strategy.ts deleted file mode 100644 index f02a249f40..0000000000 --- a/packages/core/src/checkout-buttons/strategies/masterpass/masterpass-button-strategy.ts +++ /dev/null @@ -1,161 +0,0 @@ -import { bindDecorator as bind } from '@bigcommerce/checkout-sdk/utility'; - -import { CheckoutActionCreator, CheckoutStore } from '../../../checkout'; -import { - InvalidArgumentError, - MissingDataError, - MissingDataErrorType, - NotInitializedError, - NotInitializedErrorType, -} from '../../../common/error/errors'; -import { - formatLocale, - getCallbackUrl, - Masterpass, - MasterpassCheckoutOptions, - MasterpassScriptLoader, -} from '../../../payment/strategies/masterpass'; -import { CheckoutButtonInitializeOptions } from '../../checkout-button-options'; -import CheckoutButtonStrategy from '../checkout-button-strategy'; - -export default class MasterpassButtonStrategy implements CheckoutButtonStrategy { - private _masterpassClient?: Masterpass; - private _methodId?: string; - private _signInButton?: HTMLElement; - - constructor( - private _store: CheckoutStore, - private _checkoutActionCreator: CheckoutActionCreator, - private _masterpassScriptLoader: MasterpassScriptLoader, - private _locale: string, - ) {} - - initialize(options: CheckoutButtonInitializeOptions): Promise { - const { containerId, methodId } = options; - - if (!containerId || !methodId) { - throw new InvalidArgumentError( - 'Unable to proceed because "containerId" argument is not provided.', - ); - } - - this._methodId = methodId; - - return this._store - .dispatch(this._checkoutActionCreator.loadDefaultCheckout()) - .then((state) => { - const paymentMethod = state.paymentMethods.getPaymentMethod(methodId); - - if (!paymentMethod || !paymentMethod.initializationData.checkoutId) { - throw new MissingDataError(MissingDataErrorType.MissingPaymentMethod); - } - - const masterpassScriptLoaderParams = { - useMasterpassSrc: paymentMethod.initializationData.isMasterpassSrcEnabled, - language: formatLocale(this._locale), - testMode: paymentMethod.config.testMode, - checkoutId: paymentMethod.initializationData.checkoutId, - }; - - return this._masterpassScriptLoader.load(masterpassScriptLoaderParams); - }) - .then((masterpass) => { - this._masterpassClient = masterpass; - this._signInButton = this._createSignInButton(containerId); - }); - } - - deinitialize(): Promise { - if (this._signInButton && this._signInButton.parentNode) { - this._signInButton.removeEventListener('click', this._handleWalletButtonClick); - this._signInButton.parentNode.removeChild(this._signInButton); - this._signInButton = undefined; - } - - return Promise.resolve(); - } - - private _createSignInButton(containerId: string): HTMLElement { - const buttonContainer = document.getElementById(containerId); - const state = this._store.getState(); - const paymentMethod = this._methodId - ? state.paymentMethods.getPaymentMethod(this._methodId) - : null; - const storeConfig = state.config.getStoreConfig(); - - if (!buttonContainer) { - throw new Error('Need a container to place the button'); - } - - if (!paymentMethod) { - throw new MissingDataError(MissingDataErrorType.MissingPaymentMethod); - } - - if (!storeConfig) { - throw new InvalidArgumentError('Unable to retrieve store configuration'); - } - - const button = document.createElement('input'); - - button.type = 'image'; - - if (paymentMethod.initializationData.isMasterpassSrcEnabled) { - const subdomain = paymentMethod.config.testMode ? 'sandbox.' : ''; - const { checkoutId } = paymentMethod.initializationData; - - const params = [ - `locale=${formatLocale(this._locale)}`, - `paymentmethod=master,visa,amex,discover`, - `checkoutid=${checkoutId}`, - ]; - - button.src = [ - `https://${subdomain}src.mastercard.com/assets/img/btn/src_chk_btn_126x030px.svg`, - params.join('&'), - ].join('?'); - } else { - button.src = - 'https://static.masterpass.com/dyn/img/btn/global/mp_chk_btn_160x037px.svg'; - } - - buttonContainer.appendChild(button); - - button.addEventListener('click', this._handleWalletButtonClick); - - return button; - } - - private _createMasterpassPayload(): MasterpassCheckoutOptions { - const state = this._store.getState(); - const checkout = state.checkout.getCheckout(); - const paymentMethod = this._methodId - ? state.paymentMethods.getPaymentMethod(this._methodId) - : null; - - if (!checkout) { - throw new MissingDataError(MissingDataErrorType.MissingCheckout); - } - - if (!paymentMethod) { - throw new MissingDataError(MissingDataErrorType.MissingPaymentMethod); - } - - return { - checkoutId: paymentMethod.initializationData.checkoutId, - allowedCardTypes: paymentMethod.initializationData.allowedCardTypes, - amount: checkout.cart.cartAmount.toString(), - currency: checkout.cart.currency.code, - cartId: checkout.cart.id, - callbackUrl: getCallbackUrl('cart'), - }; - } - - @bind - private _handleWalletButtonClick(): void { - if (!this._masterpassClient) { - throw new NotInitializedError(NotInitializedErrorType.CheckoutButtonNotInitialized); - } - - this._masterpassClient.checkout(this._createMasterpassPayload()); - } -} diff --git a/packages/core/src/checkout/checkout-service.spec.ts b/packages/core/src/checkout/checkout-service.spec.ts index 2c07dae433..9135836e16 100644 --- a/packages/core/src/checkout/checkout-service.spec.ts +++ b/packages/core/src/checkout/checkout-service.spec.ts @@ -380,7 +380,7 @@ describe('CheckoutService', () => { const errorLogger: ErrorLogger = { log: jest.fn() }; customerStrategyActionCreator = new CustomerStrategyActionCreator( - createCustomerStrategyRegistry(store, requestSender, locale), + createCustomerStrategyRegistry(store, requestSender), customerRegistryV2, paymentIntegrationService, errorLogger, diff --git a/packages/core/src/checkout/create-checkout-service.ts b/packages/core/src/checkout/create-checkout-service.ts index c4b5584707..f4f3e11cca 100644 --- a/packages/core/src/checkout/create-checkout-service.ts +++ b/packages/core/src/checkout/create-checkout-service.ts @@ -185,7 +185,7 @@ export default function createCheckoutService(options?: CheckoutServiceOptions): new CountryActionCreator(new CountryRequestSender(requestSender, { locale })), new CouponActionCreator(new CouponRequestSender(requestSender)), new CustomerStrategyActionCreator( - createCustomerStrategyRegistry(store, requestSender, locale), + createCustomerStrategyRegistry(store, requestSender), customerRegistryV2, paymentIntegrationService, errorLogger, @@ -196,7 +196,7 @@ export default function createCheckoutService(options?: CheckoutServiceOptions): orderActionCreator, new PaymentMethodActionCreator(new PaymentMethodRequestSender(requestSender)), new PaymentStrategyActionCreator( - createPaymentStrategyRegistry(store, paymentClient, requestSender, locale), + createPaymentStrategyRegistry(store, paymentClient, requestSender), registryV2, orderActionCreator, spamProtectionActionCreator, diff --git a/packages/core/src/customer/create-customer-strategy-registry.ts b/packages/core/src/customer/create-customer-strategy-registry.ts index d15698c558..3bef89846e 100644 --- a/packages/core/src/customer/create-customer-strategy-registry.ts +++ b/packages/core/src/customer/create-customer-strategy-registry.ts @@ -5,9 +5,6 @@ import { CheckoutActionCreator, CheckoutRequestSender, CheckoutStore } from '../ import { Registry } from '../common/registry'; import { ConfigActionCreator, ConfigRequestSender } from '../config'; import { FormFieldsActionCreator, FormFieldsRequestSender } from '../form'; -import { PaymentMethodActionCreator, PaymentMethodRequestSender } from '../payment'; -import { MasterpassScriptLoader } from '../payment/strategies/masterpass'; -import { RemoteCheckoutActionCreator, RemoteCheckoutRequestSender } from '../remote-checkout'; import { createSpamProtection, SpamProtectionActionCreator, @@ -18,12 +15,10 @@ import CustomerActionCreator from './customer-action-creator'; import CustomerRequestSender from './customer-request-sender'; import { CustomerStrategy } from './strategies'; import { DefaultCustomerStrategy } from './strategies/default'; -import { MasterpassCustomerStrategy } from './strategies/masterpass'; export default function createCustomerStrategyRegistry( store: CheckoutStore, requestSender: RequestSender, - locale: string, ): Registry { const registry = new Registry(); const scriptLoader = getScriptLoader(); @@ -33,14 +28,6 @@ export default function createCustomerStrategyRegistry( new ConfigActionCreator(new ConfigRequestSender(requestSender)), new FormFieldsActionCreator(new FormFieldsRequestSender(requestSender)), ); - const paymentMethodActionCreator = new PaymentMethodActionCreator( - new PaymentMethodRequestSender(requestSender), - ); - const remoteCheckoutRequestSender = new RemoteCheckoutRequestSender(requestSender); - const remoteCheckoutActionCreator = new RemoteCheckoutActionCreator( - remoteCheckoutRequestSender, - checkoutActionCreator, - ); const spamProtectionActionCreator = new SpamProtectionActionCreator( createSpamProtection(scriptLoader), new SpamProtectionRequestSender(requestSender), @@ -51,18 +38,6 @@ export default function createCustomerStrategyRegistry( spamProtectionActionCreator, ); - registry.register( - 'masterpass', - () => - new MasterpassCustomerStrategy( - store, - paymentMethodActionCreator, - remoteCheckoutActionCreator, - new MasterpassScriptLoader(scriptLoader), - locale, - ), - ); - registry.register('default', () => new DefaultCustomerStrategy(store, customerActionCreator)); return registry; diff --git a/packages/core/src/customer/customer-request-options.ts b/packages/core/src/customer/customer-request-options.ts index 0ec282c771..b2a92893a6 100644 --- a/packages/core/src/customer/customer-request-options.ts +++ b/packages/core/src/customer/customer-request-options.ts @@ -5,8 +5,6 @@ import { import { RequestOptions } from '../common/http-request'; -import { MasterpassCustomerInitializeOptions } from './strategies/masterpass'; - export { CustomerInitializeOptions } from '../generated/customer-initialize-options'; /** @@ -37,12 +35,6 @@ export interface BaseCustomerInitializeOptions extends CustomerRequestOptions { * @alpha */ integrations?: Array>; - - /** - * The options that are required to initialize the Masterpass payment method. - * They can be omitted unless you need to support Masterpass. - */ - masterpass?: MasterpassCustomerInitializeOptions; } /** diff --git a/packages/core/src/customer/customer-strategy-action-creator.spec.ts b/packages/core/src/customer/customer-strategy-action-creator.spec.ts index 86c3e83fa4..d1f23398de 100644 --- a/packages/core/src/customer/customer-strategy-action-creator.spec.ts +++ b/packages/core/src/customer/customer-strategy-action-creator.spec.ts @@ -76,7 +76,7 @@ describe('CustomerStrategyActionCreator', () => { }; customerRegistryV2 = createCustomerStrategyRegistryV2(paymentIntegrationService, {}); - registry = createCustomerStrategyRegistry(store, createRequestSender(), 'en'); + registry = createCustomerStrategyRegistry(store, createRequestSender()); strategy = new DefaultCustomerStrategy( store, new CustomerActionCreator( diff --git a/packages/core/src/customer/strategies/masterpass/index.ts b/packages/core/src/customer/strategies/masterpass/index.ts deleted file mode 100644 index d986b5cfc2..0000000000 --- a/packages/core/src/customer/strategies/masterpass/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default as MasterpassCustomerInitializeOptions } from './masterpass-customer-initialize-options'; -export { default as MasterpassCustomerStrategy } from './masterpass-customer-strategy'; diff --git a/packages/core/src/customer/strategies/masterpass/masterpass-customer-initialize-options.ts b/packages/core/src/customer/strategies/masterpass/masterpass-customer-initialize-options.ts deleted file mode 100644 index 32c81ffbd0..0000000000 --- a/packages/core/src/customer/strategies/masterpass/masterpass-customer-initialize-options.ts +++ /dev/null @@ -1,6 +0,0 @@ -export default interface MasterpassCustomerInitializeOptions { - /** - * The ID of a container which the checkout button should be inserted into. - */ - container: string; -} diff --git a/packages/core/src/customer/strategies/masterpass/masterpass-customer-strategy.spec.ts b/packages/core/src/customer/strategies/masterpass/masterpass-customer-strategy.spec.ts deleted file mode 100644 index e5c1d8f146..0000000000 --- a/packages/core/src/customer/strategies/masterpass/masterpass-customer-strategy.spec.ts +++ /dev/null @@ -1,356 +0,0 @@ -import { createRequestSender, RequestSender } from '@bigcommerce/request-sender'; -import { createScriptLoader } from '@bigcommerce/script-loader'; - -import { getCartState } from '../../../cart/carts.mock'; -import { - CheckoutActionCreator, - CheckoutRequestSender, - CheckoutStore, - createCheckoutStore, -} from '../../../checkout'; -import { getCheckoutState } from '../../../checkout/checkouts.mock'; -import { InvalidArgumentError, MissingDataError } from '../../../common/error/errors'; -import { ConfigActionCreator, ConfigRequestSender } from '../../../config'; -import { getConfig, getConfigState } from '../../../config/configs.mock'; -import { FormFieldsActionCreator, FormFieldsRequestSender } from '../../../form'; -import { - PaymentMethod, - PaymentMethodActionCreator, - PaymentMethodRequestSender, -} from '../../../payment'; -import { getMasterpass, getPaymentMethodsState } from '../../../payment/payment-methods.mock'; -import { Masterpass, MasterpassScriptLoader } from '../../../payment/strategies/masterpass'; -import { getMasterpassScriptMock } from '../../../payment/strategies/masterpass/masterpass.mock'; -import { RemoteCheckoutActionCreator, RemoteCheckoutRequestSender } from '../../../remote-checkout'; -import { CustomerInitializeOptions } from '../../customer-request-options'; -import { getCustomerState } from '../../customers.mock'; -import CustomerStrategy from '../customer-strategy'; - -import MasterpassCustomerStrategy from './masterpass-customer-strategy'; - -describe('MasterpassCustomerStrategy', () => { - let checkoutActionCreator: CheckoutActionCreator; - let container: HTMLDivElement; - let masterpass: Masterpass; - let masterpassScriptLoader: MasterpassScriptLoader; - let paymentMethodActionCreator: PaymentMethodActionCreator; - let paymentMethodMock: PaymentMethod; - let remoteCheckoutActionCreator: RemoteCheckoutActionCreator; - let requestSender: RequestSender; - let store: CheckoutStore; - let strategy: CustomerStrategy; - - beforeEach(() => { - paymentMethodMock = { - ...getMasterpass(), - initializationData: { - checkoutId: 'checkoutId', - allowedCardTypes: ['visa', 'amex', 'mastercard'], - isMasterpassSrcEnabled: false, - }, - }; - - store = createCheckoutStore({ - checkout: getCheckoutState(), - customer: getCustomerState(), - config: getConfigState(), - cart: getCartState(), - paymentMethods: getPaymentMethodsState(), - }); - - jest.spyOn(store, 'dispatch').mockReturnValue(Promise.resolve(store.getState())); - - jest.spyOn(store.getState().paymentMethods, 'getPaymentMethod').mockReturnValue( - paymentMethodMock, - ); - - jest.spyOn(store.getState().config, 'getStoreConfig').mockReturnValue( - getConfig().storeConfig, - ); - - requestSender = createRequestSender(); - - checkoutActionCreator = new CheckoutActionCreator( - new CheckoutRequestSender(requestSender), - new ConfigActionCreator(new ConfigRequestSender(requestSender)), - new FormFieldsActionCreator(new FormFieldsRequestSender(requestSender)), - ); - - remoteCheckoutActionCreator = new RemoteCheckoutActionCreator( - new RemoteCheckoutRequestSender(requestSender), - checkoutActionCreator, - ); - - masterpass = getMasterpassScriptMock(); - - masterpassScriptLoader = new MasterpassScriptLoader(createScriptLoader()); - - jest.spyOn(masterpassScriptLoader, 'load').mockReturnValue(Promise.resolve(masterpass)); - - paymentMethodActionCreator = new PaymentMethodActionCreator( - new PaymentMethodRequestSender(requestSender), - ); - strategy = new MasterpassCustomerStrategy( - store, - paymentMethodActionCreator, - remoteCheckoutActionCreator, - masterpassScriptLoader, - 'en-US', - ); - - container = document.createElement('div'); - container.setAttribute('id', 'login'); - document.body.appendChild(container); - }); - - afterEach(() => { - document.body.removeChild(container); - }); - - it('creates an instance of MasterpassCustomerStrategy', () => { - expect(strategy).toBeInstanceOf(MasterpassCustomerStrategy); - }); - - describe('#initialize()', () => { - let masterpassOptions: CustomerInitializeOptions; - const masterpassScriptLoaderParams = { - useMasterpassSrc: false, - language: 'en_us', - testMode: true, - checkoutId: 'checkoutId', - }; - - beforeEach(() => { - masterpassOptions = { methodId: 'masterpass', masterpass: { container: 'login' } }; - }); - - it('loads masterpass script in test mode if enabled', async () => { - paymentMethodMock.config.testMode = true; - - await strategy.initialize(masterpassOptions); - - expect(masterpassScriptLoader.load).toHaveBeenLastCalledWith( - masterpassScriptLoaderParams, - ); - }); - - it('loads masterpass without test mode if disabled', async () => { - paymentMethodMock.config.testMode = false; - masterpassScriptLoaderParams.testMode = false; - - await strategy.initialize(masterpassOptions); - - expect(masterpassScriptLoader.load).toHaveBeenLastCalledWith( - masterpassScriptLoaderParams, - ); - }); - - it('fails to initialize the strategy if no methodId is supplied', async () => { - masterpassOptions = { methodId: undefined, masterpass: { container: 'login' } }; - - try { - await strategy.initialize(masterpassOptions); - } catch (e) { - expect(e).toBeInstanceOf(InvalidArgumentError); - } - }); - - it('fails to initialize the strategy if no cart is supplied', async () => { - jest.spyOn(store.getState().cart, 'getCart').mockReturnValue(undefined); - - try { - await strategy.initialize(masterpassOptions); - } catch (e) { - expect(e).toBeInstanceOf(MissingDataError); - } - }); - - it('fails to initialize the strategy if no checkoutId is supplied', async () => { - paymentMethodMock.initializationData.checkoutId = undefined; - - try { - await strategy.initialize(masterpassOptions); - } catch (e) { - expect(e).toBeInstanceOf(MissingDataError); - } - }); - - it('proceeds to checkout if masterpass button is clicked', async () => { - jest.spyOn(masterpass, 'checkout'); - await strategy.initialize(masterpassOptions); - - if (masterpassOptions.masterpass) { - const masterpassButton = document.getElementById( - masterpassOptions.masterpass.container, - ); - - if (masterpassButton) { - const btn = masterpassButton.firstChild as HTMLElement; - - if (btn) { - btn.click(); - - expect(masterpass.checkout).toHaveBeenCalled(); - } - } - } - }); - - it('loads masterpass script with correct locale when locale contains "-" character', async () => { - await strategy.initialize(masterpassOptions); - - expect(masterpassScriptLoader.load).toHaveBeenLastCalledWith({ - ...masterpassScriptLoaderParams, - language: 'en_us', - }); - }); - - it('loads masterpass script with correct locale', async () => { - strategy = new MasterpassCustomerStrategy( - store, - paymentMethodActionCreator, - remoteCheckoutActionCreator, - masterpassScriptLoader, - 'FR', - ); - await strategy.initialize(masterpassOptions); - - expect(masterpassScriptLoader.load).toHaveBeenLastCalledWith({ - ...masterpassScriptLoaderParams, - language: 'fr_fr', - }); - }); - - it('loads masterpass script with default locale for unsupported country code', async () => { - strategy = new MasterpassCustomerStrategy( - store, - paymentMethodActionCreator, - remoteCheckoutActionCreator, - masterpassScriptLoader, - 'es_fr', - ); - await strategy.initialize(masterpassOptions); - - expect(masterpassScriptLoader.load).toHaveBeenLastCalledWith({ - ...masterpassScriptLoaderParams, - language: 'es_es', - }); - }); - - it('loads masterpass script with default locale for unsupported language', async () => { - strategy = new MasterpassCustomerStrategy( - store, - paymentMethodActionCreator, - remoteCheckoutActionCreator, - masterpassScriptLoader, - 'tr', - ); - await strategy.initialize(masterpassOptions); - - expect(masterpassScriptLoader.load).toHaveBeenLastCalledWith({ - ...masterpassScriptLoaderParams, - language: 'en_us', - }); - }); - - it('loads masterpass script with correct locale for supported language and country', async () => { - strategy = new MasterpassCustomerStrategy( - store, - paymentMethodActionCreator, - remoteCheckoutActionCreator, - masterpassScriptLoader, - 'zh_hk', - ); - await strategy.initialize(masterpassOptions); - - expect(masterpassScriptLoader.load).toHaveBeenLastCalledWith({ - ...masterpassScriptLoaderParams, - language: 'zh_hk', - }); - }); - }); - - describe('#deinitialize()', () => { - let masterpassOptions: CustomerInitializeOptions; - - beforeEach(() => { - masterpassOptions = { methodId: 'masterpass', masterpass: { container: 'login' } }; - }); - - it('successfully deinitializes the strategy', async () => { - jest.spyOn(masterpass, 'checkout'); - await strategy.initialize(masterpassOptions); - strategy.deinitialize(); - - if (masterpassOptions.masterpass) { - const masterpassButton = document.getElementById( - masterpassOptions.masterpass.container, - ); - - if (masterpassButton) { - expect(masterpassButton.firstChild).toBeNull(); - } - } - - // Prevent "After Each" failure - container = document.createElement('div'); - document.body.appendChild(container); - }); - }); - - describe('#signIn()', () => { - beforeEach(async () => { - await strategy.initialize({ - methodId: 'masterpass', - masterpass: { container: 'login' }, - }); - }); - - it('throws error if trying to sign in programmatically', () => { - expect(() => strategy.signIn({ email: 'foo@bar.com', password: 'foobar' })).toThrow(); - }); - }); - - describe('#signOut()', () => { - beforeEach(async () => { - const paymentId = { - providerId: 'masterpass', - }; - - jest.spyOn(store.getState().payment, 'getPaymentId').mockReturnValue(paymentId); - - // TODO: remove ts-ignore and update test with related type (PAYPAL-4383) - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - jest.spyOn(remoteCheckoutActionCreator, 'signOut').mockReturnValue('data'); - - await strategy.initialize({ - methodId: 'masterpass', - masterpass: { container: 'login' }, - }); - }); - - it('throws error if trying to sign out programmatically', async () => { - const options = { - methodId: 'masterpass', - }; - - await strategy.signOut(options); - - expect(remoteCheckoutActionCreator.signOut).toHaveBeenCalledWith('masterpass', options); - expect(store.dispatch).toHaveBeenCalled(); - }); - }); - - describe('#executePaymentMethodCheckout', () => { - it('runs continue callback automatically on execute payment method checkout', async () => { - const mockCallback = jest.fn(); - - await strategy.executePaymentMethodCheckout({ - continueWithCheckoutCallback: mockCallback, - }); - - expect(mockCallback.mock.calls).toHaveLength(1); - }); - }); -}); diff --git a/packages/core/src/customer/strategies/masterpass/masterpass-customer-strategy.ts b/packages/core/src/customer/strategies/masterpass/masterpass-customer-strategy.ts deleted file mode 100644 index 5cd84d3100..0000000000 --- a/packages/core/src/customer/strategies/masterpass/masterpass-customer-strategy.ts +++ /dev/null @@ -1,168 +0,0 @@ -import { CheckoutStore, InternalCheckoutSelectors } from '../../../checkout'; -import { - InvalidArgumentError, - MissingDataError, - MissingDataErrorType, - NotImplementedError, -} from '../../../common/error/errors'; -import { PaymentMethod, PaymentMethodActionCreator } from '../../../payment'; -import { - formatLocale, - getCallbackUrl, - MasterpassScriptLoader, -} from '../../../payment/strategies/masterpass'; -import { RemoteCheckoutActionCreator } from '../../../remote-checkout'; -import { - CustomerInitializeOptions, - CustomerRequestOptions, - ExecutePaymentMethodCheckoutOptions, -} from '../../customer-request-options'; -import CustomerStrategy from '../customer-strategy'; - -export default class MasterpassCustomerStrategy implements CustomerStrategy { - private _signInButton?: HTMLElement; - private _paymentMethod?: PaymentMethod; - - constructor( - private _store: CheckoutStore, - private _paymentMethodActionCreator: PaymentMethodActionCreator, - private _remoteCheckoutActionCreator: RemoteCheckoutActionCreator, - private _masterpassScriptLoader: MasterpassScriptLoader, - private _locale: string, - ) {} - - initialize(options: CustomerInitializeOptions): Promise { - const { masterpass: masterpassOptions, methodId } = options; - - if (!masterpassOptions || !methodId) { - throw new InvalidArgumentError( - 'Unable to proceed because "options.masterpass" argument is not provided.', - ); - } - - return this._store - .dispatch(this._paymentMethodActionCreator.loadPaymentMethod(methodId)) - .then((state) => { - this._paymentMethod = state.paymentMethods.getPaymentMethod(methodId); - - if (!this._paymentMethod || !this._paymentMethod.initializationData.checkoutId) { - throw new MissingDataError(MissingDataErrorType.MissingPaymentMethod); - } - - const cart = state.cart.getCart(); - - if (!cart) { - throw new MissingDataError(MissingDataErrorType.MissingCart); - } - - const { container } = masterpassOptions; - - const payload = { - checkoutId: this._paymentMethod.initializationData.checkoutId, - allowedCardTypes: this._paymentMethod.initializationData.allowedCardTypes, - amount: cart.cartAmount.toString(), - currency: cart.currency.code, - cartId: cart.id, - suppressShippingAddress: false, - callbackUrl: getCallbackUrl('checkout'), - }; - - const masterpassScriptLoaderParams = { - useMasterpassSrc: this._paymentMethod.initializationData.isMasterpassSrcEnabled, - language: formatLocale(this._locale), - testMode: this._paymentMethod.config.testMode, - checkoutId: this._paymentMethod.initializationData.checkoutId, - }; - - return this._masterpassScriptLoader - .load(masterpassScriptLoaderParams) - .then((Masterpass) => { - this._signInButton = this._createSignInButton(container); - - this._signInButton.addEventListener('click', () => { - Masterpass.checkout(payload); - }); - }); - }) - .then(() => this._store.getState()); - } - - deinitialize(): Promise { - this._paymentMethod = undefined; - - if (this._signInButton && this._signInButton.parentNode) { - this._signInButton.parentNode.removeChild(this._signInButton); - this._signInButton = undefined; - } - - return Promise.resolve(this._store.getState()); - } - - signIn(): Promise { - throw new NotImplementedError( - 'In order to sign in via Masterpass, the shopper must click on "Masterpass" button.', - ); - } - - signOut(options?: CustomerRequestOptions): Promise { - const state = this._store.getState(); - const payment = state.payment.getPaymentId(); - - if (!payment) { - return Promise.resolve(this._store.getState()); - } - - return this._store.dispatch( - this._remoteCheckoutActionCreator.signOut(payment.providerId, options), - ); - } - - executePaymentMethodCheckout( - options?: ExecutePaymentMethodCheckoutOptions, - ): Promise { - options?.continueWithCheckoutCallback?.(); - - return Promise.resolve(this._store.getState()); - } - - private _createSignInButton(containerId: string): HTMLElement { - const container = document.querySelector(`#${containerId}`); - - if (!this._paymentMethod || !this._paymentMethod.initializationData.checkoutId) { - throw new MissingDataError(MissingDataErrorType.MissingPaymentMethod); - } - - if (!container) { - throw new InvalidArgumentError( - 'Unable to create sign-in button without valid container ID.', - ); - } - - const button = document.createElement('input'); - - button.type = 'image'; - - if (this._paymentMethod.initializationData.isMasterpassSrcEnabled) { - const subdomain = this._paymentMethod.config.testMode ? 'sandbox.' : ''; - const { checkoutId } = this._paymentMethod.initializationData; - - const params = [ - `locale=${formatLocale(this._locale)}`, - `paymentmethod=master,visa,amex,discover`, - `checkoutid=${checkoutId}`, - ]; - - button.src = [ - `https://${subdomain}src.mastercard.com/assets/img/btn/src_chk_btn_126x030px.svg`, - params.join('&'), - ].join('?'); - } else { - button.src = - 'https://static.masterpass.com/dyn/img/btn/global/mp_chk_btn_160x037px.svg'; - } - - container.appendChild(button); - - return button; - } -} diff --git a/packages/core/src/payment/create-payment-strategy-registry.spec.ts b/packages/core/src/payment/create-payment-strategy-registry.spec.ts index 6e8c499473..f9833c44a5 100644 --- a/packages/core/src/payment/create-payment-strategy-registry.spec.ts +++ b/packages/core/src/payment/create-payment-strategy-registry.spec.ts @@ -7,7 +7,6 @@ import createPaymentStrategyRegistry from './create-payment-strategy-registry'; import PaymentStrategyRegistry from './payment-strategy-registry'; import PaymentStrategyType from './payment-strategy-type'; import { ConvergePaymentStrategy } from './strategies/converge'; -import { MasterpassPaymentStrategy } from './strategies/masterpass'; import { PPSDKStrategy } from './strategies/ppsdk'; import { WepayPaymentStrategy } from './strategies/wepay'; @@ -19,7 +18,7 @@ describe('CreatePaymentStrategyRegistry', () => { const requestSender = createRequestSender(); const paymentClient = createPaymentClient(); - registry = createPaymentStrategyRegistry(store, paymentClient, requestSender, 'en_US'); + registry = createPaymentStrategyRegistry(store, paymentClient, requestSender); }); it('can create a payment strategy registry', () => { @@ -38,12 +37,6 @@ describe('CreatePaymentStrategyRegistry', () => { expect(paymentStrategy).toBeInstanceOf(WepayPaymentStrategy); }); - it('can instantiate masterpass', () => { - const paymentStrategy = registry.get(PaymentStrategyType.MASTERPASS); - - expect(paymentStrategy).toBeInstanceOf(MasterpassPaymentStrategy); - }); - it('can instantiate ppsdk', () => { const paymentStrategy = registry.get(PaymentStrategyType.PPSDK); diff --git a/packages/core/src/payment/create-payment-strategy-registry.ts b/packages/core/src/payment/create-payment-strategy-registry.ts index 174aaa8fa4..142ffe08bf 100644 --- a/packages/core/src/payment/create-payment-strategy-registry.ts +++ b/packages/core/src/payment/create-payment-strategy-registry.ts @@ -14,7 +14,6 @@ import PaymentRequestTransformer from './payment-request-transformer'; import PaymentStrategyRegistry from './payment-strategy-registry'; import PaymentStrategyType from './payment-strategy-type'; import { ConvergePaymentStrategy } from './strategies/converge'; -import { MasterpassPaymentStrategy, MasterpassScriptLoader } from './strategies/masterpass'; import { createStepHandler, createSubStrategyRegistry, @@ -27,7 +26,6 @@ export default function createPaymentStrategyRegistry( store: CheckoutStore, paymentClient: any, requestSender: RequestSender, - locale: string, ) { const registry = new PaymentStrategyRegistry({ defaultToken: PaymentStrategyType.CREDIT_CARD, @@ -67,18 +65,6 @@ export default function createPaymentStrategyRegistry( ), ); - registry.register( - PaymentStrategyType.MASTERPASS, - () => - new MasterpassPaymentStrategy( - store, - orderActionCreator, - paymentActionCreator, - new MasterpassScriptLoader(scriptLoader), - locale, - ), - ); - registry.register( PaymentStrategyType.PPSDK, () => diff --git a/packages/core/src/payment/payment-methods.mock.ts b/packages/core/src/payment/payment-methods.mock.ts index 09bf4ae9a9..6af214e603 100644 --- a/packages/core/src/payment/payment-methods.mock.ts +++ b/packages/core/src/payment/payment-methods.mock.ts @@ -385,21 +385,6 @@ export function getSquare(): PaymentMethod { }; } -export function getMasterpass(): PaymentMethod { - return { - id: 'masterpass', - logoUrl: '', - method: 'masterpass', - supportedCards: ['VISA', 'MC', 'AMEX'], - config: { - displayName: 'Masterpass', - testMode: false, - }, - type: 'PAYMENT_TYPE_API', - skipRedirectConfirmationAlert: false, - }; -} - export function getWepay(): PaymentMethod { return { id: 'wepay', diff --git a/packages/core/src/payment/payment-request-options.ts b/packages/core/src/payment/payment-request-options.ts index 356f357b08..c96a03c050 100644 --- a/packages/core/src/payment/payment-request-options.ts +++ b/packages/core/src/payment/payment-request-options.ts @@ -6,8 +6,6 @@ import { import { RequestOptions } from '../common/http-request'; -import { MasterpassPaymentInitializeOptions } from './strategies/masterpass'; - export { PaymentInitializeOptions } from '../generated/payment-initialize-options'; /** @@ -45,12 +43,6 @@ export interface BasePaymentInitializeOptions extends PaymentRequestOptions { * consumption. */ creditCard?: CreditCardPaymentInitializeOptions; - - /** - * The options that are required to initialize the Masterpass payment method. - * They can be omitted unless you need to support Masterpass. - */ - masterpass?: MasterpassPaymentInitializeOptions; } export interface OrderFinalizeOptions extends RequestOptions { diff --git a/packages/core/src/payment/payment-strategy-action-creator.spec.ts b/packages/core/src/payment/payment-strategy-action-creator.spec.ts index 4d1817b040..52ef48c622 100644 --- a/packages/core/src/payment/payment-strategy-action-creator.spec.ts +++ b/packages/core/src/payment/payment-strategy-action-creator.spec.ts @@ -93,7 +93,7 @@ describe('PaymentStrategyActionCreator', () => { errorLogger = { log: jest.fn(), }; - registry = createPaymentStrategyRegistry(store, paymentClient, requestSender, 'en_US'); + registry = createPaymentStrategyRegistry(store, paymentClient, requestSender); orderActionCreator = new OrderActionCreator( new OrderRequestSender(requestSender), new CheckoutValidator(new CheckoutRequestSender(createRequestSender())), @@ -638,7 +638,7 @@ describe('PaymentStrategyActionCreator', () => { ...state, paymentMethods: { ...state.paymentMethods, data: [] }, }); - registry = createPaymentStrategyRegistry(store, paymentClient, requestSender, 'en_US'); + registry = createPaymentStrategyRegistry(store, paymentClient, requestSender); const actionCreator = new PaymentStrategyActionCreator( registry, @@ -666,7 +666,7 @@ describe('PaymentStrategyActionCreator', () => { }), }); - registry = createPaymentStrategyRegistry(store, paymentClient, requestSender, 'en_US'); + registry = createPaymentStrategyRegistry(store, paymentClient, requestSender); jest.spyOn(registryV2, 'get').mockReturnValue(noPaymentDataStrategy); @@ -779,7 +779,7 @@ describe('PaymentStrategyActionCreator', () => { ...state, order: getOrderState(), }); - registry = createPaymentStrategyRegistry(store, paymentClient, requestSender, 'en_US'); + registry = createPaymentStrategyRegistry(store, paymentClient, requestSender); const actionCreator = new PaymentStrategyActionCreator( registry, @@ -813,7 +813,7 @@ describe('PaymentStrategyActionCreator', () => { data: [], }, }); - registry = createPaymentStrategyRegistry(store, paymentClient, requestSender, 'en_US'); + registry = createPaymentStrategyRegistry(store, paymentClient, requestSender); const actionCreator = new PaymentStrategyActionCreator( registry, diff --git a/packages/core/src/payment/payment-strategy-type.ts b/packages/core/src/payment/payment-strategy-type.ts index f02da8a1c1..c5d26f4583 100644 --- a/packages/core/src/payment/payment-strategy-type.ts +++ b/packages/core/src/payment/payment-strategy-type.ts @@ -60,7 +60,6 @@ enum PaymentStrategyType { WE_PAY = 'wepay', WORLDPAYACCESS = 'worldpayaccess', WORLDPAYACCESS_GOOGLE_PAY = 'googlepayworldpayaccess', - MASTERPASS = 'masterpass', STRIPE_GOOGLE_PAY = 'googlepaystripe', SEZZLE = 'sezzle', ZIP = 'zip', diff --git a/packages/core/src/payment/strategies/masterpass/format-locale.spec.ts b/packages/core/src/payment/strategies/masterpass/format-locale.spec.ts deleted file mode 100644 index 76b5c2a262..0000000000 --- a/packages/core/src/payment/strategies/masterpass/format-locale.spec.ts +++ /dev/null @@ -1,35 +0,0 @@ -import formatLocale from './format-locale'; - -describe('formatLocale', () => { - it('fixes the format of locales with a dash', () => { - expect(formatLocale('en-us')).toBe('en_us'); - }); - - it('fills language string with default country code', () => { - expect(formatLocale('FR')).toBe('fr_fr'); - }); - - it('corrects locale with unsupported country for a given language', () => { - expect(formatLocale('zh_mx')).toBe('zh_sg'); - }); - - it('uses a default locale with unsupported languages', () => { - expect(formatLocale('tr')).toBe('en_us'); - }); - - it('uses a default locale with invalid input', () => { - expect(formatLocale('esp_mex')).toBe('en_us'); - }); - - it('only uses the valid part of a string', () => { - expect(formatLocale('es_mx_invalid_data')).toBe('es_mx'); - }); - - it('uses the default country with invalid countries', () => { - expect(formatLocale('es_mex')).toBe('es_es'); - }); - - it('maintains the value of valid locale', () => { - expect(formatLocale('uk_ua')).toBe('uk_ua'); - }); -}); diff --git a/packages/core/src/payment/strategies/masterpass/format-locale.ts b/packages/core/src/payment/strategies/masterpass/format-locale.ts deleted file mode 100644 index 2bfeb74311..0000000000 --- a/packages/core/src/payment/strategies/masterpass/format-locale.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { supportedLocales } from './masterpass-supported-locales'; - -export default function formatLocale(localeLanguage: string): string { - const [language, country] = localeLanguage.replace('-', '_').toLowerCase().split('_'); - const formattedLocale = `${language}_${country}`; - const countryLocales = supportedLocales[language]; - - if (!countryLocales) { - return 'en_us'; - } - - return countryLocales.indexOf(formattedLocale) > -1 ? formattedLocale : countryLocales[0]; -} diff --git a/packages/core/src/payment/strategies/masterpass/get-callback-url.ts b/packages/core/src/payment/strategies/masterpass/get-callback-url.ts deleted file mode 100644 index c2a02abcb3..0000000000 --- a/packages/core/src/payment/strategies/masterpass/get-callback-url.ts +++ /dev/null @@ -1,3 +0,0 @@ -export default function getCallbackUrl(origin: string): string { - return `${window.location.origin}/checkout.php?action=set_external_checkout&provider=masterpass&gateway=stripe&origin=${origin}`; -} diff --git a/packages/core/src/payment/strategies/masterpass/index.ts b/packages/core/src/payment/strategies/masterpass/index.ts deleted file mode 100644 index 1b97fb6b6a..0000000000 --- a/packages/core/src/payment/strategies/masterpass/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export * from './masterpass'; - -export { default as formatLocale } from './format-locale'; -export { default as getCallbackUrl } from './get-callback-url'; -export { default as MasterpassScriptLoader } from './masterpass-script-loader'; -export { default as MasterpassPaymentStrategy } from './masterpass-payment-strategy'; -export { default as MasterpassPaymentInitializeOptions } from './masterpass-payment-initialize-options'; diff --git a/packages/core/src/payment/strategies/masterpass/masterpass-payment-initialize-options.ts b/packages/core/src/payment/strategies/masterpass/masterpass-payment-initialize-options.ts deleted file mode 100644 index 19521be53b..0000000000 --- a/packages/core/src/payment/strategies/masterpass/masterpass-payment-initialize-options.ts +++ /dev/null @@ -1,25 +0,0 @@ -/** - * A set of options that are required to initialize the Masterpass payment method. - * - * ```html - * - *
- * ``` - * - * ```js - * service.initializePayment({ - * methodId: 'masterpass', - * masterpass: { - * walletButton: 'wallet-button' - * }, - * }); - * ``` - */ -export default interface MasterpassPaymentInitializeOptions { - /** - * This walletButton is used to set an event listener, provide an element ID if you want - * users to be able to launch the Masterpass wallet modal by clicking on a button. - * It should be an HTML element. - */ - walletButton?: string; -} diff --git a/packages/core/src/payment/strategies/masterpass/masterpass-payment-strategy.spec.ts b/packages/core/src/payment/strategies/masterpass/masterpass-payment-strategy.spec.ts deleted file mode 100644 index 81085eb406..0000000000 --- a/packages/core/src/payment/strategies/masterpass/masterpass-payment-strategy.spec.ts +++ /dev/null @@ -1,482 +0,0 @@ -import { createClient as createPaymentClient } from '@bigcommerce/bigpay-client'; -import { Action, createAction } from '@bigcommerce/data-store'; -import { createRequestSender } from '@bigcommerce/request-sender'; -import { createScriptLoader } from '@bigcommerce/script-loader'; -import { Observable, of } from 'rxjs'; - -import { getCartState } from '../../../cart/carts.mock'; -import { - CheckoutRequestSender, - CheckoutStore, - CheckoutValidator, - createCheckoutStore, -} from '../../../checkout'; -import { getCheckoutState } from '../../../checkout/checkouts.mock'; -import { getConfigState } from '../../../config/configs.mock'; -import { getCustomerState } from '../../../customer/customers.mock'; -import { getFormFieldsState } from '../../../form/form.mock'; -import { - OrderActionCreator, - OrderActionType, - OrderRequestBody, - OrderRequestSender, -} from '../../../order'; -import { OrderFinalizationNotRequiredError } from '../../../order/errors'; -import { - PaymentActionCreator, - PaymentInitializeOptions, - PaymentMethod, - PaymentRequestSender, -} from '../../../payment'; -import { createSpamProtection, PaymentHumanVerificationHandler } from '../../../spam-protection'; -import { PaymentActionType } from '../../payment-actions'; -import { getMasterpass, getPaymentMethodsState } from '../../payment-methods.mock'; -import PaymentRequestTransformer from '../../payment-request-transformer'; - -import { Masterpass } from './masterpass'; -import { getCallbackUrlMock, getMasterpassScriptMock } from './masterpass.mock'; - -import { MasterpassCheckoutOptions, MasterpassPaymentStrategy, MasterpassScriptLoader } from './'; - -describe('MasterpassPaymentStrategy', () => { - let strategy: MasterpassPaymentStrategy; - let orderRequestSender: OrderRequestSender; - let store: CheckoutStore; - let orderActionCreator: OrderActionCreator; - let paymentActionCreator: PaymentActionCreator; - let scriptLoader: MasterpassScriptLoader; - let initOptions: PaymentInitializeOptions; - let paymentMethodMock: PaymentMethod; - let masterpassScript: Masterpass; - - beforeEach(() => { - initOptions = { - methodId: 'masterpass', - masterpass: { - walletButton: 'masterpassWalletButton', - }, - }; - - orderRequestSender = new OrderRequestSender(createRequestSender()); - - store = createCheckoutStore({ - checkout: getCheckoutState(), - config: getConfigState(), - customer: getCustomerState(), - cart: getCartState(), - formFields: getFormFieldsState(), - paymentMethods: getPaymentMethodsState(), - }); - - jest.spyOn(store, 'dispatch').mockReturnValue(Promise.resolve(store.getState())); - - paymentMethodMock = getMasterpass(); - - jest.spyOn(store.getState().paymentMethods, 'getPaymentMethod').mockReturnValue( - paymentMethodMock, - ); - - const checkoutValidator = new CheckoutValidator( - new CheckoutRequestSender(createRequestSender()), - ); - - orderActionCreator = new OrderActionCreator(orderRequestSender, checkoutValidator); - - const paymentRequestSender = new PaymentRequestSender(createPaymentClient()); - - paymentActionCreator = new PaymentActionCreator( - paymentRequestSender, - orderActionCreator, - new PaymentRequestTransformer(), - new PaymentHumanVerificationHandler(createSpamProtection(createScriptLoader())), - ); - - scriptLoader = new MasterpassScriptLoader(createScriptLoader()); - masterpassScript = getMasterpassScriptMock(); - jest.spyOn(scriptLoader, 'load').mockReturnValue(Promise.resolve(masterpassScript)); - // TODO: remove ts-ignore and update test with related type (PAYPAL-4383) - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - jest.spyOn(masterpassScript, 'checkout').mockReturnValue(true); - - // Strategy - strategy = new MasterpassPaymentStrategy( - store, - orderActionCreator, - paymentActionCreator, - scriptLoader, - 'en-US', - ); - }); - - describe('#initialize()', () => { - it('throws an exception if payment method cannot be found', () => { - jest.spyOn(store.getState().paymentMethods, 'getPaymentMethod').mockReturnValue( - undefined, - ); - - const error = - 'Unable to proceed because payment method data is unavailable or not properly configured.'; - - expect(() => strategy.initialize(initOptions)).toThrow(error); - }); - - it('throws an exception if masterpass options is not passed', () => { - initOptions.masterpass = undefined; - paymentMethodMock.initializationData = { - checkoutId: 'checkout-id', - }; - - const error = - 'Unable to initialize payment because "options.masterpass" argument is not provided.'; - - return expect(strategy.initialize(initOptions)).rejects.toThrow(error); - }); - - it('loads masterpass script with correct locale', async () => { - // Strategy - strategy = new MasterpassPaymentStrategy( - store, - orderActionCreator, - paymentActionCreator, - scriptLoader, - 'FR', - ); - - paymentMethodMock.initializationData = { - checkoutId: 'checkout-id', - isMasterpassSrcEnabled: false, - }; - await strategy.initialize(initOptions); - - expect(scriptLoader.load).toHaveBeenLastCalledWith({ - useMasterpassSrc: false, - language: 'fr_fr', - testMode: false, - checkoutId: 'checkout-id', - }); - }); - - it('loads masterpass script with default locale for unsupported country code', async () => { - // Strategy - strategy = new MasterpassPaymentStrategy( - store, - orderActionCreator, - paymentActionCreator, - scriptLoader, - 'es_fr', - ); - - paymentMethodMock.initializationData = { - checkoutId: 'checkout-id', - isMasterpassSrcEnabled: false, - }; - await strategy.initialize(initOptions); - - expect(scriptLoader.load).toHaveBeenLastCalledWith({ - useMasterpassSrc: false, - language: 'es_es', - testMode: false, - checkoutId: 'checkout-id', - }); - }); - - it('loads masterpass script with default locale for unsupported language', async () => { - // Strategy - strategy = new MasterpassPaymentStrategy( - store, - orderActionCreator, - paymentActionCreator, - scriptLoader, - 'tr', - ); - - paymentMethodMock.initializationData = { - checkoutId: 'checkout-id', - isMasterpassSrcEnabled: false, - }; - await strategy.initialize(initOptions); - - expect(scriptLoader.load).toHaveBeenLastCalledWith({ - useMasterpassSrc: false, - language: 'en_us', - testMode: false, - checkoutId: 'checkout-id', - }); - }); - - it('loads masterpass script with correct locale for supported language and country', async () => { - // Strategy - strategy = new MasterpassPaymentStrategy( - store, - orderActionCreator, - paymentActionCreator, - scriptLoader, - 'zh_hk', - ); - - paymentMethodMock.initializationData = { - checkoutId: 'checkout-id', - isMasterpassSrcEnabled: false, - }; - await strategy.initialize(initOptions); - - expect(scriptLoader.load).toHaveBeenLastCalledWith({ - useMasterpassSrc: false, - language: 'zh_hk', - testMode: false, - checkoutId: 'checkout-id', - }); - }); - - it('loads masterpass script with correct locale when locale contains "-" character', async () => { - paymentMethodMock.initializationData = { - checkoutId: 'checkout-id', - isMasterpassSrcEnabled: false, - }; - await strategy.initialize(initOptions); - - expect(scriptLoader.load).toHaveBeenLastCalledWith({ - useMasterpassSrc: false, - language: 'en_us', - testMode: false, - checkoutId: 'checkout-id', - }); - }); - - describe('on click button handler', () => { - let payload: MasterpassCheckoutOptions; - let walletButton: HTMLElement; - - beforeEach(() => { - paymentMethodMock.initializationData = { - allowedCardTypes: ['visa', 'amex', 'master'], - checkoutId: 'checkout-id', - isMasterpassSrcEnabled: false, - }; - - payload = { - allowedCardTypes: ['visa', 'amex', 'master'], - amount: '190.00', - cartId: 'b20deef40f9699e48671bbc3fef6ca44dc80e3c7', - checkoutId: 'checkout-id', - currency: 'USD', - callbackUrl: getCallbackUrlMock(), - }; - - walletButton = document.createElement('a'); - jest.spyOn(document, 'getElementById').mockReturnValue(walletButton); - }); - - it('loads the script and calls the checkout when the wallet button is clicked', async () => { - await strategy.initialize(initOptions); - - expect(scriptLoader.load).toHaveBeenLastCalledWith({ - useMasterpassSrc: false, - language: 'en_us', - testMode: false, - checkoutId: 'checkout-id', - }); - - walletButton.click(); - - expect(masterpassScript.checkout).toHaveBeenCalledWith(payload); - }); - - it('loads the script in test mode, and calls the checkout when the wallet button is clicked', async () => { - paymentMethodMock.config.testMode = true; - await strategy.initialize(initOptions); - - expect(scriptLoader.load).toHaveBeenLastCalledWith({ - useMasterpassSrc: false, - language: 'en_us', - testMode: true, - checkoutId: 'checkout-id', - }); - - walletButton.click(); - - expect(masterpassScript.checkout).toHaveBeenCalled(); - }); - - it('does not call the checkout method when wallet button is not set on the init options', async () => { - paymentMethodMock.config.testMode = true; - initOptions.masterpass = {}; - await strategy.initialize(initOptions); - - expect(scriptLoader.load).toHaveBeenLastCalledWith({ - useMasterpassSrc: false, - language: 'en_us', - testMode: true, - checkoutId: 'checkout-id', - }); - - walletButton.click(); - - expect(masterpassScript.checkout).not.toHaveBeenCalled(); - }); - }); - - describe('with payment data', () => { - beforeEach(() => { - paymentMethodMock.initializationData = { - cardData: { - expMonth: '10', - expYear: '20', - accountMask: '4444', - cardType: 'MasterCard', - }, - gateway: 'stripe', - paymentData: { nonce: 'src_foobar1234567' }, - }; - }); - - it('does not load the masterpass script', async () => { - await strategy.initialize(initOptions); - - expect(scriptLoader.load).not.toHaveBeenLastCalledWith(true); - expect(masterpassScript.checkout).not.toHaveBeenCalled(); - }); - }); - }); - - describe('#execute', () => { - let payload: OrderRequestBody; - let submitOrderAction: Observable; - let submitPaymentAction: Observable; - - beforeEach(() => { - paymentMethodMock.initializationData = { - cardData: { - expMonth: '10', - expYear: '20', - accountMask: '4444', - cardType: 'MasterCard', - }, - gateway: 'stripe', - paymentData: { nonce: 'src_foobar1234567' }, - }; - - payload = { - payment: { - methodId: 'masterpass', - }, - useStoreCredit: true, - }; - - submitOrderAction = of(createAction(OrderActionType.SubmitOrderRequested)); - // TODO: remove ts-ignore and update test with related type (PAYPAL-4383) - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - orderActionCreator.submitOrder = jest.fn(() => submitOrderAction); - - submitPaymentAction = of(createAction(PaymentActionType.SubmitPaymentRequested)); - // TODO: remove ts-ignore and update test with related type (PAYPAL-4383) - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - paymentActionCreator.submitPayment = jest.fn(() => submitPaymentAction); - }); - - it('fails to submit order when payment is not provided', () => { - delete payload.payment; - - const error = - 'Unable to submit payment because "payload.payment" argument is not provided.'; - - expect(() => strategy.execute(payload)).toThrow(error); - }); - - it('throws an exception if payment data is missing', () => { - paymentMethodMock.initializationData.paymentData = undefined; - - const error = - 'Unable to proceed because payment method data is unavailable or not properly configured.'; - - expect(() => strategy.execute(payload)).toThrow(error); - }); - - it('throws an exception when the gateway is not provided', async () => { - paymentMethodMock.initializationData.gateway = undefined; - - const error = - 'Unable to proceed because payment method data is unavailable or not properly configured.'; - - await strategy.initialize(initOptions); - - expect(() => strategy.execute(payload)).toThrow(error); - }); - - it('throws an exception when the paymentData is not provided', async () => { - paymentMethodMock.initializationData.paymentData = undefined; - - const error = - 'Unable to proceed because "paymentMethod.initializationData.paymentData" argument is not provided.'; - - await strategy.initialize(initOptions); - - expect(() => strategy.execute(payload)).toThrow(error); - }); - - it('creates the order and execute the payment', async () => { - await strategy.initialize(initOptions); - await strategy.execute(payload); - - const submitPaymentArgs = { - methodId: 'masterpass', - paymentData: { nonce: 'src_foobar1234567' }, - }; - const order = { useStoreCredit: payload.useStoreCredit }; - - expect(orderActionCreator.submitOrder).toHaveBeenCalledWith(order, undefined); - expect(paymentActionCreator.submitPayment).toHaveBeenCalledWith(submitPaymentArgs); - expect(store.dispatch).toHaveBeenCalledWith(submitOrderAction); - }); - }); - - describe('#deinitialize()', () => { - let walletButton: HTMLElement; - - beforeEach(() => { - walletButton = document.createElement('a'); - jest.spyOn(walletButton, 'removeEventListener'); - jest.spyOn(document, 'getElementById').mockReturnValue(walletButton); - - paymentMethodMock.initializationData = { - allowedCardTypes: ['visa', 'amex', 'mastercard'], - checkoutId: 'checkout-id', - }; - - const submitOrderAction = of(createAction(OrderActionType.SubmitOrderRequested)); - - // TODO: remove ts-ignore and update test with related type (PAYPAL-4383) - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - orderActionCreator.submitOrder = jest.fn(() => submitOrderAction); - }); - - it('remove event listeners on wallet button', async () => { - await strategy.initialize(initOptions); - await strategy.deinitialize(); - - expect(walletButton.removeEventListener).toHaveBeenCalled(); - }); - - it('does not remove event listeners on wallet button if the id of the button was not passed on initialize options', async () => { - initOptions.masterpass = {}; - await strategy.initialize(initOptions); - await strategy.deinitialize(); - - expect(walletButton.removeEventListener).not.toHaveBeenCalled(); - }); - }); - - describe('#finalize()', () => { - it('throws error to inform that order finalization is not required', async () => { - try { - await strategy.finalize(); - } catch (error) { - expect(error).toBeInstanceOf(OrderFinalizationNotRequiredError); - } - }); - }); -}); diff --git a/packages/core/src/payment/strategies/masterpass/masterpass-payment-strategy.ts b/packages/core/src/payment/strategies/masterpass/masterpass-payment-strategy.ts deleted file mode 100644 index 3b0eb8c0fa..0000000000 --- a/packages/core/src/payment/strategies/masterpass/masterpass-payment-strategy.ts +++ /dev/null @@ -1,170 +0,0 @@ -import { bindDecorator as bind } from '@bigcommerce/checkout-sdk/utility'; - -import { CheckoutStore, InternalCheckoutSelectors } from '../../../checkout'; -import { - InvalidArgumentError, - MissingDataError, - MissingDataErrorType, -} from '../../../common/error/errors'; -import { OrderActionCreator, OrderRequestBody } from '../../../order'; -import { OrderFinalizationNotRequiredError } from '../../../order/errors'; -import PaymentActionCreator from '../../payment-action-creator'; -import PaymentMethod from '../../payment-method'; -import { PaymentInitializeOptions, PaymentRequestOptions } from '../../payment-request-options'; -import PaymentStrategy from '../payment-strategy'; - -import formatLocale from './format-locale'; -import getCallbackUrl from './get-callback-url'; -import { Masterpass, MasterpassCheckoutOptions } from './masterpass'; -import MasterpassScriptLoader from './masterpass-script-loader'; - -export default class MasterpassPaymentStrategy implements PaymentStrategy { - private _masterpassClient?: Masterpass; - private _paymentMethod?: PaymentMethod; - private _walletButton?: HTMLElement; - - constructor( - private _store: CheckoutStore, - private _orderActionCreator: OrderActionCreator, - private _paymentActionCreator: PaymentActionCreator, - private _masterpassScriptLoader: MasterpassScriptLoader, - private _locale: string, - ) {} - - initialize(options: PaymentInitializeOptions): Promise { - const { methodId } = options; - - this._paymentMethod = this._store.getState().paymentMethods.getPaymentMethod(methodId); - - if (!this._paymentMethod) { - throw new MissingDataError(MissingDataErrorType.MissingPaymentMethod); - } - - const masterpassScriptLoaderParams = { - useMasterpassSrc: this._paymentMethod.initializationData.isMasterpassSrcEnabled, - language: formatLocale(this._locale), - testMode: this._paymentMethod.config.testMode, - checkoutId: this._paymentMethod.initializationData.checkoutId, - }; - - return this._masterpassScriptLoader - .load(masterpassScriptLoaderParams) - .then((masterpass) => { - this._masterpassClient = masterpass; - - if (!options.masterpass) { - throw new InvalidArgumentError( - 'Unable to initialize payment because "options.masterpass" argument is not provided.', - ); - } - - const walletButton = - options.masterpass.walletButton && - document.getElementById(options.masterpass.walletButton); - - if (walletButton) { - this._walletButton = walletButton; - this._walletButton.addEventListener('click', this._handleWalletButtonClick); - } - - return this._store.getState(); - }); - } - - deinitialize(): Promise { - this._paymentMethod = undefined; - - if (this._walletButton) { - this._walletButton.removeEventListener('click', this._handleWalletButtonClick); - } - - this._walletButton = undefined; - this._masterpassClient = undefined; - - return Promise.resolve(this._store.getState()); - } - - execute( - payload: OrderRequestBody, - options?: PaymentRequestOptions, - ): Promise { - const { payment } = payload; - const order = { useStoreCredit: payload.useStoreCredit }; - - if (!payment) { - throw new InvalidArgumentError( - 'Unable to submit payment because "payload.payment" argument is not provided.', - ); - } - - if ( - !this._paymentMethod || - !this._paymentMethod.initializationData || - !this._paymentMethod.initializationData.gateway - ) { - throw new MissingDataError(MissingDataErrorType.MissingPaymentMethod); - } - - // TODO: Refactor the API endpoint to return nonce in the right place. - const paymentData = this._paymentMethod.initializationData.paymentData; - - // TODO: Redirect to Masterpass if nonce has not been generated yet. And then finalise the order when the shopper is redirected back to the checkout page. - if (!paymentData) { - throw new InvalidArgumentError( - 'Unable to proceed because "paymentMethod.initializationData.paymentData" argument is not provided.', - ); - } - - return this._store - .dispatch(this._orderActionCreator.submitOrder(order, options)) - .then(() => - this._store.dispatch( - this._paymentActionCreator.submitPayment({ ...payment, paymentData }), - ), - ); - } - - finalize(): Promise { - return Promise.reject(new OrderFinalizationNotRequiredError()); - } - - private _createMasterpassPayload(): MasterpassCheckoutOptions { - const state = this._store.getState(); - const checkout = state.checkout.getCheckout(); - const storeConfig = state.config.getStoreConfig(); - - if (!checkout) { - throw new MissingDataError(MissingDataErrorType.MissingCheckout); - } - - if (!storeConfig) { - throw new MissingDataError(MissingDataErrorType.MissingCheckoutConfig); - } - - if (!this._paymentMethod || !this._paymentMethod.initializationData) { - throw new MissingDataError(MissingDataErrorType.MissingPaymentMethod); - } - - return { - checkoutId: this._paymentMethod.initializationData.checkoutId, - allowedCardTypes: this._paymentMethod.initializationData.allowedCardTypes, - amount: checkout.subtotal.toFixed(2), - currency: storeConfig.currency.code, - cartId: checkout.cart.id, - callbackUrl: getCallbackUrl('checkout'), - }; - } - - @bind - private _handleWalletButtonClick(event: Event) { - event.preventDefault(); - - if (!this._masterpassClient) { - return; - } - - const payload = this._createMasterpassPayload(); - - this._masterpassClient.checkout(payload); - } -} diff --git a/packages/core/src/payment/strategies/masterpass/masterpass-script-loader.ts b/packages/core/src/payment/strategies/masterpass/masterpass-script-loader.ts deleted file mode 100644 index 3146643590..0000000000 --- a/packages/core/src/payment/strategies/masterpass/masterpass-script-loader.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { ScriptLoader } from '@bigcommerce/script-loader'; - -import { PaymentMethodClientUnavailableError } from '../../errors'; - -import { Masterpass, MasterpassHostWindow } from './masterpass'; - -interface MasterpassScriptLoaderParams { - useMasterpassSrc: boolean; - language: string; - testMode?: boolean; - checkoutId?: string; -} - -export default class MasterpassScriptLoader { - constructor( - private _scriptLoader: ScriptLoader, - public _window: MasterpassHostWindow = window, - ) {} - - async load({ - useMasterpassSrc, - language, - testMode, - checkoutId, - }: MasterpassScriptLoaderParams): Promise { - if (useMasterpassSrc) { - const subdomain = testMode ? 'sandbox.' : ''; - const params = [`locale=${language}`, `checkoutid=${checkoutId}`]; - - const sourceUrl = [ - `https://${subdomain}src.mastercard.com/srci/integration/merchant.js`, - params.join('&'), - ].join('?'); - - await this._scriptLoader.loadScript(sourceUrl); - - if (!this._window.masterpass) { - throw new PaymentMethodClientUnavailableError(); - } - - return this._window.masterpass; - } - - await this._scriptLoader.loadScript( - `//${testMode ? 'sandbox.' : ''}masterpass.com/integration/merchant.js`, - ); - - if (!this._window.masterpass) { - throw new PaymentMethodClientUnavailableError(); - } - - return this._window.masterpass; - } -} diff --git a/packages/core/src/payment/strategies/masterpass/masterpass-supported-locales.ts b/packages/core/src/payment/strategies/masterpass/masterpass-supported-locales.ts deleted file mode 100644 index ec7cfd4f02..0000000000 --- a/packages/core/src/payment/strategies/masterpass/masterpass-supported-locales.ts +++ /dev/null @@ -1,35 +0,0 @@ -export const supportedLocales: { [language: string]: string[] } = { - es: ['es_es', 'es_mx', 'es_pe', 'es_co', 'es_ar', 'es_cl'], - en: [ - 'en_us', - 'en_gb', - 'en_ca', - 'en_es', - 'en_fr', - 'en_ie', - 'en_sg', - 'en_au', - 'en_nz', - 'en_my', - 'en_hk', - 'en_th', - 'en_ae', - 'en_sa', - 'en_qa', - 'en_kw', - 'en_za', - ], - pt: ['pt_br'], - zu: ['zu_za'], - ar: ['ar_sa', 'ar_ae', 'ar_qa', 'ar_kw'], - zh: ['zh_sg', 'zh_hk'], - ms: ['ms_my'], - uk: ['uk_ua'], - sv: ['sv_se'], - hr: ['hr_hr'], - pl: ['pl_pl'], - nl: ['nl_be'], - it: ['it_it'], - de: ['de_de'], - fr: ['fr_fr', 'fr_ca'], -}; diff --git a/packages/core/src/payment/strategies/masterpass/masterpass.mock.ts b/packages/core/src/payment/strategies/masterpass/masterpass.mock.ts deleted file mode 100644 index ca2fc9ae4f..0000000000 --- a/packages/core/src/payment/strategies/masterpass/masterpass.mock.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Masterpass } from './masterpass'; - -export function getMasterpassScriptMock(): Masterpass { - return { - checkout: jest.fn(), - }; -} - -export function getCallbackUrlMock(): string { - return 'http://localhost/checkout.php?action=set_external_checkout&provider=masterpass&gateway=stripe&origin=checkout'; -} diff --git a/packages/core/src/payment/strategies/masterpass/masterpass.ts b/packages/core/src/payment/strategies/masterpass/masterpass.ts deleted file mode 100644 index bf3c6533a2..0000000000 --- a/packages/core/src/payment/strategies/masterpass/masterpass.ts +++ /dev/null @@ -1,54 +0,0 @@ -/** - * The name of the masterpass script that is hosted by the browser window - */ -export interface MasterpassHostWindow extends Window { - /** - * Use this to refer to the loaded masterpass client script instance - */ - masterpass?: Masterpass; -} - -/** - * Methods loaded by the masterpass script - */ -export interface Masterpass { - /** - * Proceed to checkout with the given parameters - */ - checkout(options: MasterpassCheckoutOptions): void; -} - -/** - * Payload that must be passed to masterpass script to start a checkout - */ -export interface MasterpassCheckoutOptions { - /** - * Merchant checkout identifier received when merchant onboarded for masterpass - */ - checkoutId: string; - /** - * Card types accepted by merchant - */ - allowedCardTypes: string[]; - /** - * Shopping cart subtotal - */ - amount: string; - /** - * Currency code for cart - */ - currency: string; - /** - * Merchant Cart identifier - */ - cartId: string; - /** - * This optional parameter can be used to override the callbackUrl specified in the Merchant Portal. - */ - callbackUrl?: string; - - /** - * Set to "true" if you don't require shipping address for checkout; default is false - */ - suppressShippingAddress?: boolean; -}