顺丰开放平台接口必须用HTTPS+POST且传JSON,签名需SHA256(参数字符串&key),company须与实际承运方一致,返回数据需安全解析并按文档校验result_code。

顺丰开放平台接口必须用 HTTPS + POST,别试 GET
顺丰所有物流查询接口(比如 sfexpress.com/openapi 下的轨迹查询)只支持 HTTPS 协议和 POST 方法,传参必须是 JSON 格式。用 file_get_contents("http://...") 或拼接 URL 的 GET 请求会直接返回 405 错误或空响应。
常见错误现象:{"result_code":"405","result_msg":"Request method not supported"}
- 必须用
curl_init(),且显式设置CURLOPT_POST => true和CURLOPT_POSTFIELDS为 JSON 字符串 - Header 里要带上
Content-Type: application/json,漏掉这个,顺丰会当无效请求处理 - 别用
http_build_query()直接传数组——它生成的是 x-www-form-urlencoded,不是 JSON - 测试时先用
curl -X POST -H "Content-Type: application/json" -d '{"..."}' ...验证通路,再写 PHP
签名(sign)计算必须用 SHA256 + 密钥拼接,顺序不能错
顺丰要求每个请求带 sign 参数,它是对「请求参数字符串 + 应用密钥(key)」做 SHA256 哈希得到的十六进制小写字符串。顺序反了、多空格、少字段都会导致 {"result_code":"401","result_msg":"Invalid signature"}。
关键点:
立即学习“PHP免费学习笔记(深入)”;
- 参与签名的字段必须按文档要求排序(通常是字典序),且只包含业务参数 + 固定字段(如
request_time,partner_id),不包括sign自身 - 拼接规则是:字段名=值(无空格、无编码),用 & 连接,末尾再拼上
&key=你的密钥 - 示例(伪代码):
$str = "company=SF&logistic_code=123456789&partner_id=123456&request_time=1712345678"; $sign = hash("sha256", $str . "&key=your_secret_key"); - 注意:
request_time必须是当前秒级时间戳,偏差超过 15 分钟也会验签失败
查单号前先确认公司编码(company),SF 不等于顺丰速运
调用轨迹查询接口时,company 字段填错是高频问题。顺丰开放平台把不同业务线拆成独立编码:SF 是顺丰速运(常用),EMS、YD 等是合作承运商,但你传 "SF" 查一个中通单号,结果永远是 {"result_code":"2001","result_msg":"No logistics information"}。
- 单号本身不决定公司——得看寄件时用的是哪家物流下单的;不能靠单号前缀硬判断(比如 SF 开头≠一定是顺丰)
- 生产环境建议先调用顺丰的
getCompanyCode接口(需另申请权限),用单号反查真实承运方 - 沙箱测试时,文档给的测试单号(如
111111111111)只对SF有效,换别的 company 就查不到 - 如果业务涉及多快递公司,别在代码里写死
company="SF",应从订单数据中读取来源字段
返回数据结构嵌套深,别直接 json_decode($res)->data->path
顺丰返回的 JSON 层级较深,且 data 字段内容随接口类型变化大。例如轨迹查询返回的 data 是个数组,里面每个元素是时间点对象,而有些接口的 data 是对象或 null。直接链式取值容易触发 PHP Notice 或 Fatal Error。
- 务必先检查
json_last_error() === JSON_ERROR_NONE,再判断isset($arr['data']) - 别假设
$arr['data'][0]['time']一定存在——可能data是空数组,也可能轨迹没更新到最新节点 - 示例安全取法:
if (!empty($data) && is_array($data) && !empty($data[0]['time'])) { $latest = $data[0]; } - 返回码不是只有
result_code == 0才成功:部分接口用200表示业务成功,201表示单号已签收,得看文档具体定义
签名逻辑和 company 判断这两块最容易在线上跑几天才发现问题——因为测试单号太“乖”,一到真实单号就断。别跳过沙箱里的多单号组合验证。











