PHP调用苏宁云API应弃用官方SDK而直接封装cURL,因SDK依赖废弃Guzzle且不兼容PHP 7.4+;所有请求需带Authorization: UPSP头,POST/PUT须用application/json及UTF-8 JSON body;新接口统一用OAuth 2.0 access_token,无需签名;接口地址为https://open.suning.com/api,版本由method参数指定;查订单时时间范围须为ISO 8601格式且跨度≤7天,分页pageSize最大100;物流接口校验运单号长度(6–20位)及快递编码;响应为多层嵌套stdClass,建议json_decode($json, true)转数组并用isset或??防错;字段命名不统一,应以真实响应为准。

PHP调用苏宁云API必须用cURL,SDK基本不可用
苏宁开放平台官方提供的PHP SDK年久失修,依赖已废弃的guzzlehttp/guzzle:~5.0,且不兼容PHP 7.4+,强行安装会触发Declaration of GuzzleHttp\Ring\Client\CurlMultiHandler::tick()等致命错误。实际项目中,直接封装cURL是最稳妥的选择。
关键点:
- 所有接口需在请求头带上
Authorization(格式为UPSP <access_token></access_token>),不是Bearer也不是Basic - POST/PUT请求必须用
Content-Type: application/json,且body必须是UTF-8编码的JSON字符串,不能传raw array或http_build_query后的表单数据 - 签名逻辑只用于OAuth 1.0a认证的旧接口(如部分库存查询),新接口统一走OAuth 2.0 + access_token,无需自己算sign
- 接口地址固定为
https://open.suning.com/api,末尾不加版本号,版本由method参数指定(如sn_open_trade_order_query)
读取订单数据:用sn_open_trade_order_query查单时注意时间范围硬限制
该接口要求startTime和endTime必须是精确到秒的ISO 8601格式(如2024-03-15T00:00:00),且时间跨度不能超过7天——超限直接返回{"error_code":"INVALID_PARAM","error_msg":"时间范围不能超过7天"},不会提示具体哪项错。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 用
date('c', strtotime('-6 days'))生成起始时间,避免手写字符串出错 - 分页靠
pageNo和pageSize,但pageSize最大只认100,设成200也只返回100条 - 响应里的
orderList是数组,但外层包裹着sn_response→sn_body→sn_open_trade_order_query_response三层,别一上来就$data['orderList'] - 订单状态码是数字(如
1表示待付款),不是字符串,判断时别写== '1'
写入物流信息:调sn_open_logistics_delivery_send前必须校验运单号长度
这个接口对logisticCode(快递公司编码)和logisticNo(运单号)有强校验:logisticCode必须是苏宁文档里列出的值(如SF、YD),而logisticNo长度不能少于6位、不能多于20位——超长或过短都会返回{"error_code":"PARAM_ERROR","error_msg":"物流单号格式错误"},错误信息毫无提示性。
容易踩的坑:
- 顺丰单号可能带字母,但京东物流(
JD)只收纯数字,传错直接拒收 - 请求体里
orderItem是数组,但每个子项的itemCode(商品编码)必须和下单时一致,大小写敏感 - 成功响应只有
{"sn_response":{"sn_body":{"sn_open_logistics_delivery_send_response":{"result":"success"}}}},没有订单号回传,得自己存映射关系 - 同一订单多次调用该接口,苏宁会覆盖上次物流信息,不会追加
PHP里处理JSON响应要防null和stdClass嵌套
苏宁API返回的JSON默认被json_decode()转成stdClass对象,而很多开发者习惯用数组语法访问,比如$res['sn_response']['sn_body']会报错。更麻烦的是,某些字段(如payTime)在无值时返回null而非空字符串,直接date('Y-m-d', $order->payTime)会警告。
推荐做法:
- 统一用
json_decode($json, true)转成关联数组,避免对象访问问题 - 取深层字段前先用
isset()或??操作符兜底,例如$order['sn_response']['sn_body']['sn_open_trade_order_query_response']['orderList'] ?? [] - 时间字段统一用
!empty($v) && is_numeric($v)判断是否可转时间戳,别信文档写的“必填” - 日志里记录原始
$json字符串,别只记print_r($arr),调试时能快速比对结构差异
orderId、orderNo或snOrderNo,文档更新滞后,最保险的方式是抓一次真实响应存为样本,按实际结构写代码。



















