艾克索拉SDK

PHP SDK

艾克索拉PHP SDK 是一种与 艾克索拉 API集成的开源库。 单击此处 您可以找到此项目在Github上的链接。

特性

  1. 使用不同的获取令牌的方法实现支付 UI 的完全定制化。
  2. 所有 API 方法的客户端,使您的集成变得简单、便捷。您可以使用它来设置和更新虚拟货币、物品和订阅计划,管理用户余额,以及使用报告API查询财务信息,等等。
  3. 方便的 webhook 服务器:
    • 只需一个回调函数即可开始。
    • 已实施所有安全检查:签名身份验证和 IP 白名单。
    • 如果标准服务器类不适合您,则可实现通知处理逻辑的完全定制化。
  4. SDK 基于 Guzzle v3 并利用它的多种功能,包括持续连接、并行请求、事件和插件(使用Symfony2 EventDispatcher)、服务描述、线上记录、缓存、灵活批处理,以及待截断指数补偿的请求重试。

入门

请注册您的发布商帐户 并创建项目。要使用 PHP SDK 库,您需要:

  • MERCHANT_ID
  • API_KEY
  • PROJECT_ID
  • PROJECT_KEY

您可以使用公司信息和项目设置中的信息获取这些参数。

系统要求

  • PHP 5.3.9+
  • 需要以下 PHP 扩展:
    • curl
    • json

安装

推荐通过Composer安装艾克索拉PHP SDK。

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

请访问我们的Github 项目站点了解其他安装方式。

使用

获取令牌

要将支付 UI 集成到您的游戏中,您应当获取访问令牌。访问令牌是一个标识游戏、用户和购买参数的字符串。

有多种获取令牌的方法。最简单的方法是使用 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);

您可以在 JSON 中为令牌传递更多参数:

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

如要为打开支付UI使用自定义参数(例如”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'];

集成支付UI(支付中心)

可以使用下列代码在您的页面上添加支付 UI:

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

有关支付 UI 集成的更多信息和示例,请访问此 链接

接收 Webhook

服务类中有一个版本可以帮助您处理 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');
}

完成服务器上的通知处理后,请在项目的’设置’页面上设置将要接收所有 webhook 通知的 URL。

通过测试后,即可启动模块。如果使用过沙盒参数,请不要忘记从代码中将其删除。

故障排除

您可以在此处找到处理和预防由艾克索拉 PHP SDK 返回的最常见错误的一些技巧。

[curl] 77:证书验证位置设置错误:CAfile

您可能会在使用艾克索拉 PHP SDK 向我们服务器发送请求(例如,获取令牌)时遇到这类错误。默认情况下,我们会启用 SSL 证书验证并使用由操作系统提供的默认 CA 捆绑包。不过,并不是所有的系统磁盘上都有已知的 CA 捆绑包。例如,Windows 和 OS X 没有适用于 CA 捆绑包的通用位置。

有几种办法可以解决这个问题。

开发。在开发模式下时,您可以禁用证书验证。您需要在生产环境中额外测试这个问题。

use Xsolla\SDK\API\XsollaClient;

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

生产。更安全和值得信赖的方法是提供正确的 CA 捆绑包。您可以使用下列代码将指定文件的 CA 路径:

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

请检查这些文件是否存在,然后设置合适的 CA 路径。

如果您没有在上述位置找到此证书,可以尝试使用 Mozilla 提供的证书,可在此处 下载(由 cURL 维护人员提供)。

某些 Windows 版本的 PHP 中存在证书路径编程配置相关的问题。要解决此问题,请下载文件 cacert.pem 并在 php.ini: curl.cainfo=c:/cacert.pem 中直接指定此文件的路径。

显示"Authorization header not found in Xsolla webhook request"信息的"INVALID_SIGNATURE"错误代码

在默认情况下, Apache下的php-cgi不会传递HTTP Basic user/pass给PHP。 为了实现这一目的,您需要将下列行添加至 .htaccess 或 httpd.conf Apache 文件:

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

Webhook 服务器中的“INVALID_CLIENT_IP”错误代码

默认情况下,艾克索拉 PHP SDK 出于安全考虑会检查发送 webhook 的 IP。如果您在开发环境中从本地主机测试 webhook 服务器或者您的应用程序服务器在某种代理服务器(如生产环境中的负载平衡器)之后工作,可能会返回错误代码“INVALID_CLIENT_IP”。

如果您位于代理服务器之后,应该手动将代理服务器添加到白名单中。

如果您在开发环境中,可以使用下列代码禁用 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 文档