# 抖音支付:前端调用商城后端接口文档 日期:2026-09-05。适用:商城 App 前端。本文只描述前端调用我们后端的接口,不涉及抖音官方服务端接口、证书配置或插件开发。 ## 一、公共约定 测试环境 Base URL:`https://api.o.tbmall.xin`。生产环境沿用项目正式用户端 API 配置,不要使用后台管理 API 地址。 请求头沿用现有登录请求封装: ```http Authorization: <项目当前环境的应用授权值> HSM-AUTH: <当前用户登录令牌> Content-Type: application/x-www-form-urlencoded ``` POST 参数以表单提交,不是 JSON body;GET 使用 URL 查询参数。不要把后台管理 Token 填到 HSM-AUTH。 业务响应统一格式: ```json { "bizcode": 100, "errcode": 0, "msg": "成功", "data": {} } ``` `bizcode=100` 表示本次接口调用成功,不等于用户已付款。其他业务码按 msg 提示;HTTP 错误、超时或网络失败不能视作付款成功。以下所有 ID、金额、签名均为示例。 ## 二、调用顺序 1. 调用 `/cart/getSupportPay`,判断返回列表是否包含 `type=douyin`。 2. 根据业务场景选择一个下单/支付接口,提交 `payway=douyin`。 3. 保存返回的 `data.orderNum`,把 `data.douyin` 中的支付参数交给 App 支付能力拉起抖音。 4. 用户返回 App 后调用 `/payment/queryResult` 查询结果,只有 `data.state=2` 才提示支付成功。 **重点:支付方式筛选传 `types=6`;实际支付传 `payway=douyin`,不是 `payway=6`。** ## 三、查询支付方式 **POST `/cart/getSupportPay`** | 参数 | 类型 | 必填 | 说明 | | ----------- | ------- | ---- | -------------------------------------------- | | types | string | 否 | 只查抖音传 `6`;多种传 `1,2,6`;全部传 `ALL` | | isDeduction | boolean | 否 | 默认 false,沿用现有抵扣券结算逻辑 | 请求表单: ```text types=6&isDeduction=false ``` 已启用抖音支付时的响应示例: ```json { "bizcode": 100, "errcode": 0, "msg": "成功", "data": [{ "type": "douyin", "name": "抖音支付", "balance": 0 }] } ``` 没有启用对应配置时,列表可能为空。显示名称使用 name,提交支付方式使用 type;balance 不是抖音钱包余额。 ## 四、发起支付(按场景选一个) ### 4.1 已创建订单,继续支付 **POST `/order/payment`** | 参数 | 类型 | 必填 | 说明 | | ------ | ------ | ---- | ----------------------- | | id | long | 是 | 待支付的商城业务订单 ID | | payway | string | 是 | 固定 `douyin` | ```text id=123456&payway=douyin ``` 后端接口还接受可选 password/code,但抖音支付不需要提交。成功响应见第五节。 ### 4.2 商品直接购买并支付 **POST `/cart/settlementOrder`** | 参数 | 类型 | 必填 | 说明 | | ------------ | ------- | -------- | ------------------------------------ | | addrId | long | 是 | 收货地址 ID | | goodsId | long | 是 | 商品 ID | | specsId | long | 是 | 规格 ID | | goodsNum | decimal | 是 | 购买数量 | | payway | string | 本流程是 | `douyin` | | payway2 | string | 否 | `vcoin` 表示抵扣券,沿用现有结算选择 | | couponUserId | long | 否 | 已选用户优惠券 ID | | remark | string | 否 | 现有分组备注 JSON 字符串 | ```text addrId=10001&goodsId=20001&specsId=30001&goodsNum=1&payway=douyin ``` remark 格式为 `[{"gkey":"结算返回的分组标识","rmk":"备注内容"}]`,通过现有请求封装表单编码。金额由后端计算,不传前端自算金额。优惠券、抵扣券沿用结算规则,不因选择抖音改变适用范围。 ### 4.3 购物车结算并支付 **POST `/cart/settle`** | 参数 | 类型 | 必填 | 说明 | | ------------ | ------ | ---- | ---------------------------------- | | addrId | long | 是 | 收货地址 ID | | cartIds | string | 是 | 购物车 ID 逗号分隔,`ALL` 表示全选 | | payway | string | 是 | `douyin` | | couponUserId | long | 否 | 用户优惠券 ID | | remark | string | 否 | 分组备注 JSON 字符串,同上一接口 | ```text addrId=10001&cartIds=40001,40002&payway=douyin ``` 购物车可能拆分业务订单并合并支付,查询支付结果仍使用本次返回的 orderNum。 ### 4.4 余额充值 **POST `/finance/recharge`** | 参数 | 类型 | 必填 | 说明 | | -------- | ------- | ---- | -------------------- | | category | string | 是 | 余额充值传 `balance` | | amount | decimal | 是 | 充值金额,单位元 | | payway | string | 是 | `douyin` | ```text category=balance&amount=1.00&payway=douyin ``` 注意:上述四个 POST 都可能创建支付单,请勿反复点击或自动重试创建。新下单接口已经返回支付参数时,不要紧接着再调用 `/order/payment`。 ## 五、下单/支付接口统一返回 上述四个接口均返回 PayInfoDto。抖音待支付响应示例(省略其他业务字段): ```json { "bizcode": 100, "errcode": 0, "msg": "成功", "data": { "orderId": 123456, "orderNum": "PAY_EXAMPLE_001", "amount": 1.0, "status": 0, "douyin": { "appId": "EXAMPLE_APP_ID", "mchId": "EXAMPLE_MERCHANT_ID", "prepayId": "EXAMPLE_PREPAY_ID", "callbackScheme": "trustbridgeapp", "packageValue": "Sign=DYPay", "nonceStr": "0123456789abcdef0123456789abcdef", "timeStamp": "1788585600", "sign": "EXAMPLE_BASE64_SIGNATURE" } } } ``` | 字段 | 类型 | 前端用途 | | --------------------- | ------- | ---------------------------------------------- | | orderId | long | 后端返回的订单 ID | | orderNum | string | 保存下来,支付结果查询必须用它 | | amount | decimal | 实际支付金额(元) | | status | integer | 此 DTO 中 0=待支付、1=已支付;不同于查单 state | | douyin | object | App 拉起抖音所需参数 | | douyin.appId | string | 抖音应用 ID | | douyin.mchId | string | 抖音商户 ID | | douyin.prepayId | string | 预支付 ID | | douyin.callbackScheme | string | App 返回 Scheme | | douyin.packageValue | string | `Sign=DYPay` | | douyin.nonceStr | string | 随机字符串 | | douyin.timeStamp | string | 秒级时间戳,保留字符串类型 | | douyin.sign | string | 后端生成的签名,原样使用 | 后端已处理签名,前端无需请求商户私钥或另调签名接口。参数缺失时停止拉起,提示支付参数异常并反馈后端,不要自行伪造字段。 若 App 支付桥接要求 SDK 小写字段,映射如下;这不是另一个 HTTP 请求: ```js const d = response.data.douyin; const payInfo = { appid: d.appId, partnerid: d.mchId, prepayid: d.prepayId, package: d.packageValue, noncestr: d.nonceStr, timestamp: d.timeStamp, sign: d.sign, }; ``` ## 六、查询支付结果 **GET `/payment/queryResult`** | 参数 | 类型 | 必填 | 说明 | | -------- | ------ | ---- | ------------------------------------------------------- | | orderNum | string | 是 | 发起支付接口返回的 data.orderNum,不是 orderId/prepayId | ```http GET https://api.o.tbmall.xin/payment/queryResult?orderNum=PAY_EXAMPLE_001 ``` ```json { "bizcode": 100, "errcode": 0, "msg": "成功", "data": { "state": 2 } } ``` | state | 含义 | 前端处理 | | ----- | ---------- | -------------------------------- | | 0 | 订单不存在 | 核对支付编号及环境,不能提示成功 | | 1 | 支付处理中 | 稍后再次查询 | | 2 | 支付成功 | 展示成功,刷新订单或充值余额 | | 3 | 支付失败 | 提示失败,刷新订单状态 | 当前 App 采用最多 5 次、间隔 1.5 秒的查询;这属于前端策略,不是后端强制限制。暂未确认、断网或超时应显示“支付结果确认中”,保存编号以便回前台再次查询,避免直接重复付款。 用户取消或支付 SDK 提示成功后,都需要以服务端查询结果为准。不要调用 `/payment/feedback` 上报成功来替代查单;前端也不需要调用后端的抖音通知/退款回调接口。 ## 七、对接范围与发布注意 - 本文按当前工作区后端代码整理;SDK 签名新增字段(packageValue、nonceStr、timeStamp、sign)尚未确认已部署到测试/生产服务器。 - 后台配置已完成不代表预下单、签名、支付回调均验收通过,实际支付链路仍需联调。 - 本次抖音支付是 App 原生支付;H5 仅可检查适用的后端业务请求,不能凭网页调用拉起此原生能力。