QQ小游戏 小游戏支付
小游戏支付
小游戏支付提供玩家在小游戏中购买道具的能力
# 业务流程
主要的流程: 1、小程序内调用登录接口,获取到用户的openid 2、开发者 server调用下单接口 4、开发者 server接收支付通知
开通小游戏支付
# 上架道具
开发者需要在QQ小程序开发者管理端上架道具
预下单
本接口应在服务器端调用,详细说明参见服务端API。
玩家购买道具前,开发者需要通过后台接口进行预下单
POST https://api.q.qq.com/api/json/openApiPay/GamePrePay?access\_token=ACCESS\_TOKEN
请求参数 | 属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|---|
openid | string | 是 | 用户唯一标识符 | ||
appid | string | 是 | 小程序 appId | ||
ts | number | 是 | UNIX 时间戳,单位是秒 | ||
zone_id | string | 是 | 游戏服务器大区id,zoneId ="1" | ||
pf | string | 是 | 平台 安卓:qq_m_qq-2001-android-2011 | ||
user_ip | string | 否 | 用户外网 IP, 不参与计算签名 | ||
amt | number | 是 | 扣除游戏币数量,不能为 0 | ||
bill_no | string | 是 | 订单号,业务需要保证全局唯一;相同的订单号不会重复扣款。长度不超过63,只能是数字、大小写字母_- | ||
goodid | string | 是 | 在开发者管理端上架道具的id | ||
good_num | int | 是 | 要购买的道具数量 | ||
app_remark | string | 否 | 备注信息,如果不为空,通知发货是会回传 | ||
sig | string | 是 | 以上参数("user_ip"字段除外,含可选最多11个)+uri+session_key,用 HMAC-SHA256签名 | ||
access_token | string | 是 | 接口调用凭证 |
返回值
Object
返回的 JSON 数据包
属性 | 类型 | 说明 |
---|---|---|
errcode | number | 错误码 |
errmsg | string | 错误信息 |
prepayId | string | 订单号,有效期是 48 小时 |
errcode 的合法值 | 值 | 说明 |
---|---|---|
0 | 请求成功 | |
-1 | 系统繁忙,此时请开发者稍候再试 | |
-3000 | access_token 校验失败,access_token需要放在url中 | |
90011 | sig签名错误 | |
90012 | 订单已存在 | |
90017 | 没有调用接口的权限 | |
90018 | 参数错误 |
POST 数据格式:JSON
{
"openid":"55107C3B8501CD7CBD90AEE4626E6D17",
"appid":"1107981003",
"ts":1507530737,
"zone_id":"1",
"pf":"qq_m_qq-2001-android-2011",
"amt":10,
"goodid":"43",
"good_num":1,
"bill_no":"69ae13a3a87f2551109a2ed26bc704201f56d664",
"app_remark":"xxxxx",
"sig":"38181bd0acf24eda203655a3be9f2e42b62d4fcf1c1de61a98b0573d13531449"
}
计算签名
1. 请求方法: POST 2. 下单url中的path(/api/json/openApiPay/GamePrePay)部分,做标准的url Encoding, 标准请参考《URL Encoding 》
3. 请求参数按字典排序,并用"&"拼接, 注意空字段不参与排序
amt=10&app_remark=xxxxx&appid=1107981003&bill_no=69ae13a3a87f2551109a2ed26bc704201f56d664&good_num=1&goodid=43&openid=55107C3B8501CD7CBD90AEE4626E6D17&pf=qq_m_qq-2001-android-2011&ts=1507530737&zone_id=1
4. 拼接session_key,用户登录时开发者后台可以通过code2session接口获取到
session_key=VUNQZ0hRYURxNlZZbmNOZw==
5. 签名前的字符串如下图
POST&%2Fapi%2Fjson%2FopenApiPay%2FGamePrePay&amt=10&app_remark=xxxxx&appid=1107981003&bill_no=69ae13a3a87f2551109a2ed26bc704201f56d664&good_num=1&goodid=43&openid=55107C3B8501CD7CBD90AEE4626E6D17&pf=qq_m_qq-2001-android-2011&ts=1507530737&zone_id=1&session_key=VUNQZ0hRYURxNlZZbmNOZw==
6.HMAC-SHA256得到的签名结果
$h = hash_hmac('sha256', 'POST&%2Fapi%2Fjson%2FopenApiPay%2FGamePrePay&amt=10&app_remark=xxxxx&appid=1107981003&bill_no=69ae13a3a87f2551109a2ed26bc704201f56d664&good_num=1&goodid=43&openid=55107C3B8501CD7CBD90AEE4626E6D17&pf=qq_m_qq-2001-android-2011&ts=1507530737&zone_id=1&session_key=VUNQZ0hRYURxNlZZbmNOZw==', 'VUNQZ0hRYURxNlZZbmNOZw==', true);
var_dump(bin2hex($h));
签名:
38181bd0acf24eda203655a3be9f2e42b62d4fcf1c1de61a98b0573d13531449
请求参数
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
openid | string | 是 | 用户唯一标识符 | |
bill_no | string | 是 | 订单号,业务需要保证全局唯一;相同的订单号不会重复扣款。长度不超过63,只能是数字、大小写字母 | |
amt | number | 是 | 扣除游戏币数量,不能为 0 | |
ts | number | 是 | UNIX 时间戳,单位是秒 | |
app_remark | string | 否 | 备注信息,如果为空,不参与计算签名 | |
sig | string | 是 | 以上所有参数(含可选最多11个)+appsecret HMAC-SHA256签名 |
回调地址 这里的回调地址是示例,以开发者在管理端 配置的为准 http://test.com/pay/callback 1
POST 数据格式:JSON
app_remark字段为空时,回调消息如下:
{
"openid": "55107C3B8501CD7CBD90AEE4626E6D17",
"bill_no":"BillNo_123",
"amt":123,
"ts":1553322984,
"sig": "1d7d3b724601a0b55a43e03f140ce55322401fedd359b1ea1dfc96a02f6e6f36"
}
app_remark字段不空时,回调消息如下:
{
"openid": "55107C3B8501CD7CBD90AEE4626E6D17",
"bill_no":"BillNo_123",
"amt":123,
"ts":1553322984,
"app_remark":"xxxxx",
"sig": "1d7d3b724601a0b55a43e03f140ce55322401fedd359b1ea1dfc96a02f6e6f36"
}
签名
为了确保,QQ会对明文数据进行签名。开发者可以根据业务需要对数据包进行签名校验,确保数据的完整性。
- 用户的 AppSecret:
HyVFkGl5F5OQWJZZaNzBBg==
- 用于签名的字符串为: 对开发者在管理端 配置回调url中的path部分,做标准的url Encoding, 标准请参考《URL Encoding 》
strPath=url.QueryEscape("/pay/callback") // 这里要替换成开发者在管理端配置的链接
3.计算签名时,没有值的参数不参与签名,所有参与签名的参数按字典序排序,这里以app_remark为空时的回调签名为例,app_remark不空时,需要参与签名
strData="POST&"+strPath+"&amt=123&bill_no=BillNo_123&openid=55107C3B8501CD7CBD90AEE4626E6D17&ts=1553322984&AppSecret=HyVFkGl5F5OQWJZZaNzBBg=="
// 计算签名前的字符串:
POST&%2Fpay%2Fcallback&amt=123&bill_no=BillNo_123&openid=55107C3B8501CD7CBD90AEE4626E6D17&ts=1553322984&AppSecret=HyVFkGl5F5OQWJZZaNzBBg==
4.hmac使用sha256算法得到的结果为
计算得到的签名:
f749f67b751fa80f27ddc0b7c8d2821aeda162ea22b323cd64a2c8056c2736f0
5.PHP示例
$h = hash_hmac('sha256', 'POST&%2Fpay%2Fcallback&amt=123&bill_no=BillNo_123&openid=55107C3B8501CD7CBD90AEE4626E6D17&ts=1553322984&AppSecret=HyVFkGl5F5OQWJZZaNzBBg==', 'HyVFkGl5F5OQWJZZaNzBBg==', true);
var_dump(bin2hex($h));
返回值
回调接口需要返回一个json
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
code | number | 是 | code等于0,表示成功,其他是失败 | |
msg | string | 是 | 错误描述 |
{
"code":0,
"msg":""
}
查询支付状态 本接口应在服务器端调用,详细说明参见服务端API。 玩家下单购买道具后,如果开发商没有收到支付支付通知,可以通过这个接口查询支付结果
POST
https://api.q.qq.com/api/json/openApiPay/CheckGamePay?access_token=ACCESS_TOKEN
查询余额
本接口应在服务器端调用,详细说明参见服务端API。
POST https://api.q.qq.com/api/json/openApiPay/GetBalance?access_token=ACCESS_TOK
请求参数
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
openid | string | 是 | 用户唯一标识符 | |
appid | string | 是 | 小程序 appId | |
sig | string | 是 | 以上参数("user_ip"字段除外,含可选最多11个)+uri+session_key,用 HMAC-SHA256签名 | |
access_token | string | 是 | 接口调用凭证 |
返回值
Object
返回的 JSON 数据包
属性 | 类型 | 说明 |
---|---|---|
errcode | number | 错误码 |
errmsg | string | 错误信息 |
remainder | number | 金币余额 |
errcode 的合法值
值 | 说明 |
---|---|
0 | 请求成功 |
-1 | 系统繁忙,此时请开发者稍候再试 |
-3000 | access_token 校验失败,access_token需要放在url中 |
90011 | sig签名错误 |
POST 数据格式:JSON
{
"openid":"55107C3B8501CD7CBD90AEE4626E6D17",
"appid":"1107981003",
"sig":"9a721574bbf7fbfc68f15edd7e9cc355d6a95e2d946ecd4e04b708c4206665b4",
}
计算签名
1.请求方法: POST 2.下单url中的path(/api/json/openApiPay/GetBalance)部分,做标准的url Encoding, 标准请参考《URL Encoding 》 3.请求参数按字典排序,并用"&"拼接, 注意空字段不参与排序
appid=1107981003&openid=55107C3B8501CD7CBD90AEE4626E6D17```
4.拼接session_key,用户登录时开发者后台可以通过code2session接口获取到
session_key=VUNQZ0hRYURxNlZZbmNOZw==
5.签名前的字符串如下图
POST&%2Fapi%2Fjson%2FopenApiPay%2FCheckGamePay&appid=1107981003&bill_no=69ae13a3a87f2551109a2ed26bc704201f56d664&openid=55107C3B8501CD7CBD90AEE4626E6D17&prepay_id=beaf257883b098007ca821e1c59f7f7a&session_key=VUNQZ0hRYURxNlZZbmNOZw==```
6.HMAC-SHA256得到的签名结果
$h = hash_hmac('sha256', 'POST&%2Fapi%2Fjson%2FopenApiPay%2FCheckGamePay&appid=1107981003&bill_no=69ae13a3a87f2551109a2ed26bc704201f56d664&openid=55107C3B8501CD7CBD90AEE4626E6D17&prepay_id=beaf257883b098007ca821e1c59f7f7a&session_key=VUNQZ0hRYURxNlZZbmNOZw==')
var_dump(bin2hex($h));
签名:
9a721574bbf7fbfc68f15edd7e9cc355d6a95e2d946ecd4e04b708c4206665b4