抖音小程序使用APP支付应调用哪个接口和SDK?
支付老李
结论
如果支付发生在抖音小程序内部,应使用抖音开放平台的小程序支付能力。服务端负责创建支付订单,小程序端通过 tt.pay 唤起收银台。
这种情况下,不应直接调用支付宝开放平台的 alipay.trade.app.pay,小程序中也不需要集成支付宝 App 支付 SDK。
只有支付发生在独立的 Android 或 iOS App 中,而且需要直接唤起支付宝客户端时,才应使用:
alipay.trade.app.pay
原生客户端还需要集成支付宝 App 支付 SDK。
为什么参数不一样
tt.pay 和 alipay.trade.app.pay 是两个平台的不同支付产品,下单方式、签名规则和参数结构自然不同。
alipay.trade.app.pay用于原生 App。商户服务端调用支付宝接口生成订单字符串,再把字符串交给支付宝客户端 SDK。tt.pay用于抖音小程序。商户服务端通过抖音开放平台相应的支付下单接口创建订单,再把返回的支付参数传给小程序。- 抖音小程序运行在抖音客户端提供的环境中,无法像原生 Android、iOS 应用那样直接集成支付宝 App SDK。
- 即使最终收银台支持支付宝,整个支付流程仍由抖音客户端及其支付体系处理,不能因此改用
alipay.trade.app.pay。
所以,两者的参数不能直接映射,签名方法也不能混用。
推荐接入流程
1. 服务端创建订单
服务端按照抖音开放平台当前支付产品的文档调用创建订单接口,同时保存以下业务信息:
- 商户订单号
- 支付金额
- 商品名称和描述
- 订单状态
- 用户或小程序标识
- 创建时间和过期时间
接口地址、签名字段和返回参数可能因支付产品及平台版本而异,应以抖音开放平台控制台中对应产品的最新文档为准。
服务端示意代码:
async function createPaymentOrder(req, res) {
const merchantOrderNo = generateOrderNo();
// 先在自己的数据库中创建待支付订单
await orderRepository.create({
orderNo: merchantOrderNo,
amount: 100,
status: "PENDING"
});
// 按抖音开放平台当前支付文档调用创建订单接口
const paymentResult = await douyinPaymentClient.createOrder({
orderNo: merchantOrderNo,
amount: 100,
subject: "测试商品"
});
// 只向小程序返回发起支付所需的数据
res.json({
paymentData: paymentResult
});
}
代码中的 douyinPaymentClient.createOrder 只是业务封装示例,并非固定的官方方法名。实际使用的请求字段、签名方式和接口地址,必须以接入产品的官方文档为准。
2. 小程序端调用 tt.pay
小程序从业务服务端取得支付参数后,再调用 tt.pay:
tt.request({
url: "https://example.com/api/payment/create",
method: "POST",
data: {
productId: "product_001"
},
success(res) {
const paymentData = res.data.paymentData;
tt.pay({
...paymentData,
success(payRes) {
console.log("支付调用成功", payRes);
queryOrderStatus();
},
fail(err) {
console.error("支付调用失败", err);
}
});
},
fail(err) {
console.error("创建订单失败", err);
}
});
paymentData 需要包含哪些字段,要看抖音开放平台创建订单接口实际返回的内容。不要自行拼装 alipay.trade.app.pay 的参数并传给 tt.pay。
3. 服务端处理支付通知
支付完成后,服务端应接收并验证平台发送的异步通知:
async function paymentNotify(req, res) {
const notification = req.body;
if (!verifyDouyinSignature(notification)) {
res.status(400).send("invalid signature");
return;
}
const order = await orderRepository.findByOrderNo(
notification.merchantOrderNo
);
if (!order) {
res.status(404).send("order not found");
return;
}
if (order.status === "PAID") {
res.send("success");
return;
}
// 还应核对订单号、金额、商户身份和支付状态
await orderRepository.markAsPaid(order.orderNo);
res.send("success");
}
verifyDouyinSignature、通知字段和成功响应格式也只是示例。具体实现需要遵循对应支付产品的验签和回调规范。
SDK 应该怎么选
可以根据支付发生的位置来选择:
| 支付场景 | 接口或能力 | 客户端 SDK |
|---|---|---|
| 抖音小程序内支付 | 服务端调用抖音开放平台支付接口,小程序调用 tt.pay | 不集成支付宝 App 支付 SDK |
| 独立 Android/iOS App 唤起支付宝 | alipay.trade.app.pay | 支付宝 Android/iOS App 支付 SDK |
| Web 页面支付 | 使用对应的网页支付产品 | 通常不使用小程序 tt.pay |
如果当前项目是抖音小程序,使用第一种方案即可。
注意事项
- 下单和签名必须在服务端完成,不能把应用密钥、商户私钥等敏感信息写入小程序代码。
- 小程序端收到支付成功回调,只能说明支付流程已成功返回。最终订单状态应以服务端异步通知或主动查单结果为准。
- 服务端必须校验通知签名、商户订单号、支付金额、商户身份和订单状态。
- 支付回调可能重复发送,因此订单更新和发货逻辑必须保证幂等。
- 金额单位必须按照所接入接口的定义处理,不能默认所有接口都使用元或分。
alipay.trade.app.pay返回的订单字符串不能直接传给tt.pay。- 如果文档中同时出现“App 支付”和“小程序支付”,需要先确认“App”是指独立原生应用,还是运行在抖音 App 内的小程序。这是两种不同的接入方式。
备注:内容仅供参考。
