虎牙小游戏 - 服务端
登陆
1. 概述
用户在终端打开小游戏后,需要先调用 login() 接口,获得用户授权码(code),然后通过虎牙开放平台的服务端接口校验登录态,并获得当前登录用户的信息。
2. 流程简介
以下是小游戏登录的流程图:
流程图中的接口1即为登录态校验接口,该接口返回两个用户身份标识:
- open_id:应用维度用户唯一身份标识,不同小游戏下,同一用户的open_id不相同
- union_id:开发者维度用户唯一身份标识,同一开发者不同小游戏下,同一用户的union_id相同
建议使用union_id作为用户的唯一身份标识,后续的支付流程中会使用到union_id。
支付
1. 概述
用户第三方支付,小游戏提供在虎牙直播客户端唤起第三方支付组件的能力。
2. 权限申请
联系开放平台运营人员申请开通支付权限,您需要提供以下信息:
- 小游戏ID:即小程序ID,可以在开发者中心的小程序概要页面获得
- 支付回调地址:用于接收用户成功发起支付请求后的回调信息
3. 流程简介
以下是第三方支付的流程图:
关键步骤
- 开发者服务端请求预下单接口①,获得虎牙生成的支付订单号。
- 小游戏根据使用支付订单号作为参数,调用SDK拉起支付组件②。
- 虎牙处理完用户的支付请求后,向开发者回调地址③发起HTTP POST请求,通知支付结果。
其他流程由开发者根据业务自行设计,例如小游戏在等待支付结果期间如何表现,未收到回调时如何提示用户等。
签名方式
在调用接口时,需要进行参数签名,通过拼接 开发者ID(appId)、开发者密钥(appSecret) 与业务请求参数,然后进行MD5加密,具体的参数拼接方式请查看接口文档。
接口文档
1. 预下单接口
服务器需要通过此接口,获得订单号,才可以在前端拉起支付组件。
ip白名单申请
接口调用前请完成服务器ip白名单配置,支持多个(以英文逗号分隔)。
接口说明
- 请求终端:服务端
- 接口地址:https://apiext.huya.com/thirdpartypay/prePayOrder
- 请求方式:POST
鉴权方式
按照统一鉴权说明生成对应的鉴权sToken(即JWT token),写入Header中的authorization字段中。
注意:其中Payload需要做以下调整:
payload参数:
| 参数名称 | 类型 | 备注 |
|---|---|---|
| iat | number | token生成时间戳(秒) |
| exp | number | 过期时间戳(秒) |
| appId | string | 开发者appid 如何查找 |
| extUuid | string | 小程序id 如何查找 |
| profileId | string | 主播unionId 如何获取 |
| userId | string | 观众unionId 如何获取 |
payload样例
{
"iat": 1555921691,
"exp": 1555928891,
"appId": "appId",
"extUuid": "extUuid",
"profileId": "unImSOHlQBsY",
"userId": "unImSOHlQBsY"
}
请求参数
Header
| 参数名 | 描述 |
|---|---|
| Content-Type | application/json |
| authorization | 网关JWT鉴权 |
QueryParam
| 参数名 | 描述 |
|---|---|
| appId | 开发者ID,可以在 开发者中心->开发者信息 查询 |
| extUuid | 小程序ID,可以在 开发者中心->我的小程序 查询 |
Body
| 参数名 | 类型 | 描述 |
|---|---|---|
| signature | Object | 支付签名 |
| profileId | String | 当前主播间的主播unionId(非直播间场景下传空值),可以从小游戏前端SDK中的hy.getStreamInfo中获得主播unionId后,传给业务服务端 |
| userId | String | 当前观众unionId,,可以从小游戏前端SDK中的hy.getUserInfo中获得观众unionId后,传给业务服务端 |
| outerPurchaseOrderId | String | 外部订单号,由开发者生成,不超过32个字符 |
| totalFee | Number | 总支付金额,单位:分 |
| price | Number | 商品单价,单位:分 |
| quantity | Number | 商品数量 |
| productName | String | 商品名称 |
| productDesc | String | 商品描述 |
signature结构
| 参数名 | 类型 | 描述 |
|---|---|---|
| timeStamp | Number | 秒级时间戳 |
| nonce | String | 随机字符串,开发者生成 |
| signType | String | 签名类型,固定填md5 |
| signStr | String | 签名结果 |
说明:
除签名和订单号之外的参数,会显示在用户的支付界面
signStr生成方式为将请求参数按以下顺序拼成字符串后进行md5签名
md5(key={appSecret}appid={appid}extUuid={extUuid}pid={profileId}uid={userId}orderId={outerPurchaseOrderId}totalFee={totalFee}price={price}quantity={quantity}productName={productName}productDesc={productDesc}timeStamp={timeStamp}nonce={nonce})
签名字段来源:
响应参数
{
"code": 0,
"msg": "success",
"response": {
"purchaseOrderId":"example"
}
}
2. SDK拉起支付组件
小游戏通过SDK拉起支付组件
接口说明
- 请求终端: 小游戏前端
- API:hyExt.context.requestPayment
请求参数
| 参数名 | 类型 | 描述 |
|---|---|---|
| timeStamp | Object | 秒级时间戳 |
| nonceStr | String | 随机字符串,开发者生成 |
| package | String | prePayOrder返回的purchaseOrderId |
| signType | String | 签名类型,固定填md5 |
| paySign | String | 签名结果 |
说明:
paySign生成方式为将请求参数按以下顺序拼成字符串后进行md5签名
md5(key={appSecret}appid={appid}extUuid={extUuid}orderId={package}timeStamp={timeStamp}nonce={nonceStr})
请求示例
hyExt.context.requestPayment({
timeStamp: 0,
nonceStr: "",
package: "",
signType: "",
paySign: "",
})
.then((res) => {
console.log("hyExt.context.requestPayment调用成功", res);
})
.catch((e) => {
console.error("hyExt.context.requestPayment调用失败", e);
});
支付组件图示
回调地址
用户支付成功后,虎牙平台将发起回调,回调地址为接入时开发者指定的HTTP地址。
接口说明
- 请求终端:虎牙服务端
- 请求方式:POST
请求参数
Body
| 参数名 | 类型 | 描述 |
|---|---|---|
| signature | Object | 支付签名 |
| extUuid | String | 小游戏/小程序ID |
| outerPurchaseOrderId | String | prePayOder请求参数中外部订单号 |
| purchaseOrderId | String | prePayOrder返回的purchaseOrderId |
| state | String | 支付状态 - NOTPAY:未支付;SUCCESS:支付成功;PAYERROR:支付失败 |
| totalFee | String | 总金额,单位:分 |
| uid | String | 支付用户的unionId |
signature结构
| 参数名 | 类型 | 描述 |
|---|---|---|
| timeStamp | Number | 秒级时间戳 |
| nonce | String | 随机字符串,开发者生成 |
| signType | String | 签名类型,固定填md5 |
| signStr | String | 签名结果 |
说明:
signStr生成方式为将请求参数按以下顺序拼成字符串后进行md5签名
md5(key={appSecret}appid={appid}extUuid={extUuid}uid={uid}orderId={purchaseOrderId}outOrderId={outPurchaseOrderId}totalFee={totalFee}timeStamp={timeStamp}nonce={nonce})
响应参数
| 参数名 | 类型 | 描述 |
|---|---|---|
| code | Number | 状态码 - 0:成功;非0:失败 |
| msg | String | 状态描述 |
说明:
- 并非所有唤起支付组件的行为都会回调,比如用户唤起后没有点击支付,或关闭应用等
- 开发者收到回调后,需要返回状态码
- 回调开发者响应状态码不为0时,会定时重试