Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions src/core/environment/environment.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { singleton } from 'tsyringe';
import {
headlessCheckoutAppUrl,
headlessCheckoutSandboxAppUrl,
} from '../../features/headless-checkout/environment';

@singleton()
export class EnvironmentService {
private _isSandbox = false;

public set isSandbox(value: boolean) {
this._isSandbox = value;
}

public get isSandbox(): boolean {
return this._isSandbox;
}

public getHeadlessCheckoutAppUrl(): string {
return this._isSandbox
? headlessCheckoutSandboxAppUrl
: headlessCheckoutAppUrl;
}
}

Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import { container } from 'tsyringe';
import { WebComponentAbstract } from '../web-component.abstract';
import { headlessCheckoutAppUrl } from '../../../features/headless-checkout/environment';
import { EnvironmentService } from '../../environment/environment.service';

export abstract class SecureComponentAbstract extends WebComponentAbstract {
protected componentName: string | null = null;
protected environmentService: EnvironmentService;

protected constructor() {
super();
this.environmentService = container.resolve(EnvironmentService);
}

protected getSecureHtml(): string {
if (!this.componentName) {
throw new Error('Component name is required');
}

return `<iframe src='${headlessCheckoutAppUrl}/secure-components/${this.componentName}'></iframe>`;
const appUrl = this.environmentService.getHeadlessCheckoutAppUrl();
return `<iframe src='${appUrl}/secure-components/${this.componentName}'></iframe>`;
}
}
3 changes: 3 additions & 0 deletions src/features/headless-checkout/environment.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
export const headlessCheckoutAppUrl =
'https://secure.xsolla.com/headless-checkout';

export const headlessCheckoutSandboxAppUrl =
'https://sandbox-secure.xsolla.com/headless-checkout';

export const cdnIconsUrl =
'https://cdn.xsolla.net/headless-checkout-prod/assets/icons';
10 changes: 10 additions & 0 deletions src/features/headless-checkout/headless-checkout.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { FormStatus } from '../../core/status/form-status.enum';
import { noopStub } from '../../tests/stubs/noop.stub';
import { headlessCheckoutAppUrl } from './environment';
import { ThemesLoader } from '../../core/customization/themes-loader';
import { EnvironmentService } from '../../core/environment/environment.service';
import { submitHandler } from './post-messages-handlers/submit/submit.handler';

const mockMessage: Message = {
Expand Down Expand Up @@ -43,6 +44,7 @@ describe('HeadlessCheckout', () => {
let postMessagesClient: PostMessagesClient;
let localizeService: LocalizeService;
let themesLoader: ThemesLoader;
let environmentService: EnvironmentService;

// eslint-disable-next-line @typescript-eslint/no-empty-function
const stub = (): void => {};
Expand Down Expand Up @@ -71,6 +73,11 @@ describe('HeadlessCheckout', () => {
getTheme: () => 'body { margin: 0;}',
} as unknown as ThemesLoader;

environmentService = {
isSandbox: false,
getHeadlessCheckoutAppUrl: () => headlessCheckoutAppUrl,
} as unknown as EnvironmentService;

container.clearInstances();

headlessCheckout = container
Expand All @@ -85,6 +92,9 @@ describe('HeadlessCheckout', () => {
.register<ThemesLoader>(ThemesLoader, {
useValue: themesLoader,
})
.register<EnvironmentService>(EnvironmentService, {
useValue: environmentService,
})
.registerSingleton(HeadlessCheckout)
.resolve(HeadlessCheckout);
});
Expand Down
21 changes: 13 additions & 8 deletions src/features/headless-checkout/headless-checkout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { getUserBalanceHandler } from './post-messages-handlers/get-user-balance
import { nextActionHandler } from './post-messages-handlers/next-action.handler';
import { Field } from '../../core/form/field.interface';
import { getPaymentStatusHandler } from './post-messages-handlers/get-payment-status/get-payment-status.handler';
import { headlessCheckoutAppUrl } from './environment';
import { EnvironmentService } from '../../core/environment/environment.service';
import { FinanceDetails } from '../../core/finance-details/finance-details.interface';
import { getFinanceDetailsHandler } from './post-messages-handlers/get-finance-details.handler';
import { FormStatus } from '../../core/status/form-status.enum';
Expand Down Expand Up @@ -176,14 +176,12 @@ export class HeadlessCheckout {

private formStatus: FormStatus = FormStatus.undefined;
private isWebView?: boolean;
private isSandbox?: boolean;
private theme?: string;
private topLevelDomain?: string;
private isApplePayInstantFlowEnabled = false;
private locale = Lang.EN;
private coreIframe!: HTMLIFrameElement;
private errorsSubscription?: () => void;
private readonly headlessAppUrl = headlessCheckoutAppUrl;
private _formConfiguration?: FormConfiguration;

public constructor(
Expand All @@ -194,11 +192,12 @@ export class HeadlessCheckout {
private readonly formSpy: FormSpy,
private readonly themesLoader: ThemesLoader,
private readonly formLoader: FormLoader,
private readonly environmentService: EnvironmentService,
) {}

public async init(environment: InitialOptions): Promise<void> {
this.isWebView = environment.isWebview;
this.isSandbox = environment.sandbox;
this.environmentService.isSandbox = !!environment.sandbox;
this.theme = environment.theme;
this.topLevelDomain = environment.topLevelDomain;
this.isApplePayInstantFlowEnabled =
Expand All @@ -207,11 +206,17 @@ export class HeadlessCheckout {

await this.localizeService.initDictionaries(environment.language);

this.postMessagesClient.init(this.coreIframe, this.headlessAppUrl);
this.postMessagesClient.init(
this.coreIframe,
this.environmentService.getHeadlessCheckoutAppUrl(),
);
await this.setupCoreIframe();
this.defineComponents();

this.postMessagesClient.init(this.coreIframe, this.headlessAppUrl);
this.postMessagesClient.init(
this.coreIframe,
this.environmentService.getHeadlessCheckoutAppUrl(),
);
void this.setupSecureStyles(this.theme);
this.errorsSubscription = this.postMessagesClient.listen<string>(
EventName.error,
Expand Down Expand Up @@ -245,7 +250,7 @@ export class HeadlessCheckout {
configuration: {
token,
isWebView: this.isWebView,
sandbox: this.isSandbox,
sandbox: this.environmentService.isSandbox,
topLevelDomain: this.topLevelDomain,
isApplePayInstantFlowEnabled: this.isApplePayInstantFlowEnabled,
locale: this.locale,
Expand Down Expand Up @@ -443,7 +448,7 @@ export class HeadlessCheckout {
this.coreIframe.height = '0px';
this.coreIframe.style.border = 'none';
this.coreIframe.style.position = 'absolute';
this.coreIframe.src = `${this.headlessAppUrl}/core`;
this.coreIframe.src = `${this.environmentService.getHeadlessCheckoutAppUrl()}/core`;
this.coreIframe.name = 'core';
this.window.document.body.appendChild(this.coreIframe);
return this.listenCoreIframeLoading();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { applePayErrors } from './apple-pay.errors.const';
import i18next from 'i18next';
import { FormSpy } from '../../../../core/spy/form-spy/form-spy';
import { finishLoadComponentHandler } from '../../post-messages-handlers/finish-load-component.handler';
import { headlessCheckoutAppUrl } from '../../environment';
import { openApplePayPageHandler } from '../../post-messages-handlers/apple-pay/open-apple-pay-page.handler';
import { getWaitingProcessingTemplate } from './waiting-processing.template';
import { waitingProcessingClassname } from './waiting-processing-classname.const';
Expand Down Expand Up @@ -160,7 +159,8 @@ export class ApplePayComponent extends SecureComponentAbstract {
}

protected getSecureHtml(): string {
return `<iframe id="apple-pay-iframe" src='${headlessCheckoutAppUrl}/secure-components/${this
const appUrl = this.environmentService.getHeadlessCheckoutAppUrl();
return `<iframe id="apple-pay-iframe" src='${appUrl}/secure-components/${this
.componentName!}' allow='payment'></iframe>`;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { SecureComponentAbstract } from '../../../../../core/web-components/secure-component/secure-component.abstract';
import { headlessCheckoutAppUrl } from '../../../environment';
import { GooglePayButtonColorType } from './google-pay-button-color.type';
import { EventName } from '../../../../../core/event-name.enum';
import { container } from 'tsyringe';
Expand Down Expand Up @@ -93,6 +92,7 @@ export class GooglePayButtonComponent extends SecureComponentAbstract {
}

protected getSecureHtml(): string {
return `<iframe allow='payment' src='${headlessCheckoutAppUrl}/secure-components/${this.componentName}?buttonColor=${this.buttonColor}'></iframe>`;
const appUrl = this.environmentService.getHeadlessCheckoutAppUrl();
return `<iframe allow='payment' src='${appUrl}/secure-components/${this.componentName}?buttonColor=${this.buttonColor}'></iframe>`;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { PhoneComponentAttributes } from './phone-component-attributes.enum';
import { headlessCheckoutAppUrl } from '../../environment';
import { TextComponent } from '../text-component/text.component';

export class PhoneComponent extends TextComponent {
Expand All @@ -19,7 +18,8 @@ export class PhoneComponent extends TextComponent {
throw new Error('Component name is required');
}

let src = `${headlessCheckoutAppUrl}/secure-components/${this.componentName}`;
const appUrl = this.environmentService.getHeadlessCheckoutAppUrl();
let src = `${appUrl}/secure-components/${this.componentName}`;
const showFlags = this.getAttribute(PhoneComponentAttributes.showFlags);

if (showFlags) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { isEventMessage } from '../../../../core/guards/event-message.guard';
import { CashPaymentData } from '../../../../core/cash-payment-data.interface';
import { getCashPaymentDataHandler } from '../../post-messages-handlers/get-cash-payment-data/get-cash-payment-data.handler';
import { PostMessagesClient } from '../../../../core/post-messages-client/post-messages-client';
import { headlessCheckoutAppUrl } from '../../environment';
import { getXsollaNumberComponentTemplate } from './templates/get-xsolla-number.compontent.template';
import './xsolla-number.component.scss';
import { SendButtonStatus } from './send-button-status.interface';
Expand Down Expand Up @@ -56,8 +55,9 @@ export class XsollaNumberComponent extends SecureComponentAbstract {
}

protected getHtml(): string {
const emailControl = `<iframe src='${headlessCheckoutAppUrl}/secure-components/xsolla-number/email'></iframe>`;
const phoneControl = `<iframe src='${headlessCheckoutAppUrl}/secure-components/xsolla-number/phone'></iframe>`;
const appUrl = this.environmentService.getHeadlessCheckoutAppUrl();
const emailControl = `<iframe src='${appUrl}/secure-components/xsolla-number/email'></iframe>`;
const phoneControl = `<iframe src='${appUrl}/secure-components/xsolla-number/phone'></iframe>`;
const title = this.cashPaymentData?.title;
const userName = this.cashPaymentData?.publicId;
const xsollaNumber = this.cashPaymentData?.xsollaNumber;
Expand Down