本文目录导读:

在PHP项目中对接抖音支付(现在通常指抖音支付或抖音电商的支付能力),主要场景有两种:
- 抖音小程序/小游戏:用户在小程序内下单,调用抖音支付。
- 抖音开放平台(App/网站):用户通过抖音App授权或扫码,在第三方App或网站完成支付。
由于抖音支付接口文档更新较快,以下提供一套核心的通用对接逻辑和代码示例(基于官方标准API),建议以抖音开放平台的最新文档为准。
对接前的必备准备
- 注册开发者:在抖音开放平台注册成为开发者,创建应用(小程序/移动应用/网站应用)。
- 申请支付权限:在应用功能中申请“支付能力”,并完成签约(通常需要个体工商户或企业资质)。
- 获取关键参数:
AppID(应用唯一标识)AppSecret(签名密钥)商户号(抖音支付分配的商户号)支付密钥(MD5 Key 或 RSA私钥)回调地址(Notify URL):用于接收支付结果通知。
核心API对接流程(以小程序为例)
典型的支付交互流程如下:
- 用户选择商品 -> 前端(小程序)向你的后端PHP服务器发起“统一下单”请求。
- PHP后端 调用抖音支付API
https://developer.toutiao.com/api/apps/ecpay/v1/create_order获取预支付ID。 - PHP后端 根据返回的
prepay_id进行二次签名,返回给前端调起支付所需参数(order_id,sign,timestamp等)。 - 前端 通过
tt.pay(小程序)或openURL(网页)调起抖音支付。 - 用户支付完成 -> 抖音服务器异步通知你的PHP回调地址(
Notify URL)。 - PHP后端 验证签名、处理订单状态,并返回成功应答给抖音。
PHP核心代码示例
以下使用 MD5 签名算法(抖音也支持HMAC-SHA256,请根据文档选择)。
统一下单接口 (PHP)
<?php
class DouyinPay
{
private $appId = '你的AppID';
private $merchantId = '你的商户号'; // 抖音支付分配的商户号
private $salt = '你的支付密钥(Token/Salt)'; // 用于签名
/**
* 生成统一下单参数并请求抖音
* @param string $outOrderNo 商户订单号
* @param int $totalAmount 支付金额(单位:分)
* @param string $subject 商品描述
* @param string $callbackUrl 异步通知地址
* @return array 包含 prepay_id 和调起支付所需参数
*/
public function createOrder($outOrderNo, $totalAmount, $subject, $callbackUrl)
{
$url = 'https://developer.toutiao.com/api/apps/ecpay/v1/create_order';
// 1. 构建请求参数
$params = [
'app_id' => $this->appId,
'out_order_no' => $outOrderNo,
'total_amount' => $totalAmount, // 注意:抖音接口金额单位是分
'subject' => $subject,
'body' => $subject,
'valid_time' => 300, // 订单有效时间,单位秒
'notify_url' => $callbackUrl,
'pay_type' => 'ALIPAY, WECHAT', // 允许的支付方式,可选
];
// 2. 生成签名(关键步骤)
// 抖音签名规则:将所有参数(不包括 sign)按 key 升序排序,拼接成 key=value 形式,最后连接 salt
ksort($params);
$signStr = '';
foreach ($params as $key => $value) {
if ($value !== '' && $key !== 'sign') {
$signStr .= $key . '=' . $value . '&';
}
}
$signStr .= 'salt=' . $this->salt;
// 计算 MD5 签名,并转大写
$params['sign'] = strtoupper(md5($signStr));
// 3. 发起 POST 请求(使用 https)
$result = $this->httpPost($url, $params);
// 4. 解析响应
$data = json_decode($result, true);
if ($data['err_no'] == 0 && $data['err_tips'] == 'success') {
$prepayId = $data['data']['order_id']; // 抖音返回的 prepay_id
// 返回给前端调起支付所需的参数
return $this->getPayParams($prepayId);
} else {
// 记录错误日志
return ['error' => $data['err_tips']];
}
}
/**
* 构造前端调起支付所需的签名参数
* @param string $orderId 抖音返回的 prepay_id
* @return array
*/
private function getPayParams($orderId)
{
$params = [
'app_id' => $this->appId,
'sign_type' => 'MD5',
'order_id' => $orderId,
'timestamp' => time(),
];
// 同样需要签名
ksort($params);
$signStr = '';
foreach ($params as $key => $value) {
if ($value !== '' && $key !== 'other_settle_params') {
$signStr .= $key . '=' . $value . '&';
}
}
$signStr .= 'salt=' . $this->salt;
$params['sign'] = strtoupper(md5($signStr));
return $params;
}
// HTTP 请求函数(省略 curl 实现)
private function httpPost($url, $data) {
// 使用 cURL 实现 POST 请求
}
}
// 使用示例
$pay = new DouyinPay();
$params = $pay->createOrder('ORDER123456', 100, '测试商品', 'https://yourdomain.com/pay/notify');
echo json_encode($params);
异步通知处理 (Notify URL)
抖音在用户支付成功后,会发送 POST 请求到你填写的 notify_url。你的服务器必须正确响应并返回 {"status": "success"}。
<?php
// notify.php
// 1. 获取抖音 POST 过来的 JSON 数据
$rawData = file_get_contents('php://input');
$data = json_decode($rawData, true);
// 2. 商户验证签名 (这里用同样的 salt 计算)
$salt = '你的支付密钥';
// 抖音的回调参数通常包含:app_id, order_id, out_order_no, total_amount, ... , sign
$sign = $data['sign'];
unset($data['sign']); // 去除 sign 字段用于计算签名
ksort($data);
$signStr = '';
foreach ($data as $key => $value) {
if ($value !== '' && $key !== 'other_settle_params') {
$signStr .= $key . '=' . $value . '&';
}
}
$signStr .= 'salt=' . $salt;
$calculatedSign = strtoupper(md5($signStr));
// 3. 验证签名
if ($sign !== $calculatedSign) {
// 签名错误,可能是伪造通知
http_response_code(400);
echo json_encode(['status' => 'fail']);
exit;
}
// 4. 验证业务数据
$orderNo = $data['out_order_no']; // 你的商户订单号
$amount = $data['total_amount']; // 支付金额(分)
$orderId = $data['order_id']; // 抖音支付订单号
// 5. 处理业务逻辑(更新订单状态、加余额等)
// 注意:需要避免重复通知处理(幂等性)
$order = getOrderByOutNo($orderNo);
if ($order['status'] == 'unpaid' && $order['amount'] == $amount) {
updateOrderStatus($orderNo, 'paid');
// 记录支付成功日志
}
// 6. 必须返回 success 给抖音
echo json_encode(['status' => 'success']);
?>
常见关键问题
签名算法
- 抖音签名规则:将所有非空参数(
key和value)按keyASCII 升序拼接,格式为key1=value1&key2=value2...&salt=你的Salt。 - 特别注意:
app_secret和salt的区别,通常在生成签名时使用salt(商户密钥),而app_secret用于接口调用鉴权(Token获取)。一定要仔细看文档的“签名”部分。
金额单位
- 抖音支付:通常以 分 为单位(如 100 表示 1 元)。
- 其他接口:有些平台接口(如查询)可能以元为单位,务必根据文档区分。
安全注意事项
- 密钥不要硬编码:建议存储环境变量或配置文件中,不要出现在代码库。
- 验证回调IP(可选):抖音支付通常有固定的回调IP范围,可以验证来源。
- 防止重放攻击:在通知处理中加入订单状态检查,确保只更新一次。
调试工具
- 抖音开放平台提供了接口调试工具,可以方便地模拟请求和验证签名。
- 打开 沙箱模式(如果支持)进行测试。
补充:PC/Web网站对接
如果是PC网站,流程稍有不同:
- 你的后端调用
https://open.douyin.com/api/ecpay/b2c/orders/create(或类似接口)获取order_id。 - 前端通过生成一个 支付链接 或通过 抖音扫码 完成支付。
- 用户扫码/点击后,跳转到抖音App或抖音收银台完成支付。
- 同样需要回调通知。
对接抖音支付的核心在于:
- 搞懂签名流程(排序 + 拼接 Salt + MD5)。
- 正确处理异步通知(验签 + 幂等性 + 返回
success)。 - 使用沙箱测试(先模拟,再上线)。
建议直接访问 抖音开放平台 -> 文档 -> 支付能力 获取最新版接口文档和SDK(官方有提供PHP SDK,推荐直接使用)。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播