Xsolla SDK

PHP SDK

Xsolla PHP SDK is an open source library for interacting with Xsolla API. You can find the link to this project on GitHub here.

Features

  1. Full customization of the payment UI with the help of different methods of getting a token.
  2. Client for all API methods, making your integration easy and convenient. Use it to set up and update virtual currency, items and subscription plans, to manage the user’s balance, to check your finance information with the help of Report API, and more.
  3. Convenient webhook server:
    • You only need one callback function to start.
    • All security checking is already implemented: signature authentication and IP whitelisting.
    • Full customization of notification processing logic if the standard server class doesn’t suit you.
  4. SDK is built on Guzzle v3, and utilizes many of its features, including persistent connections, parallel requests, events and plugins (via Symfony2 EventDispatcher), service descriptions, over-the-wire logging, caching, flexible batching, and request retrying with truncated exponential back off.

Getting Started

Please register your Publisher Account and create the project. In order to use the PHP SDK Library, you’ll need:

  • MERCHANT_ID
  • API_KEY
  • PROJECT_ID
  • PROJECT_KEY

You can obtain these parameters using the information in your company settings and project settings.

System Requirements

  • PHP 7.1.3+
  • The following PHP extensions are required:
    • curl
    • json

Installing

The recommended way to install Xsolla PHP SDK is through Composer.

$ cd /path/to/your/project
$ composer require xsolla/xsolla-sdk-php

Please visit our GitHub project site for other ways of installing.

Usage

Get Token

To integrate the payment UI into your game, you should obtain an access token. An access token is a string that identifies game, user, and purchase parameters.

There are a number of ways for getting a token. The easiest one is to use the createCommonPaymentUIToken method. You only need to pass the project ID in the Xsolla system and the user ID in your game:

use Xsolla\SDK\API\XsollaClient;

$client = XsollaClient::factory(array(
    'merchant_id' => MERCHANT_ID,
    'api_key' => API_KEY
));
$paymentUIToken = $client->createCommonPaymentUIToken(PROJECT_ID, USER_ID,
$sandboxMode = true);

You can pass more parameters in JSON for token:

<?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);

If you want to use some custom parameters for opening the payment UI (e.g., "settings.ui.theme"), you can use this example:

<?php

use Xsolla\SDK\API\XsollaClient;

$tokenContent = array (
    'user' =>
        array (
            'id' =>
                array (
                    'value' => '1234567',
                    'hidden' => true,
                )
        ),
    'settings' =>
        array (
            'project_id' => 14004,
            'ui' =>
                array(
                    'theme' => 'default_dark'
                )
        )
);


$xsollaClient = XsollaClient::factory(array(
    'merchant_id' => MERCHANT_ID,
    'api_key' => API_KEY
));
$response = $xsollaClient->CreatePaymentUIToken(array('request' => $tokenContent));
$token = $response['token'];

Integrate payment UI (Pay Station)

You can use the following code to add the payment UI on your page:

<html>
<head lang="en">
    <meta charset="UTF-8">
</head>
<body>
    <button data-xpaystation-widget-open>Buy Credits</button>

    <?php \Xsolla\SDK\API\PaymentUI\PaymentUIScriptRenderer::send($paymentUIToken, $isSandbox = true); ?>
</body>
</html>

Please follow this link for more information and examples about the payment UI integration.

Receive Webhooks

There is a built-in server class to help you handle the webhooks.

<?php

use Xsolla\SDK\Webhook\WebhookServer;
use Xsolla\SDK\Webhook\Message\Message;
use Xsolla\SDK\Exception\Webhook\XsollaWebhookException;

$callback = function (Message $message) {
    switch ($message->getNotificationType()) {
        case Message::USER_VALIDATION:
            /** @var Xsolla\SDK\Webhook\Message\UserValidationMessage $message */
            // TODO if user not found, you should throw Xsolla\SDK\Exception\Webhook\InvalidUserException
            break;
        case Message::PAYMENT:
            /** @var Xsolla\SDK\Webhook\Message\PaymentMessage $message */
            // TODO if the payment delivery fails for some reason, you should throw Xsolla\SDK\Exception\Webhook\XsollaWebhookException
            break;
        case Message::REFUND:
            /** @var Xsolla\SDK\Webhook\Message\RefundMessage $message */
            // TODO if you cannot handle the refund, you should throw Xsolla\SDK\Exception\Webhook\XsollaWebhookException
            break;
        default:
            throw new XsollaWebhookException('Notification type not implemented');
    }
};

$webhookServer = WebhookServer::create($callback, PROJECT_KEY);
$webhookServer->start();

If the standard server class does not suit you, then you can create your own:

<?php

use Xsolla\SDK\Webhook\WebhookRequest;
use Xsolla\SDK\Webhook\Message\Message;
use Xsolla\SDK\Webhook\WebhookResponse;
use Xsolla\SDK\Exception\Webhook\XsollaWebhookException;

$httpHeaders = array();//TODO fetch HTTP request headers from $_SERVER or apache_request_headers()
$httpRequestBody = file_get_contents('php://input');
$clientIPv4 = $_SERVER['REMOTE_ADDR'];
$request = new WebhookRequest($httpHeaders, $httpRequestBody, $clientIPv4);
//or $request = WebhookRequest::fromGlobals();

$this->webhookAuthenticator->authenticate($request, $authenticateClientIp = true);// throws Xsolla\SDK\Exception\Webhook\XsollaWebhookException

$requestArray = $request->toArray();

$message = Message::fromArray($requestArray);
switch ($message->getNotificationType()) {
    case Message::USER_VALIDATION:
        /** @var Xsolla\SDK\Webhook\Message\UserValidationMessage $message */
        $userArray = $message->getUser();
        $userId = $message->getUserId();
        $messageArray = $message->toArray();
        // TODO if user not found, you should throw Xsolla\SDK\Exception\Webhook\InvalidUserException
        break;
    case Message::PAYMENT:
        /** @var Xsolla\SDK\Webhook\Message\PaymentMessage $message */
        $userArray = $message->getUser();
        $paymentArray = $message->getTransaction();
        $paymentId = $message->getPaymentId();
        $externalPaymentId = $message->getExternalPaymentId();
        $paymentDetailsArray = $message->getPaymentDetails();
        $customParametersArray = $message->getCustomParameters();
        $isDryRun = $message->isDryRun();
        $messageArray = $message->toArray();
        // TODO if the payment delivery fails for some reason, you should throw Xsolla\SDK\Exception\Webhook\XsollaWebhookException
        break;
    case Message::REFUND:
        /** @var Xsolla\SDK\Webhook\Message\RefundMessage $message */
        $userArray = $message->getUser();
        $paymentArray = $message->getTransaction();
        $paymentId = $message->getPaymentId();
        $externalPaymentId = $message->getExternalPaymentId();
        $paymentDetailsArray = $message->getPaymentDetails();
        $customParametersArray = $message->getCustomParameters();
        $isDryRun = $message->isDryRun();
        $refundArray = $message->getRefundDetails();
        $messageArray = $message->toArray();
        // TODO if you cannot handle the refund, you should throw Xsolla\SDK\Exception\Webhook\XsollaWebhookException
        break;
    default:
        throw new XsollaWebhookException('Notification type not implemented');
}

Once you've finished the handling of notifications on your server, please set up the URL that will receive all webhook notifications on the Settings page for your project.

After passing the tests, you’re ready to go live. If you’ve used the sandbox parameters, please don’t forget to remove them from the code.

Troubleshooting

Here you can find some tips for handling and preventing the most frequently encountered errors returned by Xsolla PHP SDK.

[curl] 77: error setting certificate verify locations: CAfile

You may see this kind of error when you send the request to our server using Xsolla PHP SDK, for example when getting a token. By default we enable SSL certificate verification and use the default CA bundle provided by your operating system. However not all system's have a known CA bundle on disk. For example, Windows and OS X do not have a single common location for CA bundles.

There are several ways this problem can be resolved.

Development. You can disable the certificate verification, when you're in development mode. You will need additional testing of this issue on Production environment.

use Xsolla\SDK\API\XsollaClient;

$client = XsollaClient::factory(array(
    'merchant_id' => MERCHANT_ID,
    'api_key' => API_KEY
));
$client->setDefaultOption('ssl.certificate_authority', false);

Production. The more secure and reliable way is to provide the correct CA bundle. You can specify the CA path to the file using the following code:

use Xsolla\SDK\API\XsollaClient;

$client = XsollaClient::factory(array(
    'merchant_id' => MERCHANT_ID,
    'api_key' => API_KEY
));
$сlient->setDefaultOption('ssl.certificate_authority', '/path/to/file');

In Windows this file can be located in the following paths:

  • C:\windows\system32\curl-ca-bundle.crt
  • C:\windows\curl-ca-bundle.crt

Please check the existence of these files, and set the appropriate CA path.

If you don't have this certificate located in the mentioned places, you can try to use the certificate provided by Mozilla, which can be downloaded here (provided by the maintainer of cURL).

In some versions of PHP for Windows there is a problem with programmatic configuration of certificate paths. In order to solve this problem, download the file cacert.pem and specify the path to this file directly in php.ini: curl.cainfo=c:/cacert.pem.

"INVALID_SIGNATURE" error code with message "Authorization header not found in Xsolla webhook request"

Php-cgi under Apache does not pass HTTP Basic user/pass to PHP by default. In order to get this working, you need to add the following line to .htaccess or httpd.conf Apache file:

RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

"INVALID_CLIENT_IP" error code in your webhook server

By default Xsolla PHP SDK is checking the IPs from which the webhook was sent for security reasons. The error code "INVALID_CLIENT_IP" can be returned if you test your webhook server from a localhost in development environment, or your application server works behind some sort of proxy — like a load balancer — on production.

If you are behind a proxy, you should manually whitelist your proxy.

If you are in development environment, you can disable the IP checking using the following code:

use Xsolla\SDK\Webhook\WebhookServer;

$webhookServer = WebhookServer::create($callback, PROJECT_KEY);
$webhookServer->start($webhookRequest = null, $authenticateClientIp = false);

More secure and reliable way is to set your reverse proxy IP address to webhook server:

use Xsolla\SDK\Webhook\WebhookServer;
use Symfony\Component\HttpFoundation\Request;

$request = Request::createFromGlobals();
$request->setTrustedProxies(array('YOUR_PROXY_SERVER_IP_OR_CIDR'));

$webhookServer = WebhookServer::create($callback, PROJECT_KEY);
$webhookServer->start();

More information is available in Symfony Documentation.

Pay Station UE4 SDK

Pay Station UE4 SDK is used to integrate the Xsolla payment UI with apps based on the Unreal Engine.

See demo:

System Requirements

  • 64-bit OS
  • Windows 10
  • Mac OS X 10.11 and higher
  • Visual Studio 2017
  • Unreal Engine v4.19 and higher

Integration Flow

  1. Register an Xsolla Publisher Account.
  2. Create a project in your Publisher Account.
  3. Get a token.
  4. Set up webhooks.
  5. Install and set up the plugin for the Unreal Engine project.

For integration you will need the following parameters:

  • merchantId – ID of a merchant, shown in Project settings > Webhooks
  • apiKey – API key. Parameter is generated in the Company settings > API key section
  • projectId – ID of the project, shown in Project settings > Webhooks
  • projectSecretKey – A secret key of the project. Parameter is generated in the Project settings > Webhooks section

Creating a Project

  1. Log in to Publisher Account.
  2. Go to Projects and click Create new project.
  3. In project settings:
    • Specify the webhook URL
    • Generate a secret key to sign project webhooks

    Getting a Token

    For the SDK to work properly, you need to obtain a token. An access token is a string that is used to authorize client’s requests to the server.

    Xsolla API uses basic access authentication. Specify your merchant ID as the username and your API key as the password.

    URL to retrieve the token: https://api.xsolla.com/merchant/v2/merchants/{merchant_id}/token

    You can alter the HTTP POST request by including the parameters you want to pass on to the payment interface. Both the request and response are in the JSON format.

    An example with cURL:

    curl -v https://api.xsolla.com/merchant/v2/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"
        },
        "purchase": {
                "checkout": {
                    "amount": 9.99,
                    "currency": "USD"
                }
        }
    }'

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

    Setting up Webhooks

    You need to implement the following webhooks:

    To confirm the receipt of a webhook, your server will respond with HTTP code 204 without a message body. You can read more about webhooks, including examples, in the API Reference. To test webhooks, open Project settings > Webhooks section.

    Installing and Setting up the Plugin

    1. Run the Epic Games Launcher, go to My projects and select a project for which you want to add the plugin.
    2. Download the plugin.
    3. Unpack the archive into the {YourProject}/Plugins folder. If there is no Plugins folder, create it.
    4. Open the plugin settings: Settings > Project Settings > Xsolla Pay Station.
    5. Specify the Server URL parameter, which is a URL for getting a token. You can use the https://livedemo.xsolla.com/paystation/token_unreal.php URL for testing.

    Note: To open the payment interface in the sandbox mode, please tick the Sandbox mode checkbox and pass "mode":"sandbox" in the Get token request.

    Setting up a C++ Project

    Note: To set up your project, use Visual Studio for Windows or Xcode for Mac OS.

    1. Generate project files by choosing in your project context menu:
      • Generate Visual Studio project files – for Windows,
      • Open Xcode – for Mac OS.
    2. Add XsollaPayStationPlugin into ExtraModuleNames in the {YourProject}.Target.cs and {YourProjectEditor}.Target.cs files.
    3. Add XsollaPayStationPlugin into PublicDependencyModuleNames or into PrivateDependencyModuleNames in the {YourModule}.Build.cs file.
    4. Include the XsollaPayStationPlugin.h file.
    5. Set up the opening of the payment interface by using the XsollaPayStationPlugin::Get()->Create() function. Specify the following parameters:
      • EShopSizeEnum - the interface size. Available sizes: VE_Small – 620 x 630, VE_Medium – 740 x 760, and VE_Large – 820 x 840.
      • userId – in-game user ID.
      • OnPayStationClosedCallback() – activating a callback function upon closing Pay Station.

    After calling the XsollaPayStationPlugin::Get()->Create() function, the plugin:

    1. Sends a request to the server using the URL from the project settings in the Server URL parameter. User ID and Sandbox mode indicator are passed in the request.
    2. Receives a token in the server response and opens the payment interface.

    Example

    ---------------- HEADER -----------------
    
        UFUNCTION(BlueprintCallable)
        void OnPayStationClosedCallback();
    
    protected:
        // Called when the game starts or when spawned
        virtual void BeginPlay() override;
    
    ---------------- SOURCE -----------------
    
    // Called when the game starts or when spawned
    void AMyActor::BeginPlay()
    {
        Super::BeginPlay();
    
        FOnPaymantSucceeded OnPayStationClosedCallback;
        OnPayStationClosedCallback.BindUFunction(this, "OnPayStationClosedCallback");
    
        XsollaPayStationPlugin::Get()->Create(EShopSizeEnum::VE_Large, userId("exampleid"), OnPayStationClosedCallback);
    
    }
    
    void AMyActor::OnPayStationClosedCallback()
    {
        UE_LOG(LogTemp, Warning, TEXT(""));
    }
    

    Setting up a Blueprint Project

    Set up the opening of the payment interface using the Open Xsolla Pay Station function. Specify the following parameters:

    • Shop Size – interface window size. Possible parameters: Small – 620 x 630, Medium – 740 x 760, and Large – 820 x 840.
    • User Id – user ID.
    • On Pay Station Closed – activating оf a callback function upon closing Pay Station.

    After activating the Open Xsolla Pay Station function, the plugin:

    1. Sends a request to the server using the URL from the project settings in the Server URL parameter. User ID and Sandbox mode indicator are passed in the request.
    2. Receives a token in the server response and opens the payment interface.

    An example of a blueprint project with the opening of the payment interface: