Skip to content

Commit

Permalink
Merge pull request #25 from xsolla/PAYMENTS-16028-status
Browse files Browse the repository at this point in the history
Payments 16028 status
  • Loading branch information
simbirromanmakarov authored Aug 30, 2023
2 parents b890ad2 + 38d7ba1 commit e030f2a
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 16 deletions.
9 changes: 4 additions & 5 deletions examples/paypal/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
/>
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<title>PayPal integration</title>
<!--
Link the SDK bundle.
NOTE: In this example, we use a local build just for convenience purposes.
Expand Down Expand Up @@ -87,10 +87,11 @@ <h1>PayPal payment integration</h1>
/**
* Initialize payment.
* returnUrl will be opened after payment completed on PayPal side.
* Please see `examples/paypal/return.html` for more details
*/
const form = await headlessCheckout.form.init({
paymentMethodId: paypalPaymentMethodId,
returnUrl: 'https://xsolla.com',
returnUrl: 'http://return',
});

/**
Expand All @@ -116,10 +117,8 @@ <h1>PayPal payment integration</h1>

/**
* Open PayPal payment system.
* You can open PayPal in the same window with `window.location.href = url`
* and provide your return payment page url during form initialization.
*/
window.open(url, '_blank');
window.location.href = url;

/**
* Create status component. It will be updated once payment status changed.
Expand Down
81 changes: 81 additions & 0 deletions examples/paypal/return.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
/>
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Return page</title>
<!--
Link the SDK bundle.
NOTE: In this example, we use a local build just for convenience purposes.
-->
<script src="../../dist/main.js"></script>
</head>

<body>
<h1>PayPal payment return page</h1>

<!--
Add status component. It will take the necessary parameters from return url
-->
<psdk-status></psdk-status>

<!--
Add legal component to provide links to legal documents
-->
<psdk-legal></psdk-legal>

<script>
if (typeof PayStationSdk === 'undefined') {
alert(`
It seems SDK library is undefined.
Please, link CDN source or create local build (recommended to test purposes only).
`);
throw new Error('PayStationSdk not found');
}
/**
* To learn more about creating tokens,
* please read https://developers.xsolla.com/api/pay-station/operation/create-token/
*/
const accessToken = '';

if (!accessToken) {
alert('No token provided. Please, check the documentation');
throw new Error('No token provided');
}

/**
* The SDK is available under the PayStationSdk namespace.
* To begin initialization, obtain a reference to the headlessCheckout object.
*/
const { headlessCheckout } = PayStationSdk;

async function initPayStationSdk() {
/**
* Call the `init()` method with the provided environment object.
* The isWebView parameter is required and indicates whether your
* integration type is a webview or not.
* You can set sandbox payment mode with `sandbox` parameter
* Please note that this command executes asynchronously.
*/
await headlessCheckout.init({
isWebView: false,
sandbox: true,
});

/**
* After the Payments SDK has been initialized, the next step is setting the token.
* To learn more about creating tokens,
* please read https://developers.xsolla.com/api/pay-station/operation/create-token/
*/
await headlessCheckout.setToken(accessToken);
}

// initialize sdk
initPayStationSdk();
</script>
</body>
</html>
3 changes: 3 additions & 0 deletions src/features/headless-checkout/headless-checkout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,9 @@ export class HeadlessCheckout {
public async getStatus(): Promise<Status> {
const msg: Message = {
name: EventName.getPaymentStatus,
data: {
url: this.window.location.href,
},
};

return this.postMessagesClient.send<Status>(msg, (message) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ import failedImage from '../../../../assets/statuses/failed.png';
import { HeadlessCheckout } from '../../headless-checkout';
import { getStatusComponentTemplate } from './status.component.template';
import { StatusComponentConfig } from './status.component.config.interface';
import { HeadlessCheckoutSpy } from '../../../../core/spy/headless-checkout-spy/headless-checkout-spy';
import { FormSpy } from '../../../../core/spy/form-spy/form-spy';

export class StatusComponent extends WebComponentAbstract {
private readonly headlessCheckout: HeadlessCheckout;
private readonly headlessCheckoutSpy: HeadlessCheckoutSpy;
private readonly formSpy: FormSpy;

private statusConfig: StatusComponentConfig | null = null;
private prevStatusUpdate: StatusUpdatedAction | null = null;
Expand All @@ -21,10 +25,32 @@ export class StatusComponent extends WebComponentAbstract {
super();

this.headlessCheckout = container.resolve(HeadlessCheckout);
this.headlessCheckoutSpy = container.resolve(HeadlessCheckoutSpy);
this.formSpy = container.resolve(FormSpy);
}

protected connectedCallback(): void {
if (!this.headlessCheckoutSpy.appWasInit) {
this.headlessCheckoutSpy.listenAppInit(() => this.connectedCallback());
return;
}
void this.getStatus();
this.listenFormInit();
}

protected getHtml(): string {
if (this.statusConfig) {
return getStatusComponentTemplate(this.statusConfig);
}

return '';
}

private listenFormInit(): void {
if (!this.formSpy.formWasInit) {
this.formSpy.listenFormInit(() => this.listenFormInit());
return;
}

this.headlessCheckout.form.onNextAction((nextAction) => {
if (
Expand All @@ -38,14 +64,6 @@ export class StatusComponent extends WebComponentAbstract {
});
}

protected getHtml(): string {
if (this.statusConfig) {
return getStatusComponentTemplate(this.statusConfig);
}

return '';
}

private statusLoadedHandler(
statusConfig: StatusComponentConfig | null
): void {
Expand All @@ -72,13 +90,23 @@ export class StatusComponent extends WebComponentAbstract {
StatusEnum.created,
StatusEnum.held,
].includes(status.statusState);
const isError =
[StatusEnum.canceled, StatusEnum.error].includes(status.statusState) ||
status.isCancelUser;
const isCanceled =
status.statusState === StatusEnum.canceled || status.isCancelUser;
const isError = status.statusState === StatusEnum.error;
const isSuccess =
status.statusState === StatusEnum.done ??
status.statusState === StatusEnum.authorized;

// check cancel before processing since canceled invoice has status state "created"
if (isCanceled) {
return {
image: failedImage,
title: i18next.t('status.error.title'),
description: '',
showDescription: false,
};
}

if (isProcessing) {
return {
image: null,
Expand Down

0 comments on commit e030f2a

Please sign in to comment.