Skip to content

Commit

Permalink
Merge pull request #24 from xsolla/PAYMENTS-15239-update-doc
Browse files Browse the repository at this point in the history
Payments 15239 update doc
  • Loading branch information
simbirromanmakarov authored Aug 29, 2023
2 parents a3db57b + 19003b1 commit b890ad2
Show file tree
Hide file tree
Showing 7 changed files with 272 additions and 61 deletions.
120 changes: 77 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,17 @@ Except for secure inputs, the client has full control over the component's style
## PaymentSdk library interface

```typescript
declare const HeadlessCheckout: {
declare const headlessCheckout: {
/**
* Load secure Core Iframe.
* Load components to CustomElementRegistry. https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry
*/
init(environment: { isWebview: boolean }): Promise<void>;
init(environment: { isWebview?: boolean; sandbox?: boolean }): Promise<void>;

/**
* Remove secure Core Iframe.
*/
destroy(): void;

/**
* Initialize the payment with a token.
Expand All @@ -54,19 +59,29 @@ declare const HeadlessCheckout: {
setToken(token: string): Promise<void>;

/**
* Get all payment methods, including saved accounts.
* Use a country token if it hasn't been passed yet.
* regular - list of available payment methods sorted according to relevance.
* quick - list of available quick payment methods, e.g., Google and Apple Pay buttons.
* saved - list of saved user payment accounts.
* balance - special payment method for users that have an Xsolla balance. Null if the balance is not sufficient for the payment.
* Returns available payment methods, excluding quick payment options.
*/
getRegularMethods(country?: string): Promise<PaymentMethod[]>;

/**
* Returns available quick payment options, e.g., Apple Pay, Google Pay.
*/
getQuickMethods(country?: string): Promise<PaymentMethod[]>;

/**
* Returns a user’s saved methods.
*/
getMethods(country?: string): Promise<{
regular: PaymentMethod[];
quick: PaymentMethod[];
saved: Account[];
balance: PaymentMethod | null;
}>;
getSavedMethods(): Promise<SavedMethod[]>;

/**
* Returns a user’s balance.
*/
getUserBalance(): Promise<UserBalance>;

/**
* Returns financial information about the payment.
*/
getFinanceDetails(): Promise<FinanceDetails | null>;

/**
* Payment form.
Expand Down Expand Up @@ -129,11 +144,6 @@ declare const HeadlessCheckout: {
*/
getStatus(invoiceId?: number): Promise<Status>;

/**
* Delete saved user account.
*/
deleteAccount(accountId: number): Promise<void>;

/**
* Can be used instead of SDK components for creating custom components.
* List of events will be added later.
Expand All @@ -143,11 +153,6 @@ declare const HeadlessCheckout: {
onCoreEvent: (event: Event) => void;
send(event: Event): void;
};

/**
* Create an iframe with secure elements like form input and use it for component creation.
*/
createSecureComponent(name: string): HTMLIFrameElement;
};
```

Expand All @@ -157,19 +162,19 @@ declare const HeadlessCheckout: {

| **Component** | **Selector** | **Status** |
| --------------------- | -------------------- | ---------- |
| Apple Pay Button || 🕑 |
| Checkbox || 🕑 |
| Delete Account Button || 🕑 |
| Finance Details || 🕑 |
| Google Pay Button || 🕑 |
| Payment Form Messages || 🕑 |
| Payment Methods | psdk-payment-methods ||
| Receipt || 🕑 |
| Saved Methods || 🕑 |
| Payment Form Messages || 🕑 |
| Checkbox || 🕑 |
| Select || 🕑 |
| Status || 🕑 |
| Submit | psdk-submit-button ||
| Apple Pay Button || 🕑 |
| Google Pay Button || 🕑 |
| Delete Account Button || 🕑 |
| Submit Button | psdk-submit-button ||
| User Balance || 🕑 |
| Finance Details | psdk-finance-details ||
| Status | psdk-status ||
| Receipt || 🕑 |

![Regular SDK web components](./readme_images/sdk_web_components_scheme.png 'Regular SDK web components')

Expand All @@ -181,11 +186,11 @@ Using SDK components is straightforward: you only need to paste the HTML tag of

### Secure components

| **Component** | **Selector** | **Status** |
| --------------------- | ---------------- | ---------- |
| Card Number Component | psdk-card-number ||
| Phone Component | | 🕑 |
| Text Component | | 🕑 |
| **Component** | **Selector** | **Status** |
| --------------------- | ------------ | ---------- |
| Text Component | psdk-text ||
| Phone Component || 🕑 |
| Card Number Component || 🕑 |

![SDK secure componentscheme](./readme_images/secure_component_scheme.png 'SDK secure componentscheme')

Expand All @@ -197,10 +202,10 @@ Secure components have access to sensitive user data, and are encapsulated in if

### Special components

| **Component** | **Selector** | **Status** |
| ------------- | ------------ | ---------- |
| Legal | | 🕑 |
| Payment Form | | 🕑 |
| **Component** | **Selector** | **Status** |
| ------------- | ----------------- | ---------- |
| Legal | psdk-legal | |
| Payment Form | psdk-payment-form | |

The `Payment Form` component creates missed payment form components to ensure the client does not omit required payment form components. The client receives a warning message from the SDK, but still allows users to complete the payment.

Expand Down Expand Up @@ -233,7 +238,7 @@ The `Legal` component contains information about Xsolla's legal documents. Clien

To start using the Pay Station SDK, include the SDK bundle in your project. You can do this in any convenient way, such as adding the SDK bundle as npm-package or simply adding a CDN link in the `<script>` HTML tag.

> A working example can be found [here](./examples/cdn)
> A working example can be found [here](./examples/select-method)
Regardless of the SDK adding method chosen, all integration steps are the same:

Expand Down Expand Up @@ -333,3 +338,32 @@ Regardless of the SDK adding method chosen, all integration steps are the same:
</body>
</html>
```

## PayPal integration guide

> A working example can be found [here](./examples/paypal)
Integration flow:

1. Add the SDK library to your project. You can use an npm-package or CDN link.
1. Access the `headlessCheckout` object that contains the Pay Station initialization logic.
1. Add the `<psdk-legal>` component to the HTML markup to provide links to legal documents.
1. Add the `<psdk-finance-details>` component to the HTML markup to show purchase details.
- The financial details component will be updated with transaction details once the payment is completed.
1. Initialize the SDK with your environment parameters.
1. Set the access token for the initialized SDK.
1. Initialize the payment form with the PayPal payment method ID and return URL.
- The return URL is used to redirect the user once payment is completed on PayPal’s side.
- `headlessCheckout.form.init` method returns the form object that can be used for future work with the payment form.
1. Subscribe to events of the `NextActions` form to receive notifications about the next payment flow steps.
- Next action with the `redirect` type informs you that a redirect action is required on your side. You can get the URL to redirect from the action payload.
1. Add the form fields component to the HTML markup.
- Use the form object that was returned by `headlessCheckout.form.init` method to get form fields.
- Use fields with the `isMandatory` flag to get required fields only.
- Use the `<psdk-text>` component to render form fields if required. Email and ZIP fields can only be required for PayPal.
1. Add the `<psdk-submit-button>` form submit button to the HTML markup.
1. Handle next action with the `redirect` type once the submit button is clicked.
- Use action payload to get the URL. Make sure you add query parameters to the URL from action payload data.
- Redirect the user to the PayPal payment system using the generated URL.
- You can redirect to the PayPal URL in the same window or create a new window and keep the payment form in a separate tab. Once payment is completed on PayPal’s side, a user is redirected to `returnUrl`.
1. Add the `<psdk-status>` component to the HTML markup to see the payment status.
174 changes: 174 additions & 0 deletions examples/paypal/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
<!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>Document</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 integration</h1>

<div id="form-container"></div>
<div id="status-container"></div>

<!--
Add finance details component to show purchase details
-->
<psdk-finance-details></psdk-finance-details>

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

<!-- Initialization script -->
<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);

/**
* Define payment method id.
* To get lists of payment methods use psdk-payment-methods.
* Please see `examples/select-method` for more details
*/
const paypalPaymentMethodId = 24;

/**
* Initialize payment.
* returnUrl will be opened after payment completed on PayPal side.
*/
const form = await headlessCheckout.form.init({
paymentMethodId: paypalPaymentMethodId,
returnUrl: 'https://xsolla.com',
});

/**
* Subscribe to payment actions
*/
headlessCheckout.form.onNextAction((nextAction) => {
console.log('Next action', nextAction);
const statusContainer = document.querySelector('#status-container');

/**
* Handle redirect action
*/
if (nextAction.type === 'redirect') {
/**
* Generate PayPal redirect url
*/
const url = new URL(nextAction.data.redirect.redirectUrl);
const params = Object.entries(nextAction.data.redirect.data);
params.forEach((entry) => {
const [key, value] = entry;
url.searchParams.append(key, value);
});

/**
* 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');

/**
* Create status component. It will be updated once payment status changed.
* You can use <psdk-status></psdk-status> component as well
*/
const statusComponent = new PayStationSdk.StatusComponent();
statusContainer.append(statusComponent);
}
});

/**
* Create payment form
*/
const formElement = document.querySelector('#form-container');

/**
* form.fields provide available fields for selected payment method.
* You can filter it by `isMandatory` flag to get required fields only
*/
const requiredFields = form.fields.filter(
(field) => field.isMandatory === '1'
);
console.log('Required form fields', requiredFields);

/**
* Render requried fields
*/
requiredFields.forEach((field) => {
if (field.type === 'text') {
/**
* You can use <psdk-text name="field.name"></psdk-text> as well
*/
const input = new PayStationSdk.TextComponent();
input.setAttribute('name', field.name);
formElement.append(input);
}
});

/**
* Render submit form button.
* You can use <psdk-submit-button></psdk-submit-button> as well
*/
const submitButton = new PayStationSdk.SubmitButtonComponent();
submitButton.setAttribute('text', 'Pay Now');
formElement.append(submitButton);
}

// initialize sdk
initPayStationSdk();
</script>
</body>
</html>
7 changes: 5 additions & 2 deletions examples/cdn/index.html → examples/select-method/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ <h1>Pay Station SDK</h1>
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,
Expand All @@ -40,6 +41,7 @@ <h1>Pay Station SDK</h1>

if (!accessToken) {
alert(`No token provided. Please, check the documentation`);
throw new Error('No token provided');
}
async function initPayStationSdk() {
/**
Expand All @@ -56,6 +58,7 @@ <h1>Pay Station SDK</h1>
*/
await headlessCheckout.init({
isWebView: false,
sandbox: true,
});

/**
Expand All @@ -75,8 +78,8 @@ <h1>Pay Station SDK</h1>
* To add extra logic to a component, you can subscribe to
* its events and place your code in a callback function.
*/
paymentMethods.addEventListener('selectionChange', (e) => {
console.log(e);
paymentMethods.addEventListener('selectionChange', (event) => {
console.log(event.detail);
});
}

Expand Down
Loading

0 comments on commit b890ad2

Please sign in to comment.