跳到主要内容

支付通知

OmniSDK 服务器在收到渠道的订单支付成功通知时,会主动调用支付通知 URL 通知游戏服务器订单支付信息

游戏通知地址根据优先级的先后,可通过以下三种方式提供:

  • 支付时将通知地址传给 OmniSDK

  • 提供一个用于特定版本和特定渠道的通知地址,由运营同学配置到 OmniSDK 管理后台

  • 提供一个统一的通知地址,由运营同学配置到 OmniSDK 管理后台

游戏服务器在接收到支付通知时,应再次调用 OmniSDK 提供的订单查询接口,验证订单信息的一致性,否则一旦服务端密钥泄漏,就有可能遭受伪造订单通知攻击。

提示

如游戏无支付需求,则无需接入支付通知。

支付通知接口

当接收到渠道的支付结果回调信息后,OmniSDK 服务端会对订单支付信息进行确认,确认后 OmniSDK 服务端会将订单支付结果信息推送到游戏服务器提供的支付订单回调地址。

备注

此通知有重试机制。根据返回值的不同会进行指数后退重试 24 小时。若游戏服务器的返回值为 1,则判断为主动请求重试,会不断重试直到成功。

此接口的发起方为 OmniSDK 服务端,接收方为游戏服务器,游戏方提供 URL,服务器主动调用

  • 接口类型为 HTTP POST
  • Content-Type: application/json;charset=UTF-8
  • 使用签名

参数说明

NameTypeMax LengthDescriptionMust
typeString32接口类型,固定为字符串: notify-gameYes
xgAppIdString64OmniSDK 分配给游戏的唯一 IDYes
channelIdString32渠道 IDYes
uidString128用户 IDYes
zoneIdString32游戏区编号No
serverIdString32游戏服编号No
roleIdString32角色编号Yes
roleNameString64角色名称No
roleLevelString32角色等级No
roleVipLevelString32角色 VIP 等级No
currencyNameString64支付商品价格货币代码,如 CNY、USD(国际货币代码)No
productIdString64商品编号Yes
productNameString64商品名称No
productDescString128商品描述No
productQuantityString10商品数量No
productUnitPriceString10商品单价(单位:分)No
totalAmountString10总面额(单位:分)Yes
paidAmountString10总支付金额(单位:分)Yes
customInfoString2000游戏方创建订单时自定义字段,透传给游戏服务器No
tsString14当前时间表达式,秒级,如 20150723150028 对应 2015/7/23 15:00:28Yes
gameTradeNoString64游戏订单号No
signString40详见文档签名与验签,使用 OmniSDK 分配给用游戏的服务端密钥Yes
tradeNoString64OmniSDK 订单号Yes
paidTimeString14支付时间 yyyyMMddHHmmss,格式参考 ts 字段Yes
payStatusString1订单支付状态: 1 表示支付成功 2 表示支付失败Yes
payTypeString20订单支付类型, 内购没有此字段,网页支付:WebPayNo
extString2000参看 EXT 支付扩展参数 JSON 字段说明No

EXT 支付扩展参数 JSON 字段说明

KeyTypeDescription
isSandboxBool是否是沙箱环境
isTrialPeriodBool是否是试用期
cancellationDateString取消订阅时间
expiresDateString订阅过期时间
paidCurrencyNameString实际支付的商品币种代码,如 CNY、USD(国际货币代码,游戏可利用此字段与 currencyName 进行对比做业务逻辑处理

返回结果

游戏服务器处理完支付通知后,应返回如下格式的 JSON 字符串

NameDescription
code返回码,0 代表成功。详情请参考错误码章节中 支付通知错误码
msg接口调用信息提示

请求样例

请求示例
POST foobar HTTP/1.1
Host: foobar.com
Content-Type: application/json

{
"type": "notify-game",
"xgAppId": "2018",
"channelId": "mi",
"uid": "mi__3099245",
"zoneId": "1",
"serverId": "1",
"roleId": "224455",
"roleName": "八神",
"roleLevel": "42",
"roleVipLevel": "8",
"currencyName": "CNY",
"productId": "com.mygame.diamond600",
"productName": "600钻石",
"productDesc": "6元购买600钻石",
"productQuantity": "600",
"totalAmount": "600",
"paidAmount": "600",
"customInfo": "foo",
"gameTradeNo": "20160325000001",
"tradeNo": "31602f1000000001",
"paidTime": "20150723145928",
"payStatus": "1",
"ts": "20150723150028",
"ext": {
"cancellationDate": "20160901201417",
"expiresDate": "20160901201417",
"isSandbox": true,
"originalTradeNo": "016q2f1000303885"
},
"sign": "4873560491111c3f719dada104a0b055e2531d8f"
}
请求签名原始字符串
channelId=mi&currencyName=CNY&customInfo=foo&ext={"cancellationDate": "20160901201417","expiresDate": "20160901201417","isSandbox": true,"originalTradeNo": "016q2f1000303885"}&gameTradeNo=20160325000001&paidAmount=600&paidTime=20150723145928&payStatus=1&productDesc=6元购买600钻石&productId=com.mygame.diamond600&productName=600钻石&productQuantity=600&roleId=224455&roleLevel=42&roleName=八神&roleVipLevel=8&serverId=1&totalAmount=600&tradeNo=31602f1000000001&ts=20150723150028&type=notify-game&uid=mi__3099245&xgAppId=2018&zoneId=1
游戏服务端密钥及签名
密钥:aca57f8a6c494a36a516e5c282c4db87
签名:60ebcd07edf4e0563c8632c53be5af6df07f3400
返回结果
{
"code": "0",
"msg": "success"
}
警告

注意:请动态拼接所有参数(方便以后添加新参数时自动加入签名),所有非空的参数都参与签名,值为空的参数不参与签名,按参数名字自然升序排列)

信息

游戏支付通知返回值处理注意事项

为了避免被人网络截包篡改充值数据,需要游戏服务器收到充值通知后,按如下逻辑来实现校验充值数据,并到 OmniSDK 服务器再次验证:

  • 如遇服务升级不能响应,则需返回 { "code": "1" }

  • 先要进行验证签名,不通过则需返回 { "code": "-1" }

  • 如果游戏保留了游戏订单但找不到对应订单时,则需返回 { "code": "-6" }

  • 做订单排重,如果重复则需返回 { "code": "2" }

  • 如果游戏保留了游戏订单,最好能够验证 OmniSDK 订单和游戏订单的一致性,如 productIdproductQuantitypaidAmountuidroleId保证人、财、物是一致的,避免有人在网络截获包,同时密钥泄露时,冒充发送通知。如果验证不一致,返回 { "code": "-98" }

  • 二次查询验证订单,如果订单不存在或者返回的订单信息不一致时,需返回 { "code": "-98" }

  • 如果游戏系统发生内部异常,则需返回 { "code": "-99" }

若以上7步都正常,则返回 { "code": "0" }

订单查询验证

此接口用于游戏服务器验证收到的订单通知是否正确有效。

接口的发起方为游戏服务端,接收方为 OmniSDK 服务器

  • 接口类型为 HTTP GET
  • 字符集编码为 UTF-8
  • 使用签名

请求地址为:

https://a2.xgsdk.seayoo.com/pay/verify-order/{omniAppId} 

其中 omniAppId 是 OmniSDK 分配的游戏编号。

参数说明

NameTypeMax LengthDescriptionMust
typeString32接口类型,固定为 verify-orderYes
tradeNoString32OmniSDK 订单号Yes
tsString14当前时间表达式,秒级,如 20150723150028 对应 2015/7/23 15:00:28Yes
signString40详见文档签名与验签,使用 OmniSDK 分配给用游戏的服务端密钥Yes

返回结果

OmniSDK服务器处理完查询后,应返回如下格式的JSON字符串

NameDescription
code返回码,0 代表成功。详情请参考错误码章节中 查询订单错误码
msg接口调用信息提示
data订单数据

data 字段具体说明:

NameTypeMax LengthDescriptionMust
typeString32接口类型,固定为字符串:notify-gameYes
xgAppIdString64OmniSDK 分配给游戏的唯一 IDYes
channelIdString32渠道 IDYes
uidString128用户 IDYes
zoneIdString32游戏区编号No
serverIdString32游戏服编号No
roleIdString32角色编号Yes
roleNameString64角色名称No
roleLevelString32角色等级No
roleVipLevelString32角色 VIP 等级No
currencyNameString64支付货币名称No
productIdString64商品编号Yes
productNameString64商品名称No
productDescString128商品描述No
productQuantityString10商品数量No
productUnitPriceString10商品单价(单位:分)No
totalAmountString10总面额(单位:分)Yes
paidAmountString10总支付金额(单位:分)Yes
customInfoString2000游戏方创建订单时自定义字段,透传给游戏服务器No
tsString14当前时间表达式,秒级,如 20150723150028 对应 2015/7/23 15:00:28Yes
gameTradeNoString64游戏订单号No
signString40详见文档签名与验签,使用 OmniSDK 分配给用游戏的服务端密钥Yes
tradeNoString64OmniSDK 订单号Yes
paidTimeString14支付时间 yyyyMMddHHmmss,格式参考 ts 字段Yes
payStatusString1订单支付状态: 1 支付成功,2 支付失败Yes
payTypeString20订单支付类型, 内购没有此字段,网页支付:WebPayNo
extString2000iOS 支付订阅扩展参数No

请求样例

请求参数
tradeNo: 31602f1000000001

当前时间戳ts: 20150723150028

游戏服务端密钥: aca57f8a6c494a36a516e5c282c4db87
请求签名原始字符串及签名
请求签名源串为:tradeNo=2984456&ts=20150723150028&type=verify-order

签名为:516b7da2faa4f1c27f70209eec32a29935b8f80d
请求示例
https://a2.xgsdk.seayoo.com/pay/verify-order/2018?tradeNo=31602f1000000001&ts=20150723150028&type=verify-order&sign=516b7da2faa4f1c27f70209eec32a29935b8f80d
响应签名原始字符串及签名
响应签名源串为:channelId=ios_jinshanApple&currencyName=CNY&customInfo={"guid":"061EBC8F-EEAA-b438-23FF-5D245001D707","createtime":"1641525026","serverId":20231201}&ext={"originalTradeNo":"122j261034971318","isRefund":"1","isTrialPeriod":false,"isSandbox":false,"refundDate":"20220107053903","refundAmount":"1800"}&gameTradeNo=18337670027887102412&paidAmount=0&paidTime=20220108215058&payStatus=1&productDesc=开启初入江湖礼包,可获得10个绿玄晶、4个真元丹、3个黄金钥匙、3个黄金宝箱。&productId=jxsj3.libao.cuxiao18&productName=初入江湖礼包&productQuantity=1&productUnitPrice=0&roleId=100321&roleLevel=23&roleName=慕容军&serverId=2312&totalAmount=1800&tradeNo=122q2d1000708125&ts=20220108215058&type=notify-game&uid=ios_jinshanApple__b304cacec191f055992819__EXP_.&xgAppId=111111551&zoneId=2312

签名为:8a76ba82cf1dd26b91d6cc5d86162c57b8d521c1
响应示例
{
"code": "0",
"msg": "success",
"data": {
"type": "verify-order",
"xgAppId": "2018",
"channelId": "mi",
"uid": "mi__3099245",
"zoneId": "1",
"serverId": "1",
"roleId": "224455",
"roleName": "八神",
"roleLevel": "42",
"roleVipLevel": "8",
"currencyName": "CNY",
"productId": "com.mygame.diamond600",
"productName": "600钻石",
"productDesc": "6元购买600钻石",
"productQuantity": "600",
"totalAmount": "600",
"paidAmount": "600",
"customInfo": "foo",
"ts": "20150723150028",
"gameTradeNo": "20160325000001",
"sign": "9986011d474d1bb6cc927b0a1c7600aa074b7e89"
"tradeNo": "31602f1000000001",
"paidTime": "20150723145928",
"payStatus": "1",
"ext":"{\"cancellationDate\": \"20160901201417\",\"expiresDate\": \"20160901201417\",\"isSandbox\": true,\"originalTradeNo\": \"016q2f1000303885\",\"isTrialPeriod\":true}"
}
}
警告

注意:请动态拼接所有参数(方便以后添加新参数时自动加入签名),所有非空的参数都参与签名,值为空的参数不参与签名,按参数名字自然升序排列)

退款通知接口

提示

用于通知游戏服务器退款结果,目前仅限于iOS

当接收到渠道的支付退款回调信息后,OmniSDK 服务端会将退款信息推送到游戏服务器提供的退款回调地址。

备注

此通知OmniSDK有重试机制。

此接口的发起方为 OmniSDK 服务端,接收方为游戏服务器,游戏方提供 URL,OmniSDK 服务器主动调用

  • 接口类型为 HTTP POST
  • Content-Type: application/json;charset=UTF-8
  • 使用签名。

参数说明

NameTypeMax LengthDescriptionMust
typeString32接口类型,固定为字符串: notify-gameYes
xgAppIdString64OmniSDK 分配给游戏的唯一 IDYes
channelIdString32渠道 IDYes
uidString128用户 IDYes
zoneIdString32游戏区编号No
serverIdString32游戏服编号No
roleIdString32角色编号Yes
roleNameString64角色名称No
roleLevelString32角色等级No
roleVipLevelString32角色 VIP 等级No
currencyNameString64支付商品价格货币代码,如 CNY、USD(国际货币代码)No
productIdString64商品编号Yes
productNameString64商品名称No
productDescString128商品描述No
productQuantityString10商品数量No
productUnitPriceString10商品单价(单位:分)No
totalAmountString10总面额(单位:分)Yes
paidAmountString10总支付金额(单位:分)Yes
customInfoString2000游戏方创建订单时自定义字段,透传给游戏服务器No
tsString14当前时间表达式,秒级,如 20150723150028 对应 2015/7/23 15:00:28Yes
gameTradeNoString64游戏订单号No
signString40详见文档签名与验签,使用 OmniSDK 分配给用游戏的服务端密钥Yes
tradeNoString64OmniSDK 订单号Yes
paidTimeString14支付时间 yyyyMMddHHmmss,格式参考 ts 字段Yes
payStatusString1订单支付状态: 1 表示支付成功 2 表示支付失败Yes
payTypeString20订单支付类型, 内购没有此字段,网页支付:WebPayNo
extString2000参看 EXT 支付扩展参数 JSON 字段说明No

EXT 支付扩展参数 JSON 字段说明

KeyTypeDescription
isRefundString是否是退款, 1表示退款
isSandboxBool是否是沙箱环境
isTrialPeriodBool是否是试用期
refundDateString退款时间表达式,秒级,如 20150723150028 对应 2015/7/23 15:00:28
refundAmountString退款金额

返回结果

游戏服务器处理完支付通知后,应返回如下格式的 JSON 字符串

NameDescription
code返回码,0 代表成功。详情请参考支付通知错误码
msg接口调用信息提示

请求样例

请求示例
POST foobar HTTP/1.1
Host: foobar.com
Content-Type: application/json

{
"channelId": "ios_jinshanApple",
"channelTradeNo": "6941",
"currencyName": "CNY",
"ext": {
"isRefund": "1",
"isTrialPeriod": false,
"isSandbox": false,
"refundDate": "20230917101110",
"refundAmount": "3000"
},
"gameTradeNo": "3f9636851b52c04a363cd5",
"paidAmount": "3000",
"paidTime": "20230916105714",
"payStatus": "1",
"productDesc": "首次充值可获得双倍奖励",
"productId": "10086",
"productName": "300钻石",
"productQuantity": "1",
"productUnitPrice": "30",
"roleId": "123744619726391",
"roleLevel": "111",
"roleName": "foobar",
"roleVipLevel": "2",
"serverId": "0",
"sign": "75e065ec4619dea9014a95bccf4dc6fb6",
"totalAmount": "3000",
"tradeNo": "92302e10487547",
"ts": "20230917102743",
"type": "notify-game",
"uid": "jinshan__2c02c7b8868__EXP_.",
"xgAppId": "1150",
"zoneId": "0"
}