服务端对接
支付结果服务端回调
在玩家支付成功或者退款等操作后,XD SDK 会收到支付渠道的回调,平台会把支付结果和用户信息发送给游戏服务,游戏需要接收处理该消息(比如发放游戏道具给玩家 / 收回已放发的道具),并返回应答。
回调 URL:该链接由游戏服务端提供,配置到平台商户后台(可在申请开通游戏支付时在邮件或者 Jira 单一并提供,或者联系平台研发做配置)。
回调密钥:由平台后台生成,用于回调内容签名 (平台在给游戏开通支付后会提供)。
请确保回调 URL 是外部可正常访问的,且不能携带后缀参数,否则可能导致游戏服务无法接收到平台的回调通知信息。
回调 URL 示例:https://gameserver.xd.com/pay.action
。
通知规则
在玩家支付成功或者退款等操作后,XD SDK 会收到支付渠道的回调,平台会把支付结果和用户信息发送给游戏服务,游戏需要接收处理该消息(比如发放游戏道具给玩家 / 收回已放发的道具),并返回应答。
如果平台收到商户的应答不符合规范或超时,平台认为通知失败,会通过一定的策略定期重新发起通知,尽最大努力重试,但不保证通知最终能成功。
游戏服务端需要重复通知幂等处理。
重试规则如下:
通知报文
支付结果通知是以 POST 方法访问游戏设置的通知 url,通知的数据以 JSON 格式通过请求主体(BODY)传输。通知的数据包括了支付结果详情。
支付成功
通知内容主体
name | DateType | Options | Description |
---|---|---|---|
notifyId | number | require | 通知唯一 id |
notifyTime | number | require | 通知创建时间戳(毫秒) |
appId | number | require | 商户应用 id |
userId | string | require | 用户 id |
trxNo | number | require | 平台交易单号 |
trxType | number | require | 交易类型,0: 支付成功,2: 退款 |
outTrxNo | string | nullable | 商户交易单号(即客户端传入的 orderId) |
platform | number | require | 平台,枚举值见附录 |
channel | number | require | 支付渠道,枚举值见附录 |
paymentType | number | require | 支付方式,枚举值见附录 |
products | array | require | 购买的商品列表 , 见下面说明 |
currency | string | require | 货币 |
region | string | require | 地区 |
clientAmount | decimal | nullable | 玩家所实际支付金额(该值为客户端上报),仅在 Google/Apple Pay 有值 |
clientCurrency | string | nullable | 玩家所实际支付货币(该值为客户端上报),仅在 Google/Apple Pay 有值 |
clientRegion | string | nullable | 玩家所实际支付地区(该值为客户端上报),仅在 Google/Apple Pay 有值 |
totalAmount | decimal | require | 订单总金额 |
status | number | require | 订单状态 |
successTime | number | require | 订单完成时间戳(毫秒) |
attach | object | nullable | 附加数据,见下面说明 |
- trxType 为交易类型,0: 支付成功,2: 退款,请注意区分莫要出现把退款当成支付成功的情况。
- 有两种情况返回的 outTrxNo 并非是客户端传入的 orderId(即上面表格里的 outTrxNo),而是平台随机生成的唯一 id,所以不建议游戏服务端以 outTrxNo 是否存在为校验依据。
- Apple 支付票据有概率会出现多票据合并的情况,此时会丢失客户端传入的 orderId。
- 网页支付还有一个从游戏官网进入的版本,玩家在官网网页支付创建的订单都没有游戏客户端传入的 orderId。
- trxNo 为平台唯一订单号,游戏服务端需要记录并做好重复通知幂等处理。
- outTrxNo 为商户订单号(官网网页充值此订单号由平台随机生成唯一 id),商户需要保证 outTrxNo 唯一性,发起充值时平台服务会根据 outTrxNo 和 appId 做幂等处理。
- 如果客户端在调用 SDK 创建订单时未传入 outTrxNo,平台将会为该订单随机生成一个唯一的 outTrxNo。
- outTrxNo 可以用于辅助问题排查或辅助三方对账,如果游戏有类似需求还是建议游戏客户端传入 orderId(即上面表格里的 outTrxNo)。
- 网页充值中存在一笔订单购买多个商品的场景。
- 对于 Google Pay、Apple Pay、和一些 web 支付渠道,totalAmount 并非用户实际付款金额,而是该商品在平台配置的金额。
支付地区
clientRegion 表示玩家实际支付的地区仅在 Google/Apple Pay 有值,并且如果遇到苹果票据合并,clientRegion 就会为空。
只有等于或高于 6.8.1 版本的 iOS XD SDK 才新增获取 clientRegion 功能。SDK 低于 6.8.1 版本,服务端回调内的 clientRegion 一定为空
region 字段:
- AS/GP 下的 region 字段是根据IP判断的
- 网页支付锁区情况下,region 是玩家“注册地区”
- 不锁区的情况下,region 就是玩家自己选择的地区
如下 Google Pay 回调示例: region = HK 表示通过 ip 判断,下单网络是在 HK clientRegion 则表示下单地区是 CN,使用了 clientCurrency = CNY 做的支付。
{
"bankTrxNo":"2000000281119059",
"clientAmount":29.9,
"trxNo":457171434654203905,
"clientCurrency":"CNY",
"notifyTime":1676870194264,
"channel":1,
"trxType":0,
"userId":"339464430121472000",
"outTrxNo":"D7AE0F64-DC6E-4579-82B4-1F02D3920852",
"platform":1,
"paymentType":0,
"products":[
{
"productCode":"com.xd.sdkdemo1.stone300",
"quantity":1,
"channelSkuCode":"com.tds.sdkdemopro.fxqusd299"
}
],
"clientRegion":"CN",
"totalAmount":8.99,
"appId":1111,
"successTime":1676870194228,
"currency":"USD",
"notifyId":457171562190405632,
"attach":{
"gameServerId":"999",
"gameExt":"abcdexxx",
"gameRoleId":"test-user"
},
"region":"HK",
"status":0
}
网页支付示例如下:
clientRegion 为空。
在开启了网页支付锁区功能的情况,region 字段为玩家的注册
地区,否则为玩家在网页上选择的地区。
{
"bankTrxNo":"20230220194010800190188000007040217",
"trxNo":457170213067358209,
"clientCurrency":"",
"notifyTime":1676869890957,
"channel":15,
"trxType":0,
"userId":"383935802234916864",
"outTrxNo":"457170214115934209",
"platform":4,
"paymentType":1,
"products":[
{
"productCode":"com.xd.sdkdemo1.stone60",
"quantity":1,
"channelSkuCode":"com.tds.sdkdemopro.fxqusd299"
}
],
"clientRegion":"",
"totalAmount":4.99,
"appId":1111,
"successTime":1676869890938,
"currency":"USD",
"notifyId":457170290028642304,
"attach":{
"gameServerId":"ap-sg",
"gameExt":"",
"gameRoleId":"383935802234916864"
},
"region":"TW",
"status":0
}
商品信息
主体内容中的 products 字段,该字段为数组。
name | DateType | Options | Description |
---|---|---|---|
productCode | string | require | 商品码 |
quantity | number | require | 数量 |
channelSkuCode | string | require | 支付渠道商品码。只有 Google Pay、Apple Pay 该字段才有值 |
附加数据
主体内容中的 attach 字段,详细字段如下:
name | DateType | Options | Description |
---|---|---|---|
gameServerId | string | require | 客户端透传的 game_server_id 字段 |
gameRoleId | string | require | 客户端透传的 game_role_id 字段 |
gameExt | string | require | 客户端透传的 game_ext 字段 |
通知内容示例 :
{
"appId": 1111,
"attach": {
"gameExt": "ext",
"gameRoleId": "roleID",
"gameServerId": "serviIdext"
},
"channel": 1,
"currency": "CNY",
"notifyId": 264425617725165568,
"notifyTime": 1630915980056,
"outTrxNo": "79867912673",
"paymentType": 0,
"platform": 1,
"products": [
{
"productCode": "com.xd.sdkdemo1.stone30",
"quantity": 1,
"channelSkuCode":"com.tds.sdkdemopro.fxqusd299"
}
],
"status": 1,
"totalAmount": 3.99,
"trxType": 0,
"trxNo": 263336436030607360,
"userId": "262966214111019008"
}
退款通知
目前 Apple Pay 和 Google Pay 支持退款通知,后继会逐渐支持更多支付渠道的退款。如何测试退款请参考 常见问题:如何测试退款。
通知内容主体
和支付成功通知内容略有不同。
name | DateType | Options | Description |
---|---|---|---|
notifyId | number | require | 通知唯一 id |
appId | number | require | 商户应用 id |
notifyTime | number | require | 通知创建时间戳(毫秒) |
userId | string | require | 用户 id |
trxNo | number | require | 平台交易单号 |
originalTrxNo | number | require | 原始平台交易单号 |
trxType | number | require | 交易类型,0: 支付成功,2: 退款 |
platform | number | require | 平台 |
channel | number | require | 支付渠道 |
paymentType | number | require | 支付方式 |
products | array | require | 购买的商品列表,详细见下面解释 |
currency | number | require | 货币 |
totalAmount | decimal | require | 订单总金额 |
status | number | require | 订单状态 |
successTime | number | require | 退款完成时间戳(毫秒) |
attach | object | nullable | 附加数据,详细见下面解释 |
trxType 为交易类型,0: 支付成功,2: 退款,请注意区分莫要出现把退款当成支付成功的情况。
trxNo 和 originalTrxNo 是不同的(即:退款订单和支付订单的 ID 是不同的) 游戏可以通过 originalTrxNo 字段来识别原始的支付订单 。
补款订单再次支付成功不会再收到服务端的到账通知 。
商品信息
主体内容中的 products 字段,该字段为数组。
name | DateType | Options | Description |
---|---|---|---|
productCode | string | require | 商品码 |
quantity | number | require | 数量 |
channelSkuCode | string | require | 支付渠道商品码。只有 Google Pay、Apple Pay 该字段才有值 |
附加数据
主体内容中的 attach 字段,退款通知内的附加内容与原始支付订单内的附加内容一致。详细字段如下 :
name | DateType | Options | Description |
---|---|---|---|
gameServerId | string | require | 客户端透传的 game_server_id 字段 |
gameRoleId | string | require | 客户端透传的 game_role_id 字段 |
gameExt | string | require | 客户端透传的 game_ext 字段 |
通知内容示例 :
{
"appId": 1111,
"attach": {
"gameExt": "ext",
"gameRoleId": "roleID",
"gameServerId": "serviIdext"
},
"channel": 1,
"currency": "CNY",
"notifyId": 264425617725165568,
"notifyTime": 1630915980056,
"paymentType": 0,
"platform": 1,
"products": [
{
"productCode": "com.xd.sdkdemo1.stone30",
"quantity": 1,
"channelSkuCode":"com.tds.sdkdemopro.fxqusd299"
}
],
"status": 1,
"totalAmount": 3.99,
"trxNo": 263336438097889345,
"trxType": 2,
"originalTrxNo": 263336436030607360,
"userId": "262966214111019008"
}
通知应答
支付通知 http 应答码为 200
或 204
才会当作正常接收,当回调处理异常时,应答的 HTTP 状态码应为 500
,或者 4xx
。
当商户后台应答失败时,平台将记录下应答的报文,商户应按照以下格式返回:
{
"code": "SUCCESS",
"msg": "成功"
}
多回调地址
使用场景
当游戏只申请了一个 ClienID
,但是游戏服务器有开发服、提审服、正式服等区分时,为了让回调信息能够通知到不同的游戏服务端,游戏可以通过配置 serverId
与对应回调地址来实现这个需求。
配置参数需要在申请开通支付时添加到申请工单内。
配置示例
{
"default":"https://pay.demo.xd.com/callback",
"prod":"https://pay.demo.xd.com/callback",
"stg":"https://pay-stg.demo.xd.com/callback",
"test":"https://pay-test.demo.xd.com/callback"
}
配置中的 key 即为客户端下单参数 serverId:
XD Server 在做支付结果通知时会通过 serverId
查找对应的回调地址,如果查询不到则使用 key 为 default 的配置,默认使用default。
游戏角色信息查询
接口说明
该接口用于网页端支付,用于类似下图的用户充值到账角色确认。
查询 URL 该链接由游戏服务端提供,由平台研发配置到平台的后台(可在开通支付的申请邮件或 Jira 单子中一并提供,或者在 Slack 公开频道#taptap-tds 提供给平台研发)
调用角色查询接口的时机
- 游戏内打开支付网页后,支付网页会主动查询一次当前玩家的角色 id,如果查询失败或查询接口未返回正确的平台用户 id (即 xdid)会导致玩家无法继续支付流程。
- 官网网页支付页面玩家可以自行输入角色 id,玩家输入的角色 id 可以通过查询接口查询到平台用户 id 后,玩家才可以继续支付流程。
- 玩家下单时,SDK 服务端会通过该接口再次验证角色 id,接口失败默认做一次重试,最终查询失败会导致玩家下单失败。
请求参数
以 GET
方法访问游戏提供的通知 url。
name | DateType | Options | Description |
---|---|---|---|
roleId | string | require | 角色 id |
serverId | string | require | 服务器 id |
返回数据
平台请求之后,游戏的服务返回字段如下:
name | DateType | Options | Description |
---|---|---|---|
userId | string | require | 平台用户 id |
roleId | string | require | 角色 id |
name | string | require | 角色昵称(游戏希望展示给玩家什么昵称就返回什么昵称) |
avatar | string | require | 角色头像 |
roleLv | number | nullable | 角色等级 |
serverId | string | nullable | 服务器 id |
serverName | string | nullable | 服务器名称 |
http 响应 status code 应为 200
。
请求示例
curl -v '{host}/test/v1/game/role?roleId=339064846605987840&serverId=223'
返回示例
{
"userId": "63909809",
"roleId": "1111",
"name": "lvu",
"roleLv": 11,
"avatar":"https://img3.tapimg.com/default_avatars/9cc5d5bcd37bdc024fd3bea3bc58649b.jpg"
}
游戏角色列表查询
该接口用于纯官网页支付,用于查询当前 xdid 的所有游戏角色列表。
特别是在中国大陆开启官网页支付,出于防沉迷政策的要求会需要玩家在网页上登录。此时充值玩家选择充值到该 xdid 的哪个角色上。
查询 URL 该链接由游戏服务端提供,由平台研发配置到平台的后台(可在开通支付的申请 Jira 单子中一并提供)
接口调用时机
- 国内官网网页支付页面玩家选择了游戏服务器列表之后(如果有的话),会用玩家选择的服务器(serverId)去查询当前登录账号的游戏角色列表。
请求参数
以 GET
方法访问游戏提供的 url。
name | DateType | Options | Description |
---|---|---|---|
userId | string | require | XDSDK 生成的用户 ID(也就是 xdid) |
serverId | string | nullable | 服务器 id(玩家在游戏服务器列表中选择的服务器 id(如果有的话)) |
返回数据
平台请求之后,游戏的服务需要当前 xdid 对应的所有可供玩家选择的角色列表信息,results 数组内的字段包括:
name | DateType | Options | Description | |
---|---|---|---|---|
roleId | string | require | 角色 id | |
name | string | require | 角色昵称(游戏希望展示给玩家什么昵称就返回什么昵称) | |
avatar | string | require | 角色头像 | |
roleLv | number | nullable | 角色等级 | |
serverId | string | require | 游戏所在服务器,比如 t_dailay_test/release | |
serverName | string | nullable | 服务器名称 |
http 响应 status code 应为 200
。
请求示例
curl -v '{host}/test/v1/game/roles?userId=339064846605987840&serverId=223'
返回示例
有游戏角色
HTTP Status Code: 200
{
"code":200,
"msg":"OK",
"detail":"OK",
"results":[
{
"roleId":"1111",
"name":"lvu",
"roleLv":11,
"avatar":"https://img3.tapimg.com/default_avatars/9cc5d5bcd37bdc024fd3bea3bc58649b.jpg"
},
{
"roleId":"2222",
"name":"roll",
"roleLv":3,
"avatar":"https://img3.tapimg.com/default_avatars/9cc5d5bcd37bdc024fd3bea3bc58649b.jpg"
}
]
}
msg
字段为玩家侧信息,detail
字段为开发者信息。 HTTP Status Code 为非 200
时把 msg
字段展示给玩家。
无游戏角色
比如该 xdid 不存在游戏角色 HTTP Status Code: 401
{
"code":401,
"msg":"您所登录账号不存在火炬之光的游戏角色,请先往游戏客户端内创建",
"detail":"该 xdid 非法,不存在游戏角色",
"results":[
]
}
HTTP Status Code 为非 200
时把 msg
字段展示给玩家。
下单前校验
该接口用于游戏官网支付页的下单前校验,用于类似下图在官网充值页下单时调用游戏服务端接口给出提示。
新增 quantity
字段,用于批量购买限购商品时,对于玩家购买是否超限的判断,比如限购2次的商品,玩家批量购买3次,这时会把数量通过 quantity
的字段传给游戏,游戏用来判断。
线上已提供该接口的游戏并且已经开通了批量的游戏需要检查新增 quantity
对于游戏接口是否有影响。
未开通批量的游戏如果需要对限购商品支持批量购买,需要对该接口的 quantity
字段进行处理判断。
开通批量需联系平台 @刘方兴
。
比如购买数量限制:
比如在线状态校验:
该接口由游戏服务端提供,由平台研发配置到后台(可在开通支付的申请邮件或 Jira 单子中一并提供接口地址和 ClientID)。
- 该方式无法实现真正的限购,只是在下单前和游戏服务端做一次简单确认。玩家依然可以多开浏览器窗口下单,游戏的服务端在到账的时候可能会拦截但是依然会出现其中一笔到账,另一笔不到账(玩家成功下单了)的情况导致客诉。
- 调用校验接口的时机:玩家下单时,XDSDK 服务端会通过该接口验证是否允许下单,接口失败默认做一次重试,最终查询失败会导致玩家下单失败。
接口说明
请求头
name | value |
---|---|
Content-Type | application/json |
请求参数
以 POST
方法访问游戏提供的通知 url。
name | DateType | Options | Description |
---|---|---|---|
roleId | string | require | 角色 id |
serverId | string | require | 服务器 id |
productSkuCode | string | require | 商品码 |
quantity | int | require | 购买的商品数量 |
extras | string | nullable | 游戏下单时自定义字段 |
返回数据
XDSDK 服务端请求之后,如果允许购买则可以:
- http 响应 status code 应为
200
- 当 http 响应 status code 非
200
时,游戏服务应返回字段如下:
name | DateType | Options | Description |
---|---|---|---|
code | number | require | 错误码,用于前端做多语言 |
msg | string | nullable | 给玩家提示的信息 |
detail | string | require | 开发者信息,便于排查问题 |
code
游戏服务端可以自定义,但需要把 code
对应的多语言文案给到 XDSDK 的前端研发。
如果 code
未同步给 XDSDK 的前端,那么前端会直接展示游戏限购接口返回体内的 msg
信息。
我们建议游戏服务端直接使用 XDSDK 已经内置的错误码,具体详情请参考下文的内置错误码
- 当响应体中未包含
code
字段,XDSDK 服务端会把当前下单阻拦并报错,且无法提醒用户无法下单原因,请务必返回code
字段。 - 当前下单不需要拦截,http 响应 status code
200
即可,否则用户将无法下单。
请求示例
curl --location 'https://xd.cn/order/check' \
--header 'Content-Type: application/json' \
--data '{
"roleId":"12323",
"serverId":"cn-release",
"productSkuCode":"com.xd.sdkdemo1.stone30"
"quantity":1
}'
返回示例
当前下单需要
拦截,http 响应 status code 非 200
。
{
"code": 102,
"msg": "purchase overlimit",
"detail": "当前玩家已购买过该商品"
}
多语言
XDSDK 的前端会根据 code
字段进行多语言适配。
- 如果使用的是内置错误码,项目组无需关心多语言文案。
- 如果是自由定义错误码,多语言文案由项目组自行翻译。
内置错误码
我们提前准备好了一份错误码,游戏服务端可以根据游戏商品限购规则返回以下 code
,例如玩家重复购买月卡类商品时,code
可以传入 105。
coda | 中文文案 |
---|---|
101 | 请输入正确的角色 ID |
102 | 服务器错误,请稍后重试 |
103 | 当前商品不存在 |
104 | 订单提交失败,请先保持游戏在线状态 |
105 | 订单提交失败,你当前商品的购买数量已达到上限 |
106 | 当前有一笔交易正在进行中,请数分钟后重试! |
107 | 服务器错误,请稍后重试 |
112 | 当前角色不满足购买条件 |
113 | 当前有一笔交易正在进行中,请1分钟后重试! |
114 | 当前有一笔交易正在进行中,请2分钟后重试! |
115 | 当前有一笔交易正在进行中,请3分钟后重试! |
自定义错误码
内置错误码 code
都不能满足项目组需求时,可以自定义错误码
- 自定义错误码不能与上面的内置 code 重复
- 自由定义错误码文案,项目组需要自行翻译多语言版本文案
- 新增
code
可以在 slack 上 #xd-platform 频道发起需求并@项管
和@产品经理
待补款订单查询
该接口由 XD Server 提供。可以通过该接口查询到玩家当前是否存在待补款的订单。
待补款订单:指玩家针对已经发放道具的订单,自己在 Apple Store / Google Play 发起的退款的订单。此类退款订单因为道具已经发放所以可以要求玩家补缴已退款的金额,因此叫待补款订单。
使用场景
当玩家在成功退款后,平台会记录下退款信息。当玩家完成登录后,游戏客户端可以通过 XDSDK 提供的补款查询接口查询到当前待补款订单,此时可以对玩家登录进行拦截。 为了防止客户端补款查询结果被恶意篡改,游戏服务端在验证 token 后也可以再通过该接口查询是否存在待补款订单,并根据查询结果进行拦截。
当玩家在客户端完成补款后,待补款单状态会转为已补款,此时该接口也不再返回该笔订单。服务端可以通过待补款订单是否仍存在判断是否已完成补款。
我们更建议对退款订单进行倒扣(见上文退款通知部分),不建议直接拦截玩家登录。游戏可以根据自身商品特点自行选择合适的方案。
仅可以查询到 Apple Store 或 Google Play 的退款单,该接口不会返回其它渠道的退款单。
当用户完成补款后,该接口不再返回待补款订单,所以该接口不能用来拉取用户历史退款订单流水。
请求地址
- 海外域名:
https://xdsdk-intnl-6.xd.com
- 国内域名:
https://xdsdk-6.xd.cn
REST API 请求的 Base URL(下文 curl 示例中用 {{host}}
表示)。
URL | METHOD | 功能 |
---|---|---|
/order/v1/user/arrears | GET | 获取用户当前待补款订单列表 |
请求方式
请求参数
name | DateType | Options | Description |
---|---|---|---|
clientId | string | require | XD Client ID |
请求头
name | DateType | Options | Description |
---|---|---|---|
Authorization | string | require | 签名 |
Authorization 字段的签算过程见 Mac Token 签算 小节。
请求示例
curl --location 'https://{{host}}/order/v1/user/arrears?clientId=d4bjgwom9zk84wk' \
--header 'Authorization: MAC id="HlRLEwCmDk5v9G3cxVaZJ18Fj49gEXHL2IZIM-_T4EK9UxwN1wsyfEEgaESaSDIS1HxS_qAXauYCppmjZ6rmNlanLPmlGZvr4R09jkmBsCNFTbSkzFuMi_ukIzK6ZcBVZCmsLYZ8WJWcBbHtWbW87jjMUpxQSuGIC51unaW1fT0",ts="1681203136",nonce="gPQVk",mac="b1jGKWdy68Ml744Bb8sPiGy/8xs="'
返回内容(JSON)
name | DateType | Options | Description |
---|---|---|---|
tradeNo | number | non-nullable | 平台退款订单号 |
productId | string | non-nullable | 商品 SKU Id |
currency | string | non-nullable | 货币单位 |
outTradeNo | string | non-nullable | 外部订单号(非游戏单号) |
bankTradeNo | string | nullable | 支付渠道订单号 |
refundAmount | number | non-nullable | 退款金额 |
channelId | number | non-nullable | 渠道ID |
channelType | number | non-nullable | 渠道类型,具体见下方支付渠道枚举 |
supplyStatus | number | non-nullable | 补款状态 1:待补款 |
platform | number | non-nullable | 平台,具体见下方平台类型枚举 |
返回示例
{
"code": 200,
"msg": "ok",
"detail": "",
"data": {
"list": [
{
"tradeNo": 344625817118412801,
"productId": "cn.recharge.coin14.99",
"currency": "USD",
"outTradeNo": "344625817122607105",
"bankTradeNo": "",
"refundAmount": 14.990,
"channelId": 1,
"channelType": 1,
"supplyStatus": 1,
"platform": 1
},
{
"tradeNo": 475344677177233408,
"productId": "com.xd.sdkdemo1.stone980",
"currency": "CNY",
"outTradeNo": "475344677177233409",
"bankTradeNo": "",
"refundAmount": 108.000,
"channelId": 1,
"channelType": 1,
"supplyStatus": 1,
"platform": 1
}
]
}
}
游戏内消费通知
为了支持游戏和 TapTap 联合营销活动,游戏内购买指定道具,TapTap赠送月卡,游戏把购买事件通知到平台,平台转发给 TapTap。
- 海外域名:
https://xdsdk-intnl-6.xd.com
- 国内域名:
https://xdsdk-6.xd.cn
REST API 请求的 Base URL(下文 curl 示例中用 {{host}}
表示)。
URL | METHOD | 功能 |
---|---|---|
/order/v1/game/pay/notify | POST | 游戏内消费通知 |
请求方式
请求参数
name | DateType | Options | Description |
---|---|---|---|
userId | string | require | 用户ID |
roleId | string | require | 游戏角色ID |
serverId | string | require | 游戏服务器ID |
productCode | string | require | 商品码 |
appId | number | require | 商户应用 id |
nonce | string | require | 随机字符串 |
timestamp | number | require | 时间戳 |
sign | string | require | 签名 |
sign 字段的签算过程见 s2s md5 加密 小节。
返回数据
http code 返回200 即为成功。
请求示例
curl --location 'http://127.0.0.1:8080/order/v1/game/pay/notify' \
--data '{
"userId": "1111",
"roleId": "1111",
"serverId": "111",
"productCode": "1111",
"appId": 1010,
"nonce": "111",
"timestamp": 1714474338,
"sign": "5522ha6sc071vaxxn39p3fxco67v83g7"
}''
返回示例
{
"code": 200,
"msg": "ok",
"detail": "",
"data": true
}
安全机制
上述的 支付结果服务端回调、游戏角色信息查询、限购校验 XDSDK 都提供了如下安全机制。
白名单
如果您的游戏回调地址设置了防火墙,可以根据 服务端出口 ip 文档 获取平台的出口 ip,增加白名单。
验签
为了保证数据安全,我们提供了签名机制。为了避免多次开发,和账户注销的回调通知验签机制保持一致。如果您的游戏已经接入过账户注销的回调通知,那账户和支付的公钥是一样的。如果没有则联系我们提供。
虽然防火墙白名单起到了一定的作用,并且不对内容验签功能也能完成,但是我们还强烈建议游戏对回调内容验签以避免安全漏洞。
具体验签过程参考 服务端回调验签机制。
s2s md5 加密
- 对所有请求参数按字典顺序排序
- 把请求参数按 key1=value1&key2=value2...&key10=value10 的格式拼接
- 把秘钥拼接在上一步生成的字符串后(秘钥和平台约定)
- 对上一步生成的字符串计算md5
算法示例(php):
ksort($params);
$sign = md5($params . $appKey)
附录
trxType-交易类型枚举
code | description |
---|---|
0 | 支付 |
1 | 补单 |
2 | 退款 |
目前仅通知了「支付」和「退款」类型的交易结果,但类型以后可能会扩展。
platform-平台类型枚举
code | description |
---|---|
1 | iOS |
2 | Android |
3 | Web |
4 | macOS |
5 | Windows |
7 | Unknown |
paymentType-支付方式枚举
code | description |
---|---|
0 | APP 支付 |
1 | 移动 WAP 支付 |
2 | JSAPI |
3 | 扫码支付 |
status-订单状态枚举
code | description |
---|---|
0 | 交易成功 |
1 | 已创建 |
2 | 待支付 |
3 | 交易失败 |
4 | 已取消 |
channel-支付渠道枚举
code | description |
---|---|
1 | APPLE_PAY |
2 | GOOGLE_PAY |
3 | WECHAT_PAY |
4 | ALI_PAY |
5 | PAYPAL |
6 | TOSS |
7 | CODA |
8 | CODA_SHOP |
9 | RAZER |
10 | SMILE_ONE |
11 | UNIPIN |
12 | UNIPIN_SHOP |
13 | PING_PLUS |
14 | MY_CARD |
15 | INTL_ALI_PAY |
16 | ONE_PAY |
17 | STEAM_PAY |
目前仅在「交易成功」后发送通知。channel 类型可能会逐渐增多,建议尽量游戏不要对 channel 做特殊判断避免新增了支付渠道无法使用。
currency-标准货币代码
请参考 ISO 代码。