需按滴滴货运API规范生成SHA256-HMAC+Base64签名,严格拼接method、uri、timestamp、nonce、body;回调解析须校验UTF-8编码及json_last_error;状态同步需用order_id+event_id做幂等控制。

如何用 PHP 发起滴滴货运 API 的 POST 请求(含签名)
滴滴货运开放平台要求所有请求必须带 Authorization 签名头,不是简单填个 access_token 就能调通。签名逻辑是 SHA256-HMAC + Base64,密钥是平台分配的 secret_key,且要按字段顺序拼接字符串——漏掉空格、错位字段、时间戳不校准都会返回 401 Unauthorized。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 用
hash_hmac('sha256', $sign_str, $secret_key, true)计算原始签名,再base64_encode(),别用md5或直接拼接字符串 -
$sign_str必须严格按文档顺序包含:method(大写)、uri(不带域名,如/api/v1/order/create)、timestamp(秒级 Unix 时间戳)、nonce(随机 8 位字符串)、body(原始 JSON 字符串,不含空格换行) - PHP 中用
file_get_contents('php://input')或json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)保证 body 字符串无格式化空格 - 务必检查服务器时间是否与 NTP 同步,偏差超过 300 秒会直接拒签
PHP 解析滴滴货运回调通知时的 JSON 编码陷阱
滴滴推送的订单状态变更通知是标准 JSON,但部分 PHP 环境(尤其老版本或禁用了 json 扩展的容器)会因 mbstring.func_overload 开启导致 json_decode() 返回 null,而错误日志里只显示“无效 JSON”,实际是编码被截断。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 收到回调先用
file_get_contents('php://input')原始读取,不要依赖$_POST - 检查
mb_detect_encoding($raw_body)是否为UTF-8,如果不是,用mb_convert_encoding($raw_body, 'UTF-8', 'auto')转换后再json_decode() - 加一层校验:
json_last_error() === JSON_ERROR_NONE,否则记录原始$raw_body到日志,别只打json_decode结果 - 滴滴回调 header 里带
X-DiDi-Signature,可用对应公钥验签——这步常被跳过,但线上环境建议加上,防伪造通知
PHP 处理滴滴货运订单状态同步的幂等性设计
滴滴可能因网络重试多次推送同一订单的 order_status=confirmed,如果 PHP 每次都新建数据库记录或触发发车逻辑,会导致重复调度、司机重复接单、财务对账错乱。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 回调里必须提取
order_id和event_id(滴滴推送的唯一事件 ID),两者组合做数据库唯一索引,插入前用INSERT IGNORE或ON DUPLICATE KEY UPDATE - 状态更新不能只写
UPDATE orders SET status = ? WHERE order_id = ?,要加条件:WHERE order_id = ? AND status (比如当前状态是 <code>created才允许更新为confirmed) - 避免用 PHP 的
sleep()或锁文件做“简单去重”,高并发下失效;优先用 RedisSETNX以event_id为 key,过期时间设为 10 分钟 - 订单创建接口返回的
order_id是字符串,但部分旧版 SDK 示例里当整数处理,导致后续查询失败——注意类型一致性
PHP cURL 调用滴滴货运 API 时的 SSL 与超时配置
生产环境常见报错 cURL error 35: SSL connect error 或 Operation timed out after 10000 milliseconds,本质不是网络问题,而是 PHP cURL 默认不校验 SNI 或超时太短,而滴滴网关强制要求 TLS 1.2+ 且响应通常在 800ms 内。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 必须显式设置:
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2),禁用 SSLv3/TLSv1.0 - 关闭 SNI 报错干扰:
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2)和curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true),并指定系统 CA 包路径:curl_setopt($ch, CURLOPT_CAINFO, '/etc/ssl/certs/ca-certificates.crt') - 超时分两级:连接超时设为
1000ms(CURLOPT_CONNECTTIMEOUT_MS),总超时设为3000ms(CURLOPT_TIMEOUT_MS),别用秒级单位 - 别用
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true),滴滴 API 不跳转,开启反而可能触发 302 后丢失签名头
签名逻辑、回调解析、状态幂等、cURL 配置这四块,任意一块没对齐文档细节,就会卡在“明明参数一样却调不通”。滴滴的错误码不总提示具体原因,得靠日志比对原始请求体和签名字符串——这点最容易被跳过。











