diff --git a/examples/apple-pay/index.html b/examples/apple-pay/index.html index 8b853622..ba0f3256 100644 --- a/examples/apple-pay/index.html +++ b/examples/apple-pay/index.html @@ -122,14 +122,6 @@

Apple pay

* Refer to `examples/return.html` for more details. */ returnUrl: 'http://return', - - paymentMethodSettings: { - /** - * Enables applePayWindowOpened to handle edge cases related to external window openings; - * set to false by default. - */ - enableExternalWindowOpenMessage: true, - }, }); } diff --git a/src/core/form/form-configuration.interface.ts b/src/core/form/form-configuration.interface.ts index 0f913b50..91bf5658 100644 --- a/src/core/form/form-configuration.interface.ts +++ b/src/core/form/form-configuration.interface.ts @@ -1,6 +1,5 @@ import { cardPid } from '../../features/headless-checkout/web-components/payment-methods/variables'; import { XpsBoolean } from '../xps-boolean.enum'; -import { PaymentConfigurationApplePaySettings } from './types/apple-pay-form-configuration.interface'; import { PaymentConfigurationCreditCardSettings } from './types/credit-card-form-configuration.interface'; import { PaymentConfigurationGooglePaySettings } from './types/google-pay-form-configuration.interface'; @@ -27,5 +26,4 @@ interface PaymentConfigurationWithGeneralSettings export type FormConfiguration = | PaymentConfigurationCreditCardSettings | PaymentConfigurationGooglePaySettings - | PaymentConfigurationApplePaySettings | PaymentConfigurationWithGeneralSettings; diff --git a/src/core/form/types/apple-pay-form-configuration.interface.ts b/src/core/form/types/apple-pay-form-configuration.interface.ts deleted file mode 100644 index 746705e2..00000000 --- a/src/core/form/types/apple-pay-form-configuration.interface.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { BasePaymentConfiguration } from '../form-configuration.interface'; -import { applePayPid } from '../../../features/headless-checkout/web-components/payment-methods/variables'; - -export type PaymentConfigurationApplePaySettings = BasePaymentConfiguration & { - paymentMethodId: typeof applePayPid; - paymentMethodSettings: { - enableExternalWindowOpenMessage?: boolean; - }; -}; diff --git a/src/core/form/types/is-apple-pay-settings.guard.ts b/src/core/form/types/is-apple-pay-settings.guard.ts deleted file mode 100644 index fdb72089..00000000 --- a/src/core/form/types/is-apple-pay-settings.guard.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { FormConfiguration } from '../form-configuration.interface'; -import { applePayPid } from '../../../features/headless-checkout/web-components/payment-methods/variables'; -import { PaymentConfigurationApplePaySettings } from './apple-pay-form-configuration.interface'; - -export const isApplePaySettingsGuard = ( - settings: FormConfiguration, -): settings is PaymentConfigurationApplePaySettings => { - return settings.paymentMethodId === applePayPid; -}; diff --git a/src/core/guards/open-external-window.guard.ts b/src/core/guards/open-external-window.guard.ts deleted file mode 100644 index bc64417f..00000000 --- a/src/core/guards/open-external-window.guard.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Message } from '../message.interface'; -import { isEventMessage } from './event-message.guard'; -import { EventName } from '../event-name.enum'; - -export const isOpenExternalWindowMessage = ( - messageData: unknown, -): messageData is Message<{ error: string } | null | undefined> => { - if (isEventMessage(messageData)) { - return messageData.name === EventName.openExternalWindow; - } - return false; -}; diff --git a/src/features/headless-checkout/headless-checkout.ts b/src/features/headless-checkout/headless-checkout.ts index 4891f0d1..288f4216 100644 --- a/src/features/headless-checkout/headless-checkout.ts +++ b/src/features/headless-checkout/headless-checkout.ts @@ -42,8 +42,6 @@ import { InitialOptions } from './initial-options.interface'; import { submitHandler } from './post-messages-handlers/submit/submit.handler'; import { externalInputChangeValueHandler } from './post-messages-handlers/external-input-change-value/external-input-change-value.handler'; import { isGooglePaySettingsGuard } from '../../core/form/types/is-google-pay-settings.guard'; -import { isApplePaySettingsGuard } from '../../core/form/types/is-apple-pay-settings.guard'; -import { PaymentConfigurationApplePaySettings } from '../../core/form/types/apple-pay-form-configuration.interface'; import { PaymentConfigurationGooglePaySettings } from '../../core/form/types/google-pay-form-configuration.interface'; @singleton() @@ -507,11 +505,6 @@ export class HeadlessCheckout { this.getDefaultGooglePaySettings(configuration); } - if (isApplePaySettingsGuard(configuration)) { - configurationWithDefaultValues.paymentMethodSettings = - this.getDefaultApplePaySettings(configuration); - } - return configurationWithDefaultValues; } @@ -531,21 +524,4 @@ export class HeadlessCheckout { true, }; } - - private getDefaultApplePaySettings( - configuration: PaymentConfigurationApplePaySettings, - ): PaymentConfigurationApplePaySettings['paymentMethodSettings'] { - if (!configuration.paymentMethodSettings) { - return { - enableExternalWindowOpenMessage: false, - }; - } - - return { - ...configuration.paymentMethodSettings, - enableExternalWindowOpenMessage: - configuration.paymentMethodSettings?.enableExternalWindowOpenMessage ?? - false, - }; - } } diff --git a/src/features/headless-checkout/post-messages-handlers/open-external-window.handler.ts b/src/features/headless-checkout/post-messages-handlers/open-external-window.handler.ts deleted file mode 100644 index 98e2e704..00000000 --- a/src/features/headless-checkout/post-messages-handlers/open-external-window.handler.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Handler } from '../../../core/post-messages-client/handler.type'; -import { Message } from '../../../core/message.interface'; -import { isOpenExternalWindowMessage } from '../../../core/guards/open-external-window.guard'; - -export const openExternalWindowHandler: Handler< - { error: string } | null | undefined -> = ( - message: Message, -): { - isHandled: boolean; - value: null; -} | null => { - if (!isOpenExternalWindowMessage(message)) { - return null; - } - - return { - isHandled: true, - value: null, - }; -}; diff --git a/src/features/headless-checkout/web-components/apple-pay/apple-pay.component.ts b/src/features/headless-checkout/web-components/apple-pay/apple-pay.component.ts index d3de633f..3ba1899a 100644 --- a/src/features/headless-checkout/web-components/apple-pay/apple-pay.component.ts +++ b/src/features/headless-checkout/web-components/apple-pay/apple-pay.component.ts @@ -18,20 +18,18 @@ import { applePayQrClosedHandler } from '../../post-messages-handlers/apple-pay/ import { applePayQrOpenedHandler } from '../../post-messages-handlers/apple-pay/apple-pay-qr-opened.handler'; import { applePayButtonClickedHandler } from '../../post-messages-handlers/apple-pay/apple-pay-button-clicked.handler'; import { closeExternalWindowHandler } from '../../post-messages-handlers/close-external-window.handler'; -import { openExternalWindowHandler } from '../../post-messages-handlers/open-external-window.handler'; -import { isApplePaySettingsGuard } from '../../../../core/form/types/is-apple-pay-settings.guard'; export class ApplePayComponent extends SecureComponentAbstract { protected componentName: string | null = 'pages/apple-pay'; private readonly applePayWindowName = 'HeadlessCheckout_PayStation_ApplePay'; - private readonly externalWindowTimeoutMs = 5000; private readonly headlessCheckout: HeadlessCheckout; private readonly formSpy: FormSpy; private readonly window: Window; private applePayWindow?: Window | null; private readonly subscriptions: Array<() => void> = []; - private externalWindowTimeoutId?: number; - private isWaitingElementShown = false; + // eslint-disable-next-line no-magic-numbers + private readonly externalWindowCheckIntervalMs = 500; + private externalWindowCheckIntervalId?: ReturnType; public constructor() { super(); @@ -110,20 +108,6 @@ export class ApplePayComponent extends SecureComponentAbstract { ), ); - if (this.isExternalWindowOpenMessageEnabled) { - this.subscriptions.push( - this.headlessCheckout.events.onCoreEvent( - EventName.openExternalWindow, - openExternalWindowHandler, - () => { - this.notifyExternalWindowOpened(); - this.clearExternalWindowTimeout(); - this.setupWaitingPayment(true); - }, - ), - ); - } - this.subscriptions.push( this.headlessCheckout.events.onCoreEvent( EventName.applePayButtonClicked, @@ -148,9 +132,7 @@ export class ApplePayComponent extends SecureComponentAbstract { protected disconnectedCallback(): void { this.subscriptions.forEach((unsubscribe) => unsubscribe()); - if (this.isExternalWindowOpenMessageEnabled) { - this.clearExternalWindowTimeout(); - } + this.stopWindowCheckInterval(); } protected getHtml(): string { @@ -213,9 +195,6 @@ export class ApplePayComponent extends SecureComponentAbstract { } private drawWaitingElement(): void { - if (this.isWaitingElementShown) { - return; - } const waitingProcessingWrapper = document.createElement('div'); waitingProcessingWrapper.classList.add(waitingProcessingClassname); waitingProcessingWrapper.innerHTML = getWaitingProcessingTemplate( @@ -223,7 +202,6 @@ export class ApplePayComponent extends SecureComponentAbstract { i18next.t('status.processing.description'), ); this.append(waitingProcessingWrapper); - this.isWaitingElementShown = true; } private removeWaitingElement(): void { @@ -233,7 +211,6 @@ export class ApplePayComponent extends SecureComponentAbstract { if (waitingProcessingWrapper) { waitingProcessingWrapper.remove(); } - this.isWaitingElementShown = false; } private openRedirectPage(redirectUrl: string): void { @@ -242,15 +219,34 @@ export class ApplePayComponent extends SecureComponentAbstract { redirectUrl, this.applePayWindowName, ); - if (this.isExternalWindowOpenMessageEnabled) { - this.startExternalWindowTimeout(); + + this.startWindowCheckInterval(); + } + + private startWindowCheckInterval(): void { + this.stopWindowCheckInterval(); + + this.externalWindowCheckIntervalId = setInterval(() => { + if (this.applePayWindow?.closed) { + this.stopWindowCheckInterval(); + this.onApplePayWindowClosed(); + } + }, this.externalWindowCheckIntervalMs); + } + + private stopWindowCheckInterval(): void { + if (this.externalWindowCheckIntervalId) { + clearInterval(this.externalWindowCheckIntervalId); + this.externalWindowCheckIntervalId = undefined; } } + private onApplePayWindowClosed(): void { + this.destroyApplePayWindow(true); + } + private destroyApplePayWindow(stopLoading?: boolean): void { - if (this.isExternalWindowOpenMessageEnabled) { - this.clearExternalWindowTimeout(); - } + this.stopWindowCheckInterval(); this.dispatchEvent(new CustomEvent(EventName.applePayWindowClosed)); this.window.focus(); @@ -263,23 +259,6 @@ export class ApplePayComponent extends SecureComponentAbstract { } } - private startExternalWindowTimeout(): void { - this.clearExternalWindowTimeout(); - const timeoutId = this.window.setTimeout(() => { - if (this.externalWindowTimeoutId === timeoutId) { - this.setupWaitingPayment(false); - } - }, this.externalWindowTimeoutMs); - this.externalWindowTimeoutId = timeoutId; - } - - private clearExternalWindowTimeout(): void { - if (this.externalWindowTimeoutId !== undefined) { - this.window.clearTimeout(this.externalWindowTimeoutId); - this.externalWindowTimeoutId = undefined; - } - } - private addStylesForQrCode(): void { const iframe = this.querySelector('#apple-pay-iframe'); @@ -295,25 +274,4 @@ export class ApplePayComponent extends SecureComponentAbstract { (iframe as HTMLElement).style.removeProperty('top'); (iframe as HTMLElement).style.removeProperty('left'); } - - private notifyExternalWindowOpened(): void { - this.dispatchEvent(new CustomEvent(EventName.applePayWindowOpened)); - } - - private get isExternalWindowOpenMessageEnabled(): boolean { - const configuration = this.headlessCheckout.formConfiguration; - - if (!configuration) { - return false; - } - - if (!isApplePaySettingsGuard(configuration)) { - return false; - } - - return ( - configuration.paymentMethodSettings?.enableExternalWindowOpenMessage ?? - false - ); - } } diff --git a/src/features/headless-checkout/web-components/payment-methods/variables.ts b/src/features/headless-checkout/web-components/payment-methods/variables.ts index f8b05337..1757a655 100644 --- a/src/features/headless-checkout/web-components/payment-methods/variables.ts +++ b/src/features/headless-checkout/web-components/payment-methods/variables.ts @@ -2,5 +2,3 @@ export const cardPid = 1380 as const; // eslint-disable-next-line @typescript-eslint/no-magic-numbers export const googlePayPid = 3431 as const; -// eslint-disable-next-line @typescript-eslint/no-magic-numbers -export const applePayPid = 3175 as const;