Tokenization

Tokenization refers to a set of API methods that allow you to securely process payments without opening the payment UI or involving the user. The module allows you to:

  • Obtain the list of saved payment accounts,
  • Make a payment using a saved payment account,
  • Delete a payment account.

Tokenization is supported for the following payment methods:

  • Credit Card
  • PayPal
  • Amazon
  • Skrill
  • Yandex
  • Webmoney
  • Qiwi
  • Liqpay Privat Bank

Integration Guide

The user must make the first payment via the Pay Station UI. Once the payment is made, Pay Station will generate a token — a saved payment account ID — and use it afterward without involving the user or opening the UI.

To integrate the module:

  1. Register an Xsolla Publisher Account.
  2. Create a new project.
  3. Get a token.
  4. Set up the opening of the payment UI.
  5. Set up webhook handling.
  6. Test the payment process.
  7. Launch the module and sign the agreement.
  8. Implement processes related to saved accounts.

The following parameters are required for the integration:

  • Merchant ID — shown in the Publisher Account URL: https://publisher.xsolla.com/{merchant_id}/.
  • API Key — generated in Publisher Account > Settings > Company.
  • Project ID — shown in the Publisher Account URL when viewing project settings: https://publisher.xsolla.com/{merchant_id}/projects/{project_id}/.
  • Project secret key — generated in project settings.

Creating a Project

  1. Go to Projects and click Create new project.
  2. In set up mode:
    a. Specify the webhook URL.
    b. Generate a secret key to sign project webhooks.
    c. Turn on the Payment Wall module.

Getting the Payment UI Token

To integrate Payment UI into your game you should obtain an access token. An access token is a string that identifies game, user and purchase parameters. Xsolla API uses HTTP Basic Authentication. Provide your Merchant ID as the basic auth username and API key as a password.

Set the value "mode":"sandbox" to test the payment process.

Getting token endpoint:

https://api.xsolla.com/merchant/merchants/{merchant_id}/token

In a HTTP POST request you can use parameters for store UI. Request and response payloads are formatted as JSON.

Example Request

Below you can find an example of getting the token in PHP with the help of Xsolla PHP SDK. If you're using another language, please take a look at the CURL example by clicking on the CURL tab.

PHP
CURL
  <?php

  use Xsolla\SDK\API\XsollaClient;
  use Xsolla\SDK\API\PaymentUI\TokenRequest;

  $tokenRequest = new TokenRequest($projectId, $userId);
  $tokenRequest->setUserEmail('email@example.com')
      ->setExternalPaymentId('12345')
      ->setSandboxMode(true)
      ->setUserName('USER_NAME')
      ->setCustomParameters(array('key1' => 'value1', 'key2' => 'value2'));

  $xsollaClient = XsollaClient::factory(array(
      'merchant_id' => MERCHANT_ID,
      'api_key' => API_KEY
  ));
  $token = $xsollaClient->createPaymentUITokenFromRequest($tokenRequest);
      curl -v https://api.xsolla.com/merchant/merchants/{merchant_id}/token \
      -X POST \
      -u your_merchant_id:merchant_api_key \
      -H 'Content-Type:application/json' \
      -H 'Accept: application/json' \
      -d '
      {
          "user": {
              "id": {
                  "value": "1234567"
              },
              "email": {
                  "value": "email@example.com"
              }
          },
          "settings": {
              "project_id": 14004,
              "mode": "sandbox"
          }
      }'

You can find the full list of parameters in the API reference.

Opening the Payment UI

There are three ways of opening the payment UI:

  • Use the Pay Station Embed script.
  • New window.
  • Iframe.

To open the payment UI in sandbox mode, use the following URL: https://sandbox-secure.xsolla.com/.

Pay Station Embed

The Pay Station Embed script determines the type of device and opens the payment UI in a lightbox (on desktop screens) or in a new window (on mobile and tablet screens). We recommend using asynchronous script loading.

Asynchronous script loading example:

   <script>
       var options = {
           access_token: 'ACCESS_TOKEN', //TODO use access token, received on previous step
           sandbox: true //TODO please do not forget to remove this setting when going live
       };
       var s = document.createElement('script');
       s.type = "text/javascript";
       s.async = true;
       s.src = "https://static.xsolla.com/embed/paystation/1.0.7/widget.min.js";
       s.addEventListener('load', function (e) {
           XPayStationWidget.init(options);
       }, false);
       var head = document.getElementsByTagName('head')[0];
       head.appendChild(s);
   </script>

  <button data-xpaystation-widget-open>Buy Credits</button>

You can find the full list of parameters in the API Reference.

New Window

To open the payment UI in a new window, use the following link: https://secure.xsolla.com/paystation2/?access_token=ACCESS_TOKEN, where ACCESS_TOKEN is the token obtained in the previous step.

Iframe

To open the payment UI in an iframe, you must implement the following mechanisms on your side:

  • Specify the device type (desktop vs mobile) and send it within the token’s settings.ui.version parameter;
  • Receiving events from the payment UI via postMessage.

To open the payment UI in a new window, use the following link: https://secure.xsolla.com/paystation2/?access_token=ACCESS_TOKEN, where ACCESS_TOKEN is the token obtained in the previous step.

Configuring Webhooks

Xsolla sends the following webhooks to your project:

  • User validation
  • Payment
  • Refund

Acknowledge the receipt of a webhook by responding with HTTP code 204 without a message body. You can find more information and examples of webhook handling in the API Reference.

Creating a Signature

To create an electronic signature, we:

  1. Concatenate the data sent in the Xsolla server’s request and the project’s secret key (generated in project settings).
  2. Hash the string using the SHA1 algorithm.
  3. Send the signature in the Signature header.

When handling a webhook, make sure that the signature received matches the one set in the Signature header.

User Validation

The Xsolla server sends a request to the project’s webhook URL to verify that a user exists in the game.

Request example

PHP
CURL
  $request = array(
      'notification_type' => 'user_validation',
      'user' => array(
          'ip' => '127.0.0.1',
          'phone' => '18777976552',
          'email'=> 'email@example.com',
          'id'=> '1234567',
          'country' => 'US'
      )
  )
  curl -v https://example.com/ \
  -X POST \
  -H 'Content-Type:application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Signature 13342703ccaca5064ad33ba451d800c5e823db8f' \
  -d '
  {
      "notification_type": "user_validation",
      "user": {
          "ip": "127.0.0.1",
          "phone": "18777976552",
          "email": "email@example.com",
          "id": "1234567",
          "country": "US"
      }
  }'

You can find the full list of parameters in the API Reference.

Payment

The Xsolla server sends a webhook including payment details whenever a user completes a payment.

Request example

PHP
CURL
  $request = array(
      'notification_type' => 'payment',
      'purchase' => array(
          'virtual_items' => array(
              'items' => array(
                  0 => array(
                      'sku' => 'test_item1',
                      'amount' => 1,
                      ),
                  1 => array(
                      'sku' => 'test_item2',
                      'amount' => 1,
                      ),
                  2 => array(
                      'sku' => 'test_item3',
                      'amount' => 1,
                      ),
              )
          ),
          'total' => array(
              'currency' => 'USD',
              'amount' => 9.99
          )
      ),
      'user' => array(
          'ip' => '127.0.0.1',
          'phone' => '18777976552',
          'email' => 'email@example.com',
          'id' => '1234567',
          'country' => 'US'
      ),
      'transaction' => array(
          'id' => 87654321,
          'payment_date' => '2014-09-23T19:25:25+04:00',
          'payment_method' => 1380,
          'dry_run' => 1
      ),
      'payment_details' => array(
          'payment' => array(
              'currency' => 'USD',
              'amount' => 9.99
          ),
          'vat' => array(
              'currency' => 'USD',
              'amount' => 0
          ),
          'payout_currency_rate' => 1,
          'payout' => array(
              'currency' => 'USD',
              'amount' => 9.49
          ),
          'xsolla_fee' => array(
              'currency' => 'USD',
              'amount' => 0.19
          ),
          'payment_method_fee' => array(
              'currency' => 'USD',
              'amount' => 0.31
          )
      )
  )
  curl -v https://example.com/ \
  -X POST \
  -H 'Content-Type:application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Signature 13342703ccaca5064ad33ba451d800c5e823db8f' \
  -d '
  {
      "notification_type": "payment",
      "purchase": {
          "virtual_items": {
              "items": [
                  {
                      "sku": "test_item1",
                      "amount": 1
                  },
                  {
                      "sku": "test_item2",
                      "amount": 1
                  },
                  {
                      "sku": "test_item3",
                      "amount": 2
                  },
              ]
          },
          "total": {
              "currency": "USD",
              "amount": 9.99
          }
      },
      "user": {
          "ip": "127.0.0.1",
          "phone": "18777976552",
          "email": "email@example.com",
          "id": "1234567",
          "country": "US"
      },
      "transaction": {
          "id": 87654321,
          "payment_date": "2014-09-23T19:25:25+04:00",
          "payment_method": 1380,
          "dry_run": 1
      },
      "payment_details": {
          "payment": {
              "currency": "USD",
              "amount": 9.99
          },
          "vat": {
              "currency": "USD",
              "amount": 0
          },
          "payout_currency_rate": 1,
          "payout": {
              "currency": "USD",
              "amount": 9.49
          },
          "xsolla_fee": {
              "currency": "USD",
              "amount": 0.19
          },
          "payment_method_fee": {
              "currency": "USD",
              "amount": 0.31
          }
      }
  }'

You can find the full list of parameters in the API Reference.

Refund

The Xsolla server sends a webhook including payment details whenever a user cancels a payment.

Request example

PHP
CURL
  $request = array(
      'notification_type' => 'refund',
      'purchase' => array(
          'virtual_currency' => array(
              'name' => 'Coins',
              'quantity' => 100,
              'currency' => 'USD',
              'amount' => 9.99
          ),
          'total' => array(
              'currency' => 'USD',
              'amount' => 9.99
          )
      ),
      'user' => array(
          'ip' => '127.0.0.1',
          'phone' => '18777976552',
          'email' => 'email@example.com',
          'id' => '1234567',
          'country' => 'US'
      ),
      'transaction' => array(
          'id' => 87654321,
          'payment_date' => '2014-09-23T19:25:25+04:00',
          'payment_method' => 1380,
          'dry_run' => 1
      ),
      'refund_details' => (
              'code' => 1,
              'reason' => 'Fraud'
      ),
      'payment_details' => array(
          'payment' => array(
              'currency' => 'USD',
              'amount' => 9.99
          ),
          'vat' => array(
              'currency' => 'USD',
              'amount' => 0
          ),
          'payout_currency_rate' => 1,
          'payout' => array(
              'currency' => 'USD',
              'amount' => 9.49
          ),
          'xsolla_fee' => array(
              'currency' => 'USD',
              'amount' => 0.19
          ),
          'payment_method_fee' => array(
              'currency' => 'USD',
              'amount' => 0.31
          )
      )
  );
  curl -v https://example.com/ \
  -X POST \
  -H 'Content-Type:application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Signature 13342703ccaca5064ad33ba451d800c5e823db8f' \
  -d '
  {
      "notification_type":"refund",
      "purchase":{
          "virtual_currency":{
              "name": "Coins",
              "quantity":10,
              "currency":"USD",
              "amount":100
          },
          "subscription":{
              "plan_id": "b5dac9c8",
              "subscription_id": "10",
              "date_create": "2014-09-22T19:25:25+04:00",
              "currency": "USD",
              "amount": 9.99
          },
          "checkout":{
              "currency":"USD",
              "amount":50
          },
          "virtual_items":{
              "items":[
                  {
                      "sku": "test_item1",
                      "amount":1
                  }
              ],
              "currency":"USD",
              "amount":50
          },
          "total":{
              "currency":"USD",
              "amount":200
          }
      },
      "user": {
          "ip": "127.0.0.1",
          "phone": "18777976552",
          "email": "email@example.com",
          "id": "1234567",
          "name": "Xsolla User",
          "country": "US"
      },
      "transaction":{
          "id":1,
          "external_id":1,
          "dry_run":1,
          "agreement":1
      },
      "refund_details":{
          "code":1,
          "reason":"Fraud"
      },
      "payment_details":{
          "xsolla_fee":{
              "currency":"USD",
              "amount":"10"
          },
          "payout":{
              "currency":"USD",
              "amount":"200"
          },
          "payment_method_fee":{
              "currency":"USD",
              "amount":"20"
          },
          "payment":{
              "currency":"USD",
             "amount":"230"
          }
      }
  }'

You can find the full list of parameters in the API Reference.

Testing Webhooks

To test the webhook handler:

  1. Open module settings in your Publisher Account.
  2. Go to the Testing tab.
  3. Enter the test data and click Test. The Xsolla server will send all possible webhooks.
  4. The test is marked green in case of a valid response and red in case of an error.

Testing Payment Process

Xsolla Sandbox is a standalone environment that supports all features of the live environment, except real payments. You can access the Sandbox by sending "mode" = "sandbox" when getting the token.

To test a bank card payment:

  1. Open the payment UI in sandbox mode.
  2. Click Credit/debit cards.
  3. Enter the bank card details and any values in the remaining fields. You can also specify incorrect details (card number, expiration date, or CVV) in order to generate an error.

List of bank cards to be used for testing

Important! Sandbox bank card payments can only be made in USD, EUR, RUB, GBP, SGD, HKD, or THB.

Launching the Module

To launch the module after its successful testing, open its settings in the Publisher Account, go to the Launch tab, and click On.

Important! Before you can accept real payments, you must:

  1. Remove "mode" = "sandbox".
  2. Sign the agreement.

Working with saved payment accounts

After the user makes the first payment via the Payment UI, their payment account is saved, and further payments can be made without involving the user or opening the UI.

Obtaining the List of Saved Payment Accounts

Request example

CURL
curl -v 'https://api.xsolla.com/merchant/projects/{project_id}/users/{user_id}/payment_accounts' \
-X GET \
-u merchant_id:merchant_api_key

Response example

CURL
[
    {
        "type": "card",
        "id": 1,
        "name": "411111******1111",
        "payment_system": {
            "id": 1380,
            "name": "Credit/Debit Cards"
        }
    }
]

You can find the full list of parameters in the API Reference.

Making a Payment Using a Saved Payment Account

Request example

CURL
$ curl -v 'https://api.xsolla.com/merchant/projects/{project_id}/users/{user_id}/payments/{type}/{account_id}' \
-X POST \
-u merchant_id:merchant_api_key \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "user": {
        "ip": "127.0.0.1",
        "name": "John Smith"
    },
    "purchase": {
        "virtual_currency": {
            "quantity": 100
        },
        "description": {
            "value": "Test Purchase"
        }
    },
    "settings": {
        "mode": "sandbox"
    }
}'

Response example

CURL
{
    "transaction_id": 119478390
}

You can find the full list of parameters in the API Reference.

Deleting a Saved Payment Account

Request example

CURL
$ curl -v 'https://api.xsolla.com/merchant/projects/{project_id}/users/{user_id}/payment_accounts/{type}/{account_id}' \
-X DELETE \
-u merchant_id:merchant_api_key

You can find the full list of parameters in the API Reference.