设置订单状态跟踪
要将商品发放给用户,需确保付款已成功。
选择一种订单状态跟踪方式:
选择最适合您项目的方式来访问艾克索拉数据:
如没有服务器或您是在客户端侧实现购买处理逻辑,可使用以下方式:
艾克索拉事件API
艾克索拉事件API是Webhook的替代方案,允许您直接从客户端通过向艾克索拉服务器发送请求来获取支付事件信息。这种方式让您无需搭建和维护自己的服务器来处理Webhook。关于艾克索拉事件API的详细使用方法,请参阅我们的文档。
使用WebSocket API在客户端侧获取订单状态
本解决方案使用websocket在不获取订单详细信息的情况下获取订单状态。该方法适用于:客户端(如您的网站或移动应用)和艾克索拉服务器间只创建了一个连接,因此客户端或服务器上都没有额外负载。
完成以下步骤:
- 创建连接,以便艾克索拉服务器和您的客户端识别订单状态消息:
- javascript
1const client = new Centrifuge(
2connectionURL,
3{
4data: {
5 user_external_id: user_external_id,
6 auth: auth,
7 project_id: project_id
8}
9}
10)
11connectionURL - wss://ws-store.xsolla.com/connection/websocket
12auth - user JWT token
- 使用
client.on函数来订阅事件,以便接收关于订单状态的新消息:
- javascript
1client.on('publication', (ctx) => {
2 //handle the status
3});
- 触发建立实际连接:
- javascript
1client.connect()
- 连接API历史记录方法,以便接收订单状态更改历史记录。
- javascript
1client.on('subscribed', function (ctx) {
2 client.history(ctx.channel, { limit: -1, since: { offset: 0 }, reverse: false }).then(function (resp) {
3resp.publications.forEach((ctx) => {
4 /handle the status
5});
6
7 }, function (err) {
8 //handle the status
9 });
10});
消息正文示例:
- javascript
1{
2order_id: 59614241,
3status: "new"
4}
可能出现以下订单状态:
New— 已创建订单但未支付Paid— 订单已支付Done— 订单已交付(已发送所有支付凭证,交付在艾克索拉侧、外部平台等进行)Canceled— 订单已取消,付款已退给用户
Websocket使用建议:
- 通过websocket接收响应的最大等待时间为5分钟。
- 应在打开支付界面时建立连接。
- 一旦收到最终订单状态,无论是
Canceled或Done,都应中止连接。 - 如果websocket的生命周期到期或连接出现任何问题,请使用短轮询。
短轮询
要在状态切换后获取订单中商品的详细信息,请调用获取订单API。
XsollaCatalog.Purchase方法封装了若干跟踪订单状态的方法。关于跟踪机制的详细信息,请参阅Unity专用艾克索拉SDK(旧版/企业版)文档。
此外,您可以实现对订单状态和内容的处理,这些在购买方法的onSuccess回调函数中传入。
您可以使用CheckPendingOrder SDK方法跟踪订单状态。请向该方法传入以下参数:
AccessToken— 购买商品时收到的支付令牌。OrderId— 购买商品时收到的订单ID。SuccessCallback— 支付成功回调。ErrorCallback— 请求错误回调。bIsUserInvolvedToPayment— 用户在付款过程中是否参与。如使用真是货币购买,传入true;如购买免费商品或使用虚拟货币购买,传入false。
关于跟踪机制的详细信息,请参阅虚幻引擎专用艾克索拉SDK文档
要请求订单的状态和内容,请调用CheckOrder SDK方法,并传入以下参数:
要跟踪所创建订单的状态并进行验证,需在应用程序的服务器侧配置Webhook的处理。
在艾克索拉侧,针对商品购买和退款场景,有两种Webhook接收方式:支付和交易数据相关信息与已购买商品信息可以分别通过独立Webhook接收,也可以合并到一个Webhook中接收。默认情况下,所有新项目都会接收合并Webhook。
如需切换到接收合并Webhook的新方式,请联系您的客户成功经理或发送邮件至csm@xsolla.com。
为确保游戏内购商店和支付管理完整运行,需要实现主要Webhook的处理:
| Webhook名称 | 描述 |
|---|---|
用户验证 > 用户验证 (user_validation) | 在支付流程的不同阶段发送,用于确保用户已在游戏中注册。 |
游戏服务 > 合并Webhook > 订单成功支付 (order_paid) | 包含支付数据、交易详细信息和已购买商品的信息。使用Webhook中的数据向用户发放商品。 |
游戏服务 > 合并Webhook > 订单取消 (order_canceled) | 包含已取消支付的数据、交易详细信息和已购买商品的信息。使用Webhook中的数据移除已购买的商品。 |
下图显示了使用合并webhooks进行商品购买和退货的过程。
%%{init: {'themeVariables': { 'noteBkgColor': 'transparent', 'noteBorderColor': 'transparent' }}}%%
sequenceDiagram
participant User as 用户
participant GameClient as 游戏客户端
participant Xsolla as 艾克索拉
participant GameServer as 游戏服务器
%% Item Purchase
rect rgb(243, 243, 241)
Note over User, GameServer: 商品购买
end
User ->> GameClient: 登录
activate GameClient
GameClient ->> Xsolla: 发送用户身份认证请求
activate Xsolla
Xsolla -->> GameClient: 返回JWT/OAuth 2.0令牌
deactivate Xsolla
GameClient ->> Xsolla: 发送JWT、项目ID、分页参数
activate Xsolla
Xsolla -->> GameClient: 返回商品数组
deactivate Xsolla
GameClient -->> User: 显示商店
deactivate GameClient
User ->> GameClient: 选择商品并点击购买按钮
activate GameClient
GameClient ->> Xsolla: 创建订单请求
deactivate GameClient
activate Xsolla
Xsolla -->> GameClient: 返回支付令牌
deactivate Xsolla
activate GameClient
GameClient ->> Xsolla: 使用收到的令牌打开支付UI URL
deactivate GameClient
activate Xsolla
Xsolla ->> GameServer: 发送用户验证Webhook
activate GameServer
GameServer -->> Xsolla: 返回成功状态码
deactivate GameServer
Xsolla -->> User: 显示支付UI
deactivate Xsolla
User ->> Xsolla: 选择支付方式并点击支付按钮
activate Xsolla
Xsolla ->> GameServer: 发送订单支付成功Webhook
activate GameServer
activate GameServer
Note right of GameServer: 向用户发放购买物
deactivate GameServer
GameServer -->> Xsolla: 返回成功状态码
deactivate GameServer
Xsolla -->> User: 显示购买成功界面
deactivate Xsolla
%% Refund / Chargeback
rect rgb(243, 243, 241)
Note over User, GameServer: 退款/拒付
end
User ->> Xsolla: 请求退款或拒付
activate Xsolla
Xsolla ->> GameServer: 发送订单取消Webhook
activate GameServer
activate GameServer
Note right of GameServer: 从用户物品库移除商品
deactivate GameServer
GameServer -->> Xsolla: 返回成功状态码
deactivate GameServer
Xsolla -->> User: 执行退款
deactivate Xsolla
如果在您的应用程序侧实现了商品目录个性化,请设置合作伙伴侧目录个性化的处理。
关于Webhook的完整列表及常规使用信息,请参阅Webhook文档。
设置Webhook的发送
要启用接收Webhook:
- 在发布商帐户中打开项目,前往Project settings > Webhooks部分。
- 在Webhook server字段中,指定用于接收Webhook的服务器URL,格式为https://example.com。您也可以指定Webhook测试工具中提供的URL。
- 生成密钥:
- 在Secret keys部分,点击Add key。
- 在弹出的窗口中,输入便于在常规列表中识别的密钥名称。
- 点击Create key。
- 点击Copy secret,并在己侧保存创建的密钥。
- 点击Done。
- 确认您已保存密钥,然后点击Ok, close。
密钥建议:
- 在己侧保存生成的Secret key。密钥只能在创建时在发布商帐户中看到一次。
- 不要与任何人分享您的密钥。
- 密钥必须存储在您的服务器上,绝不能存储在二进制文件或前端。
- 点击Enable webhooks。
密钥轮换
您最多可以在项目中创建5个密钥,以便进行轮换
每个项目只能有一个活动密钥。如需更改,请在另一个密钥所在行点击Set as active并确认操作。成功迁移到新密钥后,建议删除已停用的密钥。
添加Webhook监听器
Webhook监听器是一个程序代码,可以在指定的URL地址接收传入的Webhook、生成签名及向艾克索拉Webhook服务器发送响应。
生成签名
接收Webhook时,应确保数据传输的安全性。为此,必须从Webhook数据生成一个签名并确保它与HTTP请求头中发送的签名匹配。
要生成签名:
- 将请求正文中的JSON与项目密钥串联起来。
- 对第一步中得到的字符串应用SHA-1加密散列函数。
向Webhook发送响应
要确认收到Webhook,您的服务器必须返回:
200、201或204HTTP代码(成功响应时)。- 带问题描述的
400HTTP代码(如未找到指定用户或传入的签名无效)。
如您的服务器发生临时问题,您的Webhook处理程序也可以返回5xx代码。
如果艾克索拉服务器未收到对订单成功支付或订单取消Webhook的响应,或收到了包含5xx代码的响应,将根据以下规则重新发送Webhook:
- 间隔5分钟尝试2次
- 间隔15分钟尝试7次
- 间隔60分钟尝试10次
自首次尝试起,12小时内最多尝试发送Webhook20次。
支付和退款Webhook的重试逻辑在各自的Webhook页面中有详细说明。
如果艾克索拉服务器未收到用户验证Webhook的响应,或收到400或5xx代码的响应,将不会重新发送用户验证Webhook。
该情况下会向用户显示一个错误,且不会发送支付和订单成功支付Webhook。
配置Webhook中的商品信息
您可以通过items数组配置在订单成功支付和订单取消Webhook中包含的商品数据。
启用附加参数包含
启用以下附加参数的包含功能以标识:
- 商品是否免费(
is_free) - 商品是否为奖励(
is_bonus) - 商品是否为捆绑包内容(
is_bundle_content)
要接收这些参数,您需要使用更新Webhook设置信息API调用将Webhook切换到版本2。在版本1(默认版本)中,这些参数不可用。
包含附加参数的items数组示例:
- json
1"items": [
2 {
3 "sku": "com.xsolla.item_new_1",
4 "type": "bundle",
5 "is_pre_order": false,
6 "is_free": false,
7 "is_bonus": false,
8 "is_bundle_content": false,
9 "quantity": 1,
10 "amount": "1000",
11 "promotions": []
12 },
13 {
14 "sku": "com.xsolla.gold_1",
15 "type": "virtual_currency",
16 "is_pre_order": false,
17 "is_free": false,
18 "is_bonus": false,
19 "is_bundle_content": true,
20 "quantity": 1500,
21 "amount": "[null]",
22 "promotions": []
23 }
24 ]
禁用捆绑包内容包含
默认情况下,Webhook会将捆绑包中的所有商品作为单独商品列表包含在内。您可以将Webhook配置为仅包含捆绑包本身,而不列出其内容。
在这种情况下,捆绑包中包含的商品不会出现在items数组中。在上面的数组中,SKU为com.xsolla.gold_1的商品(作为捆绑包的一部分)未被包含。
禁用捆绑包内容时的items数组示例:
- json
1
2"items": [
3 {
4 "sku": "com.xsolla.item_new_1",
5 "type": "bundle",
6 "is_pre_order": false,
7 "is_free": false,
8 "is_bonus": false,
9 "is_bundle_content": false,
10 "quantity": 1,
11 "amount": "1000",
12 "promotions": []
13 }
14 ]
如需禁用捆绑包内容包含功能,请联系您的客户成功经理或发送邮件至csm@xsolla.com。
发现了错别字或其他内容错误? 请选择文本,然后按Ctrl+Enter。