Set up subscription catalog display and purchase
The implementation of the subscription catalog depends on how you’re integrating subscriptions into your project:
- If you’re integrating subscription sales into your own application or website, you can either:
- Build the catalog UI entirely on your side using subscription plan data from the Xsolla API or your local data.
- Display the subscription catalog using Xsolla’s payment UI — no need to fetch plan data separately.
- If you’re creating a website using Xsolla site builder, the catalog UI should be placed directly within the website layout. In this case, you don’t need to fetch plan data or implement payment UI separately.
Choose where you want to display the subscription catalog:
Choose an authentication option for subscription purchases:
In this scenario, you implement the subscription catalog display on your side and manage the purchase flow via your own server. All interactions with Xsolla are performed using Xsolla API server-side calls.
To implement subscription catalog display and the payment UI opening:
- Implement retrieving a list of subscription plans using the Get plans server-side call (optional).
- Implement the catalog display on your side.
- Implement token generation to open the payment UI for subscription purchase in one of the following ways:
- Implement the payment UI opening.
Generate token to open payment UI on payment method selection page
To make the payment UI display the payment method selection page when opened, pass the purchase.subscription.plan_id parameter with the ID of the selected plan to the Create token API call. Pass additional customization parameters if needed.
purchase.checkout.amountwith the price of the subscription planpurchase.checkout.currencywith the currency value
- curl
1curl -v https://api.xsolla.com/merchant/v2/merchants/{merchant_id}/token \
2-X POST \
3-u your_merchant_id:merchant_api_key \
4-H 'Content-Type:application/json' \
5-H 'Accept: application/json' \
6-d '
7{
8 "user":{
9 "id":{
10 "value": "1234567",
11 "hidden": true
12 },
13 "email": {
14 "value": "user1234@game1234.com"
15 },
16 "name": {
17 "value": "UserName",
18 "hidden": false
19 }
20 },
21 "settings": {
22 "project_id": 12345,
23 "currency": "USD"
24 },
25 "purchase": {
26 "subscription": {
27 "plan_id": "54321"
28 }
29 }
30}'
Example of payment method selection page:

Generate token to open payment UI on entering payment data page
To make the payment UI display the payment data entry page when opened, pass the following parameters in the Create token API call:
purchase.subscription.plan_idwith the ID of the selected plan.settings.payment_methodwith the payment method ID. To find the list of identifiers, in your project in Publisher Account, go to the Payments > Payment methods section, or request it from your Customer Success Manager.
purchase.checkout.amountwith the price of the subscription planpurchase.checkout.currencywith the currency value
Pass additional parameters for customization if needed.
- curl
1curl -v https://api.xsolla.com/merchant/v2/merchants/{merchant_id}/token \
2-X POST \
3-u your_merchant_id:merchant_api_key \
4-H 'Content-Type:application/json' \
5-H 'Accept: application/json' \
6-d '
7{
8 "user":{
9 "id":{
10 "value": "1234567",
11 "hidden": true
12 },
13 "email": {
14 "value": "user1234@game1234.com"
15 },
16 "name": {
17 "value": "UserName",
18 "hidden": false
19 }
20 },
21 "settings": {
22 "project_id": 12345,
23 "payment_method": 1380,
24 "currency": "USD"
25 },
26 "purchase": {
27 "subscription": {
28 "plan_id": "54321"
29 }
30 }
31}'
Example of payment data entry page:

Open payment UI
To open the payment UI in a new window, use the following URL: https://sandbox-secure.xsolla.com/paystation4/?token=TOKEN, where TOKEN is the obtained token.
You can also open the payment UI using other options:
- With Pay Station Embed. Limitation: there might be problems when opening it in the in-game browser (WebView).
- In iframe. Limitation: there might be problems when opening it in the in-game browser (WebView) and in the mobile version of your application.
EXAMPLE: ASYNCHRONOUS SCRIPT LOADING
- html
1<script>
2 var options = {
3 access_token: 'ACCESS_TOKEN', //TODO use access token, received on previous step
4 sandbox: true //TODO please do not forget to remove this setting when going live
5 };
6 var s = document.createElement('script');
7 s.type = "text/javascript";
8 s.async = true;
9 s.src = "https://cdn.xsolla.net/payments-bucket-prod/embed/1.5.0/widget.min.js";
10 s.addEventListener('load', function (e) {
11 XPayStationWidget.init(options);
12 }, false);
13 var head = document.getElementsByTagName('head')[0];
14 head.appendChild(s);
15</script>
16
17<button data-xpaystation-widget-open>Buy Credits</button>
Pay Station Embed allows getting events from the payment UI via postMessage. You can send these events to analytics systems. To set up events processing in your analytics system, contact your Customer Success Manager or email to csm@xsolla.com.
The Xsolla team created a widget that simplifies the integration of the payment UI into your website. The widget script is available in our GitHub repository.
Script initialization parameters:
| Parameter | Type | Description |
|---|---|---|
access_token | string | Token, received via API. Required. |
sandbox | boolean | Set to true to test the payment process: sandbox-secure.xsolla.com will be used instead of secure.xsolla.com. |
lightbox | object | Lightbox parameters (object; desktop version only). |
payment_widget_ui.lightbox.width | string | Lightbox frame width. If null, depends on Pay Station width. Default is null. |
payment_widget_ui.lightbox.height | string | Lightbox frame height. If null, depends on Pay Station height. Default is 100%. |
payment_widget_ui.lightbox.zIndex | integer | Defines arrangement order. Default is 1000. |
payment_widget_ui.lightbox.overlayOpacity | integer | Opacity of the widget’s background (0 — completely transparent, 1 — completely opaque). The default value is 60% (.6). |
payment_widget_ui.lightbox.overlayBackground | string | Overlay background color. Default is #000000. |
payment_widget_ui.lightbox.modal | boolean | If true, the lightbox frame cannot be closed. Default is false. |
lightbox.closeByClick | boolean | If true, clicking the overlay will close the lightbox. Default is true. |
lightbox.closeByKeyboard | boolean | If true, pressing ESC will close the lightbox. Default is true. |
payment_widget_ui.lightbox.contentBackground | string | Frame background color. Default is #ffffff. Note that these color changes do not affect the Pay Station iframe itself, only the settings of the lightbox that hold it. |
payment_widget_ui.lightbox.contentMargin | string | Frame margin. Default is 10px. |
payment_widget_ui.lightbox.spinner | string | Type of animated loading indicator. Can be xsolla or round. Default is xsolla. |
payment_widget_ui.lightbox.spinnerColor | string | Spinner color. No default value. |
childWindow | object | Options for the child window containing the Pay Station UI. Supported in the mobile version. |
childWindow.target | string | Where to open the Pay Station window. Can be _blank, _self, _parent. Default is _blank. |
The script allows you to track payment UI events. Depending on the event type, you can perform various actions on the web page.
List of events:
| Parameter | Description |
|---|---|
| init | Widget initialized. |
| open | Widget opened. |
| load | Payment UI (Pay Station) loaded. |
| close | Payment UI (Pay Station) closed. |
| status | User is on the status page. |
| status-invoice | User is on the status page; payment in progress. |
| status-delivering | Event when the user was moved on the status page, payment was completed, and we’re sending payment notification. |
| status-done | User is on the status page; payment credited to the user’s account. |
| status-troubled | Event when the user was moved on the status page, but the payment failed. |
https://secure.xsolla.com/paystation4/?token=TOKEN.https://sandbox-secure.xsolla.com/paystation4/?token=TOKEN.access_token parameter contains private user data. Make sure that you use server-to-server communication when getting this parameter.To open the payment UI in an iframe:
- Implement the
postMessagemechanism to receive events from the payment UI. - Open the payment UI by following the link
https://sandbox-secure.xsolla.com/paystation4/?token=TOKEN, whereTOKENis the received token.
Potential issue: If a button for copying a payment confirmation code required by some payment systems is not displayed when opening the payment UI in an iframe, pass the allow=“clipboard-read; clipboard-write; payment” attribute to the iframe.
Example:
- html
1<iframe
2 src="https://sandbox-secure.xsolla.com/paystation4/?token=TOKEN"
3 width="800"
4 height="930"
5 allow="clipboard-read; clipboard-write; payment"
6></iframe>
In this scenario, all operations with subscription plan data are handled using Xsolla API client-side calls. This allows you to retrieve the list of plans, display the catalog, and launch the payment UI directly from the client.
To implement subscription catalog display and the payment UI opening:
- Implement retrieving a list of subscription plans using client-side call (optional).
- if your project has subscription-based products configured, use the method to get the subscription plans by products
- if your project doesn’t have subscription-based products configured, use the method for getting the list of plans
- Implement the catalog display on your side.
- Implement token generation to open the payment UI for subscription purchase. To do it, use the client-side call to get the payment UI link.
- Implement the payment UI opening.
Client-side method to get subscription plans by products
On the client side of your application, use an HTTP GET request to implement getting the list of plans: https://subscriptions.xsolla.com/api/user/v1/projects/{projectId}/products/{productId}/plans.
The request must contain an Authorization: Bearer <client_user_jwt> header, where <client_user_jwt> is user’s JSON Web Token (JWT) — a unique, Base64-encoded token encoded according to the Base64 standard. To get the token:
Use the
Register new user andAuth by username and password API calls if your application uses login and password authorization.Use the
Auth via social network API call if your application uses authorization through social networks.
Specify as the path parameters:
projectId— project ID. You can find this parameter in your Publisher Account next to the name of the project.

productID— subscription-based product ID. To get it, contact your Customer Success Manager or email to csm@xsolla.com.
Specify as query parameters:
| Parameter | Type | Description |
|---|---|---|
plan_id | array of integers | Plan ID. |
| array of strings | Plan external ID. Can be found in the Publisher Account in the Items catalog > Subscriptions > Subscription plans > your plan section or via the Get Plans API call. |
| integer | Limit for the number of elements on the page. 15 items are displayed by default. |
| integer | Number of the element from which the list is generated. The count starts from 0 by default. |
| string | Interface language in two-letter lowercase per ISO 639-1. If this parameter is not passed, the language is determined by the user’s IP address. If the passed locale is not in the Xsolla list, English is used by default. |
| string | The two-letter ISO 3166-1 alpha-2 designation is used to identify the user’s country. This parameter affects the choice of locale and currency. If this parameter is not passed, the country is determined by the user’s IP address. |
- curl
1curl -X 'GET' \
2'https://subscriptions.xsolla.com/api/user/v1/projects/{project_id}/products/{productId}/plans?country=RU ' \
3 -H 'accept: application/json' \
4 -H 'Authorization: Bearer client_user_jwt'
- json
1{
2 "items": [
3 {
4 "plan_id": 54321,
5 "plan_external_id": "PlanExternalId",
6 "plan_group_id": "TestGroupId",
7 "plan_type": "all",
8 "plan_name": "Localized plan name",
9 "plan_description": "Localized plan description",
10 "plan_start_date": "2021-04-11T13:51:02+03:00",
11 "plan_end_date": "2031-04-11T13:51:02+03:00",
12 "trial_period": 7,
13 "period": {
14 "value": 1,
15 "unit": "month"
16 },
17 "charge": {
18 "amount": 4.99,
19 "setup_fee": 0.99,
20 "currency": "USD"
21 },
22 "promotion": {
23 "promotion_charge_amount": 3.99,
24 "promotion_remaining_charges": 3
25 }
26 }
27 ],
28 "has_more": false
29}
Client-side method for getting list of plans
On the client side of your application, use an HTTP GET request to implement getting the list of plans: https://subscriptions.xsolla.com/api/user/v1/projects/{projectId}/plans.
The request must contain an Authorization: Bearer <client_user_jwt> header, where <client_user_jwt> is user’s JSON Web Token (JWT) — a unique, Base64-encoded token encoded according to the Base64 standard. To get the token:
Use the
Register new user andAuth by username and password API calls if your application uses login and password authorization.Use the
Auth via social network API call if your application uses authorization through social networks.
Specify the project ID as the projectId path parameter. You can find this parameter in your Publisher Account next to the name of the project.

Specify as query parameters:
| Parameter | Type | Description |
|---|---|---|
plan_id | array of integers | Plan ID. |
| array of strings | Plan external ID. Can be found in the Publisher Account in the Items catalog > Subscriptions > Subscription plans > your plan section or via the Get Plans API call. |
| integer | Limit for the number of elements on the page. 15 items are displayed by default. |
| integer | Number of the element from which the list is generated. The count starts from 0 by default. |
| string | Interface language in two-letter lowercase per ISO 639-1. If this parameter is not passed, the language is determined by the user’s IP address. If the passed locale is not in the Xsolla list, English is used by default. |
| string | The two-letter ISO 3166-1 alpha-2 designation is used to identify the user’s country. This parameter affects the choice of locale and currency. If this parameter is not passed, the country is determined by the user’s IP address. |
- curl
1curl -X 'GET' \
2'https://subscriptions.xsolla.com/api/user/v1/projects/{project_id}/plans?country=RU ' \
3 -H 'accept: application/json' \
4 -H 'Authorization: Bearer client_user_jwt'
- json
1{
2 "items": [
3 {
4 "plan_id": 54321,
5 "plan_external_id": "PlanExternalId",
6 "plan_group_id": "TestGroupId",
7 "plan_type": "all",
8 "plan_name": "Localized plan name",
9 "plan_description": "Localized plan description",
10 "plan_start_date": "2021-04-11T13:51:02+03:00",
11 "plan_end_date": "2031-04-11T13:51:02+03:00",
12 "trial_period": 7,
13 "period": {
14 "value": 1,
15 "unit": "month"
16 },
17 "charge": {
18 "amount": 4.99,
19 "setup_fee": 0.99,
20 "currency": "USD"
21 },
22 "promotion": {
23 "promotion_charge_amount": 3.99,
24 "promotion_remaining_charges": 3
25 }
26 }
27 ],
28 "has_more": false
29}
Client method for getting a link to open a payment UI
On the client side of your application, use an HTTP POST request to implement opening the payment UI: https://subscriptions.xsolla.com/api/user/v1/projects/{projectId}/subscriptions/buy.
The request must contain an Authorization: Bearer <client_user_jwt> header, where <client_user_jwt> is user’s JSON Web Token (JWT) — a unique, Base64-encoded token encoded according to the Base64 standard. To get the token:
Use the
Register new user andAuth by username and password API calls if your application uses login and password authorization.Use the
Auth via social network API call if your application uses authorization through social networks.
Specify the project ID as the projectId path parameter. You can find this parameter in your Publisher Account next to the name of the project.

Specify country as the query parameter — the two-letter designation of the user’s country according to the ISO 3166-1 alpha-2 standard. Affects the choice of locale and currency. If this parameter is not passed, the country is determined by the user’s IP address.
Pass the following parameters in the request:
plan_external_idto open the payment interface on the payment method selection page.
An example of a payment UI:

plan_external_idandsettings.payment_methodto open the payment interface on the page for entering payment data.
An example of a payment UI:

Request body parameters:
| Parameter | Type | Description |
|---|---|---|
| string | Required. The external ID of the subscription plan. You can find it in the Publisher Account > Items catalog > Subscriptions > Subscription plans section. |
| object | Custom project settings (object). |
| object | Interface settings (object). |
| string | Payment UI theme. Can be default, default_dark or custom theme ID. |
| string | Device type. Can be desktop (default) or mobile. |
| object | Interface settings for the desktop version (object). |
| object | Header settings (object). |
| boolean | Whether to show a Close button in Pay Station desktop. The button closes Pay Station and redirects the user to the URL specified in the settings.return_url parameter. false by default. |
| boolean | Whether to show the header in the payment UI. |
| string | Header appearance. Can be compact (in which case the game name and user ID is not shown in the header) or normal. |
| boolean | If true, the header shows your logo (first provide the image to your Customer Success Manager). |
| boolean | Whether to show the project name in the header. |
| string | How to show the header. Can be compact (hides project name and user ID) or normal (default). |
| boolean | Whether to show a Close button in Pay Station mobile. The button closes Pay Station and redirects the user to the URL specified in the settings.return_url parameter. false by default. |
| string | Interface mode in Pay Station. Can be user_account only: The header contains only the account navigation menu, and the user cannot select a product or make a payment. This mode is only available on the desktop. |
| string | Preferred payment currency. Three-letter ISO 4217 currency code. |
| string | Transaction ID in the game. Has to be unique for each user payment. |
| integer | Payment method ID. You can get the list of payment method IDs in Publisher Account. |
| string | Page to redirect the user to after payment. Parameters user_id, foreigninvoice, invoice_id and status will be automatically added to the link. |
| object | Redirect policy settings (object). |
| string | A payment status that redirects the user to a return URL after making a payment. Can be none, successful, successful_or_canceled, or any. |
settings.redirect_policy.delay | integer | Delay (in seconds) after which a user is automatically redirected to the return URL. |
| string | A payment status that redirects the user to a return URL after making a payment. Can be none, successful, successful_or_canceled, or any. |
| string | Text on the button for manual redirection. |
Pass additional parameters for customization if needed.
- curl
1curl -X 'POST' \
2'https://subscriptions.xsolla.com/api/user/v1/projects/{project_id}/subscriptions/buy?country=RU ' \
3 -H 'accept: application/json' \
4 -H 'Authorization: Bearer client_user_jwt'
5
6 {
7 "plan_external_id": "PlanExternalId",
8 "settings": {
9 "ui": {
10 "size": "large",
11 "theme": "string",
12 "version": "desktop",
13 "desktop": {
14 "header": {
15 "is_visible": true,
16 "visible_logo": true,
17 "visible_name": true,
18 "type": "compact",
19 "close_button": true
20 }
21 },
22 "mobile": {
23 "mode": "saved_accounts",
24 "footer": {
25 "is_visible": true
26 },
27 "header": {
28 "close_button": true
29 }
30 },
31 "mode": "user_account"
32 }
33 },
34 "currency": "string",
35 "locale": "string",
36 "external_id": "string",
37 "payment_method": 1,
38 "return_url": "string",
39 "redirect_policy": {
40 "redirect_conditions": "none",
41 "delay": 0,
42 "status_for_manual_redirection": "none",
43 "redirect_button_caption": "string"
44 }
45 }
- json
1{
2 "link_to_ps": "https://secure.xsolla.com/paystation2/?access_token=<access_token>"
3}
Open payment UI
To open the payment UI in a new window, use the following URL: https://sandbox-secure.xsolla.com/paystation4/?token=TOKEN, where TOKEN is the obtained token.
You can also open the payment UI using other options:
- With Pay Station Embed. Limitation: there might be problems when opening it in the in-game browser (WebView).
- In iframe. Limitation: there might be problems when opening it in the in-game browser (WebView) and in the mobile version of your application.
EXAMPLE: ASYNCHRONOUS SCRIPT LOADING
- html
1<script>
2 var options = {
3 access_token: 'ACCESS_TOKEN', //TODO use access token, received on previous step
4 sandbox: true //TODO please do not forget to remove this setting when going live
5 };
6 var s = document.createElement('script');
7 s.type = "text/javascript";
8 s.async = true;
9 s.src = "https://cdn.xsolla.net/payments-bucket-prod/embed/1.5.0/widget.min.js";
10 s.addEventListener('load', function (e) {
11 XPayStationWidget.init(options);
12 }, false);
13 var head = document.getElementsByTagName('head')[0];
14 head.appendChild(s);
15</script>
16
17<button data-xpaystation-widget-open>Buy Credits</button>
Pay Station Embed allows getting events from the payment UI via postMessage. You can send these events to analytics systems. To set up events processing in your analytics system, contact your Customer Success Manager or email to csm@xsolla.com.
The Xsolla team created a widget that simplifies the integration of the payment UI into your website. The widget script is available in our GitHub repository.
Script initialization parameters:
| Parameter | Type | Description |
|---|---|---|
access_token | string | Token, received via API. Required. |
sandbox | boolean | Set to true to test the payment process: sandbox-secure.xsolla.com will be used instead of secure.xsolla.com. |
lightbox | object | Lightbox parameters (object; desktop version only). |
payment_widget_ui.lightbox.width | string | Lightbox frame width. If null, depends on Pay Station width. Default is null. |
payment_widget_ui.lightbox.height | string | Lightbox frame height. If null, depends on Pay Station height. Default is 100%. |
payment_widget_ui.lightbox.zIndex | integer | Defines arrangement order. Default is 1000. |
payment_widget_ui.lightbox.overlayOpacity | integer | Opacity of the widget’s background (0 — completely transparent, 1 — completely opaque). The default value is 60% (.6). |
payment_widget_ui.lightbox.overlayBackground | string | Overlay background color. Default is #000000. |
payment_widget_ui.lightbox.modal | boolean | If true, the lightbox frame cannot be closed. Default is false. |
lightbox.closeByClick | boolean | If true, clicking the overlay will close the lightbox. Default is true. |
lightbox.closeByKeyboard | boolean | If true, pressing ESC will close the lightbox. Default is true. |
payment_widget_ui.lightbox.contentBackground | string | Frame background color. Default is #ffffff. Note that these color changes do not affect the Pay Station iframe itself, only the settings of the lightbox that hold it. |
payment_widget_ui.lightbox.contentMargin | string | Frame margin. Default is 10px. |
payment_widget_ui.lightbox.spinner | string | Type of animated loading indicator. Can be xsolla or round. Default is xsolla. |
payment_widget_ui.lightbox.spinnerColor | string | Spinner color. No default value. |
childWindow | object | Options for the child window containing the Pay Station UI. Supported in the mobile version. |
childWindow.target | string | Where to open the Pay Station window. Can be _blank, _self, _parent. Default is _blank. |
The script allows you to track payment UI events. Depending on the event type, you can perform various actions on the web page.
List of events:
| Parameter | Description |
|---|---|
| init | Widget initialized. |
| open | Widget opened. |
| load | Payment UI (Pay Station) loaded. |
| close | Payment UI (Pay Station) closed. |
| status | User is on the status page. |
| status-invoice | User is on the status page; payment in progress. |
| status-delivering | Event when the user was moved on the status page, payment was completed, and we’re sending payment notification. |
| status-done | User is on the status page; payment credited to the user’s account. |
| status-troubled | Event when the user was moved on the status page, but the payment failed. |
https://secure.xsolla.com/paystation4/?token=TOKEN.https://sandbox-secure.xsolla.com/paystation4/?token=TOKEN.access_token parameter contains private user data. Make sure that you use server-to-server communication when getting this parameter.To open the payment UI in an iframe:
- Implement the
postMessagemechanism to receive events from the payment UI. - Open the payment UI by following the link
https://sandbox-secure.xsolla.com/paystation4/?token=TOKEN, whereTOKENis the received token.
Potential issue: If a button for copying a payment confirmation code required by some payment systems is not displayed when opening the payment UI in an iframe, pass the allow=“clipboard-read; clipboard-write; payment” attribute to the iframe.
Example:
- html
1<iframe
2 src="https://sandbox-secure.xsolla.com/paystation4/?token=TOKEN"
3 width="800"
4 height="930"
5 allow="clipboard-read; clipboard-write; payment"
6></iframe>
In this scenario, the subscription catalog is displayed directly in the Xsolla payment UI, eliminating the need to implement a custom UI for the list of plans. This approach simplifies integration and ensures automatic updates to subscription plan data.
To set up token generation and open the payment UI with the subscription catalog:
- Implement getting the token via the server-side Create token API call. Pass the following parameters in the request:
user.id— user ID in your authorization system.user.email— user email. Must be valid according to the RFC 822 protocol.settings.project_id— project ID. You can find this parameter in your Publisher Account next to the name of the project.
Request example:
- json
1{
2 "user": {
3 "name": {
4 "value": "j.smith@email.com"
5 },
6 "id": {
7 "value": "123a345b678c091d"
8 }
9 },
10 "settings": {
11 "project_id": 177226
12 }
13}
- Implement opening the payment UI in one of the following ways:
To open the payment UI in a new window, use the following URL: https://sandbox-secure.xsolla.com/paystation4/?token=TOKEN, where TOKEN is the obtained token.
You can also open the payment UI using other options:
- With Pay Station Embed. Limitation: there might be problems when opening it in the in-game browser (WebView).
- In iframe. Limitation: there might be problems when opening it in the in-game browser (WebView) and in the mobile version of your application.
EXAMPLE: ASYNCHRONOUS SCRIPT LOADING
- html
1<script>
2 var options = {
3 access_token: 'ACCESS_TOKEN', //TODO use access token, received on previous step
4 sandbox: true //TODO please do not forget to remove this setting when going live
5 };
6 var s = document.createElement('script');
7 s.type = "text/javascript";
8 s.async = true;
9 s.src = "https://cdn.xsolla.net/payments-bucket-prod/embed/1.5.0/widget.min.js";
10 s.addEventListener('load', function (e) {
11 XPayStationWidget.init(options);
12 }, false);
13 var head = document.getElementsByTagName('head')[0];
14 head.appendChild(s);
15</script>
16
17<button data-xpaystation-widget-open>Buy Credits</button>
Pay Station Embed allows getting events from the payment UI via postMessage. You can send these events to analytics systems. To set up events processing in your analytics system, contact your Customer Success Manager or email to csm@xsolla.com.
The Xsolla team created a widget that simplifies the integration of the payment UI into your website. The widget script is available in our GitHub repository.
Script initialization parameters:
| Parameter | Type | Description |
|---|---|---|
access_token | string | Token, received via API. Required. |
sandbox | boolean | Set to true to test the payment process: sandbox-secure.xsolla.com will be used instead of secure.xsolla.com. |
lightbox | object | Lightbox parameters (object; desktop version only). |
payment_widget_ui.lightbox.width | string | Lightbox frame width. If null, depends on Pay Station width. Default is null. |
payment_widget_ui.lightbox.height | string | Lightbox frame height. If null, depends on Pay Station height. Default is 100%. |
payment_widget_ui.lightbox.zIndex | integer | Defines arrangement order. Default is 1000. |
payment_widget_ui.lightbox.overlayOpacity | integer | Opacity of the widget’s background (0 — completely transparent, 1 — completely opaque). The default value is 60% (.6). |
payment_widget_ui.lightbox.overlayBackground | string | Overlay background color. Default is #000000. |
payment_widget_ui.lightbox.modal | boolean | If true, the lightbox frame cannot be closed. Default is false. |
lightbox.closeByClick | boolean | If true, clicking the overlay will close the lightbox. Default is true. |
lightbox.closeByKeyboard | boolean | If true, pressing ESC will close the lightbox. Default is true. |
payment_widget_ui.lightbox.contentBackground | string | Frame background color. Default is #ffffff. Note that these color changes do not affect the Pay Station iframe itself, only the settings of the lightbox that hold it. |
payment_widget_ui.lightbox.contentMargin | string | Frame margin. Default is 10px. |
payment_widget_ui.lightbox.spinner | string | Type of animated loading indicator. Can be xsolla or round. Default is xsolla. |
payment_widget_ui.lightbox.spinnerColor | string | Spinner color. No default value. |
childWindow | object | Options for the child window containing the Pay Station UI. Supported in the mobile version. |
childWindow.target | string | Where to open the Pay Station window. Can be _blank, _self, _parent. Default is _blank. |
The script allows you to track payment UI events. Depending on the event type, you can perform various actions on the web page.
List of events:
| Parameter | Description |
|---|---|
| init | Widget initialized. |
| open | Widget opened. |
| load | Payment UI (Pay Station) loaded. |
| close | Payment UI (Pay Station) closed. |
| status | User is on the status page. |
| status-invoice | User is on the status page; payment in progress. |
| status-delivering | Event when the user was moved on the status page, payment was completed, and we’re sending payment notification. |
| status-done | User is on the status page; payment credited to the user’s account. |
| status-troubled | Event when the user was moved on the status page, but the payment failed. |
https://secure.xsolla.com/paystation4/?token=TOKEN.https://sandbox-secure.xsolla.com/paystation4/?token=TOKEN.access_token parameter contains private user data. Make sure that you use server-to-server communication when getting this parameter.To open the payment UI in an iframe:
- Implement the
postMessagemechanism to receive events from the payment UI. - Open the payment UI by following the link
https://sandbox-secure.xsolla.com/paystation4/?token=TOKEN, whereTOKENis the received token.
Potential issue: If a button for copying a payment confirmation code required by some payment systems is not displayed when opening the payment UI in an iframe, pass the allow=“clipboard-read; clipboard-write; payment” attribute to the iframe.
Example:
- html
1<iframe
2 src="https://sandbox-secure.xsolla.com/paystation4/?token=TOKEN"
3 width="800"
4 height="930"
5 allow="clipboard-read; clipboard-write; payment"
6></iframe>
An example of displaying the subscription catalog in the Xsolla Pay Station:

In this scenario, all catalog elements and purchase logic are configured directly within the site builder, with no need to use the API.
To add subscription sales, you need to add a button to your site and configure the Purchase subscription action for it. You can use customizable buttons in the Header, Card grid, and Game editions blocks.
We recommend using the Cards grid block for subscription sales — it offers extensive customization options for both the cards themselves and their layout.
To make subscriptions available for purchase on the website:
- Open your project in Publisher Account and go to the Storefronts > Websites section.
- Select your site and click Open Site Builder.
- In the main area of the builder, choose a place where you want to add a new block and click Add block.
- Add the Card grid block and set it up. For example, specify a title, set a background, and add texts.
- In the main area of the builder, configure the card grid:
- To split any grid area vertically or horizontally, click the icon with a vertical or horizontal line in the upper-left corner of the area.

- To set the height or width of an area, drag the ║ or ═ icon.

- Go to the card settings. To do this, click the ⚙ icon.

- Add a subscription purchase button to the card:
- Click Add button.

- In the Action drop-down list, select Purchase subscription.
- In the Subscription plan drop-down list, select the plan you created earlier.
The list displays only subscriptions with the Regular plan type.
If the plan you need is not in the list, click Add new plan and set up a subscription plan in Publisher Account.
- Change the button style (optional).
- Customize the subscription purchase button text (optional):
- In the main area of the builder, click on the button text.
- Enter the desired text. By default, the button displays the subscription price or the number of trial days if a trial period is set in the selected subscription plan. When editing the text, you can also include the subscription price or trial period using the following variables:
{priceDefault}— base price. If there's a discount, this value will be struck through.- Example of text display on the site:
- $0.09 per month — if the subscription is not discounted.
$0.09per month — if the subscription is discounted.
{pricePromo}— final subscription price with discount.{trial}— number of trial days.

By default, the text is determined automatically by these rules:
{trial} day(s) for free— if the subscription has a trial period.{priceDefault} {pricePromo} per month— if the subscription doesn’t have a trial period, but is discounted.{priceDefault} per month— if the subscription doesn’t have a trial period and is not discounted.Manage plan— if the current authorized user has an active subscription. This text can’t be changed in the builder and will be displayed even if you manually set custom text for the button.
To restore default text, click on the button text, delete the custom text and unfocus the button.
- Configure other card settings. For example, add text, images, and background.
- Configure other cards in the grid.
Example for recurrent subscription:

Example for subscription with trial:

Example for subscription with discount:

Example for subscription pricing table:

Complete your website setup:
- Configure the website’s visual theme.
- Add additional blocks to the website. To do this, click Add block and select the block that will be displayed on the site. To see the full list of blocks, refer to the instructions.
- Edit the content of each block. To do this, add images and edit texts in the main part of the builder that users will see.
- Set up SEO and localization settings (optional).
- Add additional site pages (optional).
To make your site publicly available, publish it:
- In the upper-right corner of the site builder, click Publish.

- Check the boxes next to the pages you want to publish.
- Confirm that the website is ready for publishing, and click Publish.
If website publication isn’t available, make sure all the conditions are met:
- There are no empty sections on the website (marked with a red indicator).
- The licensing agreement with Xsolla has been signed.
- The main page is published or selected for publication. You can’t publish child pages before the main one.
Enhance the settings (optional):
- Go to the Storefronts > Websites section and click Configure on your website pane.
- To connect your own domain, go to the Site settings > Domain section and make changes to the Xsolla Domain or connect your own domain.
- To monitor the effectiveness of the website, go to the Site settings > Apps section and select and connect services for promotion and analytics.
Found a typo or other text error? Select the text and press Ctrl+Enter.