# 道具直购
道具直购是虚拟支付的核心能力,允许玩家在游戏内直接购买虚拟道具。本文将详细介绍道具直购的接入流程和注意事项。
# 功能介绍
道具直购支持玩家使用真实货币购买游戏内的虚拟道具,包括但不限于:
- 游戏货币(钻石、金币等)
- 角色皮肤、装扮
- 游戏道具、装备
- 会员服务、特权
# 接入流程
# 1. 配置商品
在 TapTap 开发者后台配置需要售卖的商品:
| 配置项 | 说明 |
|---|---|
| 商品 ID(productId) | 道具的唯一标识,需与游戏内一致 |
| 商品名称 | 道具的显示名称 |
| 商品价格 | 道具的售价(单位:分) |
| 分区 ID(zoneId) | 游戏分区标识,默认为 "1" |
# 2. 实现服务端接口
# 签名生成
服务端需要实现 paySig 和 signature 的签名生成逻辑,详细算法请参考 tap.requestPaymentGameItem 文档。
# 发货回调
服务端需要实现发货回调接口,用于接收支付成功后的发货通知。详细协议请参考发货消息协议文档。
# 3. 客户端调用
使用 tap.requestPaymentGameItem API 发起支付请求:
// 1. 向服务端请求支付参数
const payParams = await requestPayParamsFromServer({
productId: 'diamond_100',
quantity: 1
})
// 2. 调用支付 API
tap.requestPaymentGameItem({
signData: payParams.signData,
paySig: payParams.paySig,
signature: payParams.signature,
success(res) {
console.log('支付成功', res)
// 等待服务端发货回调确认后,再给用户发放道具
},
fail(err) {
console.error('支付失败', err.errCode, err.errMsg)
handlePaymentError(err.errCode)
}
})
# 支付参数说明
# signData 参数
signData 是支付原串,包含以下关键字段:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| mode | string | 是 | 固定为 "goods" 表示道具直购 |
| offerId | string | 是 | 应用 ID |
| productId | string | 是 | 商品 ID,需与后台配置一致 |
| goodsPrice | number | 是 | 商品单价(单位:分),需与后台配置一致 |
| buyQuantity | number | 是 | 购买数量 |
| outTradeNo | string | 是 | 业务订单号,需保证唯一性 |
| currencyType | string | 是 | 币种,如 "CNY" |
| zoneId | string | 否 | 分区 ID,默认 "1" |
| env | number | 否 | 环境:0-正式环境,1-沙箱环境 |
| attach | string | 否 | 透传数据,发货时原样返回 |
# 发货流程
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ 客户端 │ │ 服务端 │ │ TapTap │ │ 支付渠道 │
└────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘
│ │ │ │
│ 1.请求支付参数 │ │ │
│───────────────>│ │ │
│ │ │ │
│ 2.返回签名参数 │ │ │
│<───────────────│ │ │
│ │ │ │
│ 3.调用支付API │ │ │
│────────────────────────────────>│ │
│ │ │ │
│ │ │ 4.调起支付 │
│ │ │───────────────>│
│ │ │ │
│ │ │ 5.支付结果 │
│ │ │<───────────────│
│ │ │ │
│ │ 6.发货回调 │ │
│ │<───────────────│ │
│ │ │ │
│ │ 7.返回发货结果 │ │
│ │───────────────>│ │
│ │ │ │
│ 8.支付结果回调 │ │ │
│<────────────────────────────────│ │
│ │ │ │
# 注意事项
# 价格校验
goodsPrice会与后台配置的商品价格进行校验,必须完全一致- 价格单位为「分」,1 元 = 100 分
# 订单号唯一性
outTradeNo每个订单只能使用一次- 建议使用时间戳 + 随机数生成唯一订单号
- 订单号要求:32 个字符内,只能是数字、大小写字母、符号
_-|*@组成,不能以下划线开头
# 防沉迷限制
- 未成年用户受防沉迷系统限制,可能无法完成支付
- 错误码
-15009表示由于健康系统限制,支付已超过限额
# 沙箱测试
- 测试时设置
env: 1使用沙箱环境 - 需要在开发者后台将测试账号加入沙箱白名单
- 沙箱环境的支付不会真实扣款
# 错误处理
常见错误码及处理建议:
| 错误码 | 说明 | 处理建议 |
|---|---|---|
| -1 | 系统失败 | 提示用户稍后重试 |
| -15003 | 订单重复 | 检查订单号是否重复使用 |
| -15006 | 货币类型不支持 | 检查 currencyType 是否为 CNY |
| -15012 | 签名错误 | 检查 signature 签名算法 |
| -15014 | 支付签名错误 | 检查 paySig 签名算法 |
| -15016 | 商品价格错误 | 检查 goodsPrice 是否与后台配置一致 |
| 1 | 用户取消支付 | 无需特殊处理 |
完整错误码列表请参考 tap.requestPaymentGameItem 文档。
