支付配置
收藏
我的收藏简介
为了保证「小游戏」的资金和互动数据的安全性,我们提供了一套鉴权认证机制。
当且仅当鉴权认证通过之后,才允许执行相应的接口逻辑。
规则说明
基本规则
- •基本信息
API请求必须使用HTTPS。
- •数据格式
Content-Type: application/json Accept: application/json
- •参数兼容性
鉴权认证与请求参数的顺序无关。
- •请求的唯一标示
「开放平台」会给每一个接收到的请求分配一个唯一标示,该标示包含在应答的HTTP头
x-tt-logid
中。当需要「开放平台」帮助时,请提供请求的唯一标示,以便我们更快的定位到具体的请求。
HTTP状态码
状态码 | 错误类型 | 解决方案 |
200 | 无 | 无需处理 |
非200 | 网络等原因导致请求未成功发送 | 采用重试策略 |
密钥介绍
鉴权认证机制采用
SHA256-RSA2048
实现。使用说明
在鉴权认证机制中,需要4个密钥,分别为
- •平台公钥
每个「小游戏」对应的平台公钥是不一样的,平台公钥由「开放平台」负责生成,并告知「小游戏」开发者。
- •平台私钥
每个「小游戏」对应的平台私钥是不一样的,平台私钥由「开放平台」负责生成和保存。
- •应用公钥
「小游戏」的应用公钥由开发者生成并上传到「开放平台」,可支持更换。
- •应用私钥
「小游戏」的应用私钥由开发者生成并保存,不能对外提供,可支持更换。
交互方式如下图所示
应用公钥
生成方式
应用公钥和私钥的生成方式可参考
$ openssl OpenSSL> genrsa -out private_key.pem 2048 Generating RSA private key, 2048 bit long modulus ....................+++ ...........................................................................+++ e is 65537 (0x10001) OpenSSL> rsa -in private_key.pem -pubout -out public_key.pem writing RSA key OpenSSL> exit $ ls private_key.pem public_key.pem
注意❗️:应用私钥务必妥善保存,不能对外公开。当发现应用私钥泄漏之后,应及时重新生成,并将新应用公钥上传到「开放平台」。
上传方式
前期接入可联系运营,以文档形式收集应用公钥并完成配置
- 1.登陆「抖音小游戏开发者平台」,进入小游戏的「商业化-激励能力-支付设置」页面。
- 2.点击「添加游戏公钥」,即可进行公钥录入。
- 3.完成公钥的录入后需点击「游戏公钥验证」进行验证,也可在必要时进行编辑
平台公钥
平台公钥和私钥由「开放平台」负责生成和保存,不同「小游戏」的平台公钥和私钥是不同的。
- •获取方式
- 1.无需单独处理,平台会为每个游戏提供平台公钥,登陆「字节小游戏平台」,进入小游戏的「商业化-金币激励-支付设置」页。
签名介绍
- •签名
「开放平台」通过验证签名来保证请求的真实性和数据的完整性。
- •请求签名
「小游戏」首先需要对URL、消息体等关键数据进行拼接组合,使用应用私钥对组合后的数据进行
SHA256-RSA2048
签名。签名信息通过HTTP头Byte-Authorization
传递。「开放平台」会拒绝没有携带签名或者签名验证不通过的请求,并返回对应验签失败的错误信息 。
- •应答签名
「开放平台」会执行签名验证成功的请求,并使用 平台私钥对应答数据进行签名,签名的信息包含在HTTP头部。「小游戏」应拒绝没有携带签名信息的成功应答(HTTP状态码为2xx),应认为是被伪造的或被篡改的应答。
- •回调通知签名
当能力接口涉及回调通知结果时,「开放平台」使用平台私钥对回调通知请求进行签名。签名的方法同应答签名的方法一致,「小游戏」务必验证回调通知请求的签名信息。
开发指南
签名生成
「小游戏」应按照下述步骤生成请求的签名信息。
- •构造待签名串
待签名串一共有五行,每一行为一个参数。行尾以
\n
(换行符,ASCII编码值为0x0A)结束,包括最后一行。如果参数本身以\n
结束,也需要附加一个\n
。最终格式如下HTTP请求方法\n URL\n 请求时间戳\n 请求随机串\n 请求报文主体\n
其中:•HTTP请求方法
如:POST,GET,PUT等。•URL
获取请求的绝对URL,并去除域名部分得到参与签名的URL。去除域名后的部分,必须以斜杠字符“/”开头。如果去除域名后的部分为空,则用单个斜杠字符“/”来当作URL用于签名。如果请求中有查询参数,URL末尾应附加有'?'和对应的查询字符串。如:URL则为/mgplatform/api/apps/open/pay
•请求时间戳
发起请求时系统的当前时间戳,即格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数,作为请求时间戳。「开放平台」会拒绝处理一个小时之前发起的请求。命令可参考:date +%s
•请求随机串
任意生成一个随机字符串,以保证相同时间相同参数发起的请求签名值不一样(我们推荐生成随机串算法如下:调用随机数函数生成,将得到的值转换为字符串)。命令可参考:hexdump -n 16 -e '4/4 "%08X" "\n"' /dev/random
•请求报文主体
获取请求中的请求报文主体(request body)。1.请求方法为GET时,报文主体为空。
2.当请求方法为POST或PUT时,请使用JSON报文内容。
- •计算签名值
「小游戏」成功构造待签名串后,「小游戏」使用应用私钥对待签名串进行
SHA256-RSA2048
签名,并对签名结果进行Base64
编码得到签名值。签名命令可参考
$ echo -n -e \ "POST\n/api/business/diamond/query\n1623934869\nDC10180A100073E70A48F195DA2AF2E6\n{\"appid\":\"ttxxx\",\"order_id\":\"xxx\"}\n" \ | openssl dgst -sha256 -sign private_key.pem | openssl base64 -A nwd1L3wCX+01/TVTkILeovF1DtYeghC1VHjrcjTHVkh7+gRaONEQkC2Y72Mw8JdSnIyeAtyp/pDHzyKGywjVqv5+JOBEhQG1/pvwNHN49wD26qg3AJL4hXw0fMJSRiTQEV1MszwDLuaabvo/qM9OXL9KyYiEPwVJqYtzmho4cHXT6mYgzNOW1xt5d7RDf4QO74JI3i4dtk9Uj8svJTrrBabML6AUcqcx2OP/7xukdaUgPdPf+IqmMG6GC4n52LUDogcL5n/osLdfHg9l6kW5gDcDjBfNDaggz07QMPHGdVao7pnQ2ub7VqcFIuY6Q3cBL7ndQdDGKrv+WBy5Q90QjQ==
- •设置HTTP Header
签名信息通过HTTP头
Byte-Authorization
传递,Byte-Authorization
由认证类型和签名信息两部分组成。Byte-Authorization: 认证类型 签名信息
•认证类型
目前为SHA256-RSA2048
•签名信息
1.应用
appid
2.请求随机串
nonce_str
3.请求时间戳
timestamp
4.公钥版本
key_version
5.签名值
signature
注意⚠️:1.以上五项签名信息,无顺序要求
2.请求随机串和请求时间戳必须和计算签名值时使用的请求随机串和请求时间戳保持一致
3.公钥版本必须填写计算签名值时采用的应用私钥对应的应用公钥版本,应用公钥版本可通过「开发管理-开发设置-密钥设置」处获取
示例如下
Byte-Authorization: SHA256-RSA2048 appid="ttxxx",nonce_str="DC10180A100073E70A48F195DA2AF2E6",timestamp="1623934869",key_version="1",signature="nwd1L3wCX+01/TVTkILeovF1DtYeghC1VHjrcjTHVkh7+gRaONEQkC2Y72Mw8JdSnIyeAtyp/pDHzyKGywjVqv5+JOBEhQG1/pvwNHN49wD26qg3AJL4hXw0fMJSRiTQEV1MszwDLuaabvo/qM9OXL9KyYiEPwVJqYtzmho4cHXT6mYgzNOW1xt5d7RDf4QO74JI3i4dtk9Uj8svJTrrBabML6AUcqcx2OP/7xukdaUgPdPf+IqmMG6GC4n52LUDogcL5n/osLdfHg9l6kW5gDcDjBfNDaggz07QMPHGdVao7pnQ2ub7VqcFIuY6Q3cBL7ndQdDGKrv+WBy5Q90QjQ=="
请求示例如下
curl -v -d '{"appid":"ttxxx","order_id":"xxx"}' -H 'Byte-Authorization: SHA256-RSA2048 appid="ttxxx",nonce_str="DC10180A100073E70A48F195DA2AF2E6",timestamp="1623934869",key_version="1",signature="nwd1L3wCX+01/TVTkILeovF1DtYeghC1VHjrcjTHVkh7+gRaONEQkC2Y72Mw8JdSnIyeAtyp/pDHzyKGywjVqv5+JOBEhQG1/pvwNHN49wD26qg3AJL4hXw0fMJSRiTQEV1MszwDLuaabvo/qM9OXL9KyYiEPwVJqYtzmho4cHXT6mYgzNOW1xt5d7RDf4QO74JI3i4dtk9Uj8svJTrrBabML6AUcqcx2OP/7xukdaUgPdPf+IqmMG6GC4n52LUDogcL5n/osLdfHg9l6kW5gDcDjBfNDaggz07QMPHGdVao7pnQ2ub7VqcFIuY6Q3cBL7ndQdDGKrv+WBy5Q90QjQ=="' -H 'Content-Type: application/json' -H 'Accept: application/json' -X POST https://webcast.bytedance.com/api/business/diamond/query
签名验证
「小游戏」应按照下述步骤验证成功应答(HTTP状态码为2xx)的签名信息。
- •构造验签名串
应答验签名串一共有三行,每行以
\n
结束,包括最后一行。\n
为换行符(ASCII编码值为0x0A)。若应答报文主体为空(如:HTTP状态码为204 No Content
),最后一行仅为一个\n
换行符。应答时间戳\n 应答随机串\n 应答报文主体\n
•应答时间戳
从应答HTTP头Byte-Timestamp
中获取应答时间戳。•应答随机串
从应答HTTP头Byte-Nonce-Str
中获取应答随机串。•应答报文主体
应答中的应答JSON报文主体(response body)。
- •获取应答签名
应答签名值通过HTTP头
Byte-Signature
传递。如:Byte-Signature: hWsiaADxS4OKLW/0JpDXiiji+GNRIsnnXsux3nVdyk7X6dqoyyJVYloQR9h/C1DIhGeBKe0i1iciyp6uq4LIkScyQKLhwEaXnWpcYat3+SAgS3ZYcGFY/op/MTO1bf172wbQBamC6gwydOWF0tWlMQb33ZYhztEDnD8iw/JkogOGHjO5uo869xWbgcq0OrkRN4zPGpOc/eiOR/B7fzxbasdMZtENOQMpgPP0z3k/cgeG/DSOwtwfA0eYnpYC8YqvKZ52HI5aCPkexmkfzUqNl1tbVylbMKDQDQoipQSxQPK2fxOFHj+jYu1TQ+nQFeu6amU/1rsMbT8JWa94bwwgkg==
对
Byte-Signature
的签名值使用Base64
解码,得到应答签名。- •校验签名
使用平台公钥对验签名串和应答签名进行
SHA256-RSA2048
签名验证。签名验证命令可参考:
# 1. 把Byte-Signature的签名值使用Base64解码,并保存到sign.txt文件中 $ openssl base64 -d -A <<< 'hWsiaADxS4OKLW/0JpDXiiji+GNRIsnnXsux3nVdyk7X6dqoyyJVYloQR9h/C1DIhGeBKe0i1iciyp6uq4LIkScyQKLhwEaXnWpcYat3+SAgS3ZYcGFY/op/MTO1bf172wbQBamC6gwydOWF0tWlMQb33ZYhztEDnD8iw/JkogOGHjO5uo869xWbgcq0OrkRN4zPGpOc/eiOR/B7fzxbasdMZtENOQMpgPP0z3k/cgeG/DSOwtwfA0eYnpYC8YqvKZ52HI5aCPkexmkfzUqNl1tbVylbMKDQDQoipQSxQPK2fxOFHj+jYu1TQ+nQFeu6amU/1rsMbT8JWa94bwwgkg==' > sign.txt # 2. 验证签名 $ openssl dgst -sha256 -verify public_key.pem -signature sign.txt << EOF 1623934990 49F0B152663446B14D57DDCA0D5418DB {"order_id":"xxx","order_status":2,"open_id":"openid","pay_tag":"参与游戏"} EOF Verified OK