SDK Иксоллы

PHP SDK

Xsolla PHP SDK — это открытая библиотека для работы с API Иксоллы. По ссылке вы можете найти этот проект на Github.

Особенности

  1. Настройка платежного интерфейса при помощи нескольких методов получения токена.
  2. Клиент для всех методов API, с помощью которого процесс интеграции будет простым и понятным. Вы можете использовать SDK для создания и обновления пакетов виртуальной валюты, предметов и рекуррентных планов, для управления балансом пользователя, для сверки финансовых данных при помощи API Отчетов и т.д.
  3. Удобный webhook сервер:
    • Чтобы начать работу, вам понадобится только одна callback функция.
    • В SDK уже реализованы методы проверки безопасности запросов: подписи и IP.
    • Если стандартный класс сервера вам не подходит, вы можете при помощи готовых классов создать свой, с собственной логикой обработки оповещений.
  4. SDK основан на фреймворке Guzzle v3 и использует такие его возможности, как постоянное соединение, параллельные запросы, события и плагины (через Symfony2 EventDispatcher), описания веб-сервисов, сквозное логирование, кеширование, гибкую пакетную обработку и повторяющиеся запросы на основе алгоритма усеченной экспоненциальной выдержки.

С чего начать

Для начала работы, пожалуйста, пройдите процесс регистрации в Личном кабинете и создайте проект. Для использования PHP SDK вам понадобятся следующие параметры:

  • MERCHANT_ID
  • API_KEY
  • PROJECT_ID
  • PROJECT_KEY

Эти параметры можно найти в настройках компании и настройках проекта.

Требования

  • PHP 5.3.9+
  • Необходимы следующие PHP расширения:
    • curl
    • json

Установка

Рекомендуемый способ установки PHP SDK — Composer.

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

На странице нашего Github аккаунта есть информация о других способах установки.

Использование

Получение токена

Для интеграции платежного интерфейса в вашей игре необходимо получить токен. Токен — это строка, в которой содержится информация об игре, пользователе и параметрах платежа.

Есть несколько способов получения токена. Наиболее простым среди них является использование метода createCommonPaymentUIToken, вам нужно будет указать только ID проекта в Иксолле и ID пользователя в вашей игре:

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

Вы можете использовать другие параметры:

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

Если вы хотите использовать дополнительные параметры для открытия интерфейса оплаты (например, “settings.ui.theme”), вы можете использовать следующий пример:

<?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'];

Открытие платежного интерфейса

Вы можете использовать следующий код для добавления платежного интерфейса в вашу игру:

<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>

Больше информации и примеров вы можете найти по ссылке.

Обработка Webhook-ов

Готовый класс сервера для обработки оповещений.

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

Если стандартный класс сервера вам не подходит, вы можете создать свой:

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

Как только вы завершите обработку оповещений на вашем сервере, пожалуйста, добавьте URL обработки оповещений, который будет принимать webhook, на странице Настройки для вашего проекта.

После успешного прохождения тестов можно запускать проект в Live. Пожалуйста не забудьте удалить sandbox параметры из кода, если вы их использовали.

Решение проблем

Здесь вы найдете советы по обработке и профилактике наиболее часто встречающихся ошибок, возвращаемых PHP SDK.

[curl] 77: ошибка настройки сертификата проверки местоположения: CAfile

Вы можете увидеть такой вид ошибки, когда отправляете запрос на наш сервер, используя PHP SDK, к примеру, при получении токена. По умолчанию, мы включаем SSL проверку сертификата и используем сертификаты, предоставленные операционной системой. Однако не все системы имеют сертификаты на диске. К примеру, Windows и OS X не имеют единого расположения для цепочек сертификатов.

Есть несколько путей решения данной проблемы.

Разработка. Вы можете отключить проверку сертификата, если вы в находитесь в режиме разработки. Обратите внимание, что вам будет необходимо дополнительно тестировать данную задачу в боевом режиме.

use Xsolla\SDK\API\XsollaClient;

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

Production. Наиболее безопасный и надежный способ — это предоставление корректного сертификата. Вы можете указывать путь к сертификату, используя следующий код:

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

В Windows этот файл может находиться в:

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

Пожалуйста, убедитесь, что файлы существуют и установите соответствующие пути к сертификатам.

Если вы не имеете данного сертификата в указанных местах, вы можете использовать сертификат, предоставленных Mozilla, который можно скачать здесь.

В некоторых версиях PHP на Windows существует проблема с настройкой путей к сертификатам через код. Для ее решения необходимо скачать файл cacert.pem и прописать путь к этому файлу непосредственно в php.ini: curl.cainfo=c:/cacert.pem.

Код ошибки "INVALID_SIGNATURE" с сообщением "Authorization header not found in Xsolla webhook request"

PHP-CGI под Apache не проходит HTTP Basic user/pass to PHP по умолчанию. Чтобы это заработало, вам необходимо добавить следующую строку в .htaccess или httpd.conf файла Apache:

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

"INVALID_CLIENT_IP" код ошибки в вашем Webhook сервере

По умолчанию, из соображений безопасности, PHP SDK проверяет IP-адреса с которых были отправлен webhook. Код ошибки “INVALID_CLIENT_IP” может быть возвращен если вы тестировали ваш webhook-сервер локально, в среде разработки, или сервер вашего приложения работает через некий прокси-серевер — к примеру, балансировщик нагрузки — в боевом режиме.

Если вы используете прокси, вы можете вручную добавить ваш прокси в белый лист.

Если вы находитесь в среде разработки, отключить проверку IP можно используя следующий код:

use Xsolla\SDK\Webhook\WebhookServer;

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

Наиболее безопасный и надежный способ — это добавить ваш обратный прокси IP-адрес на webhook сервер:

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

Больше информации доступно в документации Symfony.