Pay2Play

The Pay2Play module allows game developers to sell PIN codes directly from a game's website. Users can access the store using the Pay2Play widget. The module has several integration options and allows developers to:

  • Choose different DRM platforms
  • Set different prices for different DRM platforms
  • Configure widget size and color theme
  • Pay tips to the developer

Integration Options

You can integrate the module in either advanced or basic mode.

Basic Integration

Basic integration:

  • Is quick to implement,
  • Does not require token generation or server implementation, and
  • Works well for games not requiring user pre-authorization.

Advanced Integration

Advanced integration:

  • Allows you to securely transfer user and purchase data for its further linking on the game side, and
  • Requires server-side implementation.

Basic Integration Guide

To implement basic integration:

  1. Register an Xsolla Publisher Account.
  2. Create a project.
  3. Set up the module.
  4. Test the payment process.
  5. Add the Pay2Play widget to the game page.
  6. Sign an agreement.

The following parameters are required for the integration:

  • Project ID — shown in the Publisher Account URL when viewing project settings: https://publisher.xsolla.com/{merchant_id}/projects/{project_id}/.

Creating a Project

  1. Go to Projects and click Create new project.
  2. In set up mode:
    • Set Webhooks to Off.
    • Set Serverless integration to On.
    • Turn on the Pay2Play module.

Setting Up the Module

  1. Go to the Pay2Play module settings and configure the following parameters for the game:
    • Name.
    • Description.
    • System requirements.
    • SKU — a unique identifier.
    • Release date.
    • Image.
    • DRM platform.
    • Operating systems/game console versions for the selected DRM platforms.
  2. Click Next.
  3. Configure prices for the selected DRM platforms. Click Next.
  4. Set Uploaded codes to On.
  5. Upload PIN codes for the selected DRM platforms.

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 "settings.mode" = "sandbox" within the access_data object. The JSON structure and parameters in access_data are the same as in the Token request.

To test a bank card payment:

  1. Open the store in sandbox mode.
  2. Choose the item to purchase.
  3. Choose the Credit/debit cards group of payment methods.
  4. 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.

Integrating the Pay2Play Widget

The Pay2Play widget opens your store in a lightbox (on desktop screens) or a new window (on mobile and tablet screens). The widget automatically determines the type of device. To get the widget code, open module settings in your Publisher Account and go to the Publish tab. Copy the code of the desired widget and add it to your game’s website. We recommend using asynchronous loading.

Asynchronous loading example

HTML
 <script>
     var access_data = {"settings":{"project_id":14004},"purchase":{"pin_codes":{"codes":[{"digital_content":"game_sku"}]}}};
     var target_element = "#widget-example-element";
     var s = document.createElement('script');
     s.type = "text/javascript";
     s.async = true;
     s.src = "//static.xsolla.com/embed/pay2play/2.1.0/widget.min.js";
     s.addEventListener('load', function (e) {
         var widgetInstance = XPay2PlayWidget.create(access_data,target_element);
     }, false);
     var head = document.getElementsByTagName('head')[0];
     head.appendChild(s);
 </script>

You can find the complete list of widget initialization parameters in the API Reference and its installation instructions on GitHub.

Advanced Integration Guide

To implement advanced integration:

  1. Register an Xsolla Publisher Account.
  2. Create a project.
  3. Set up the module.
  4. Get a token.
  5. Set up webhook handling.
  6. Test the payment process.
  7. Add the Pay2Play widget to the game page and sign the agreement.

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 the project settings:
    • Set Webhooks to On.
    • Specify the webhook URL.
    • Generate a secret key to sign project webhooks.
    • Set Serverless integration to Off.
    • Turn on the Pay2Play module.

Setting Up the Module

  1. Go to the Pay2Play module settings and configure the following parameters for the game:
    • Name.
    • Description.
    • System requirements.
    • SKU — a unique identifier.
    • Release date.
    • Image.
    • DRM platform.
    • Operating systems/game console versions for the selected DRM platforms.
  2. Click Next.
  3. Configure prices for the selected DRM platforms. Click Next.
  4. Set Uploaded codes to On.
  5. Upload PIN codes for the selected DRM platforms.

Get Token to Open Store

To integrate the store UI into your game, you will need an access token. An access token is a string that identifies the game, user and purchase parameters.

Xsolla API uses HTTP Basic Authentication. Provide your Merchant ID as the basic auth username and the API key as your password.

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

Token endpoint URL:

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

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

Example Request

Below you can find sample code of how to get a token in PHP with the help of Xsolla PHP SDK. If you're using another programming 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.

Setting up Webhooks

Xsolla sends the following webhooks to your project:

  • User Validation
  • Payment
  • Refund

To acknowledge that you received webhook notifications without any problem, your server should return a 204 HTTP status code without body. The full description of webhook mechanism with samples is described in detail in the API Reference.

Creating a Signature

To create a signature:

  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

If the user cancels the payment, the Xsolla server sends a webhook notification with information about the 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. In the Publisher Account, open the module settings.
  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 store in sandbox mode.
  2. Choose the item to purchase.
  3. Click Credit/debit cards.
  4. 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.

Integrating the Pay2Play Widget

The Pay2Play widget opens your store in a lightbox (on desktop screens) or a new window (on mobile and tablet screens). The widget automatically determines the type of device. To get the widget code, open module settings in your Publisher Account and go to the Publish tab. Copy the code of the desired widget and add it to your game’s website. We recommend using asynchronous loading.

Asynchronous loading example

HTML
 <script>
     var access_data = {"settings":{"project_id":14004},"purchase":{"pin_codes":{"codes":[{"digital_content":"game_sku"}]}}};
     var target_element = "#widget-example-element";
     var s = document.createElement('script');
     s.type = "text/javascript";
     s.async = true;
     s.src = "//static.xsolla.com/embed/pay2play/2.1.0/widget.min.js";
     s.addEventListener('load', function (e) {
         var widgetInstance = XPay2PlayWidget.create(access_data,target_element);
     }, false);
     var head = document.getElementsByTagName('head')[0];
     head.appendChild(s);
 </script>

You can find the complete list of widget initialization parameters in the API Reference and its installation instructions on GitHub.

Tips to the Developer

A project can receive tips from each purchase. To enable the option, open Pay2Play price settings and set Use Tips in the Pay2Play widget to On. Three pre-defined tip amounts are available for each currency you add.

The user will be able to choose the tip amount before entering the store. The tips will be added to the purchase price.

Delivering PIN Codes via API

You can send PIN codes after each purchase instead of uploading the list of PIN codes in a file. To enable the feature:

  • Implement the Get PIN code webhook.
  • In Pay2Play settings, go to Upload codes, set On demand to On and Uploaded codes to Off.

Restricting PIN Code Sales

You can limit the number of PIN codes that can be sold for a project. You will get two email notifications: one when 100 or fewer PIN codes are left, and another one when none are. If the limit is exceeded, users won’t be able to execute payment.

Restricting Sales by Regions

The Pay2Play module allows you to configure regional restrictions on PIN code sales. In particular, you can:

  • Set different prices for individual countries or groups of countries;
  • Prohibit sales in certain countries.

Once you have properly configured the project, a user trying to purchase a PIN code in a restricted country will see a corresponding warning. In countries for which PIN code sales are prohibited, payment is not possible.

To enable the feature, contact your account manager. We will need the following information for each platform that you want to be subject to regional restrictions:

  • Restriction type:
    • Activation: A PIN code can be activated in certain countries only.
    • Launch: A PIN code can be activated in any country, but the game can be launched in certain countries only;
    • Activation and launch: A PIN code can be activated and the game can be launched in certain countries only.
  • List of country groups with different PIN code prices.
  • Settings for each group of countries:
    • Group name.
    • SKU — a unique group identifier.
    • List of prices in different currencies. Make sure to include the price in the default currency set in module settings.
    • List of countries within each group.
  • List of countries where PIN codes are disabled (if any).

For any single platform, a country can belong either to a different-price group or to the preorders-disabled group. If a country is not listed in any of the groups, PIN codes can be sold without any restrictions, at the prices set in default module settings.

Important! If PIN code activation and game launching are made on your or the DRM platform’s side, then, on the release date, make sure to upload PIN codes with regional restrictions already configured.