开发文档 / 接入指引 / 接口概述

开放平台开发文档

HMAC-SHA256 签名认证 · 商户级限流 · 幂等下单 · Webhook 事件推送(自动重试 + 死信保护)。覆盖国内快递、汽车托运、宠物托运三大业务域。

🚀 OpenAPI v2 · B3 企业级规范
更新时间:2026-09-14 17:10
💡
30 秒接入:后台「开发者中心」创建应用获得 app_id / app_secret → 按签名算法组装请求 → 收到 Webhook 推送即完成闭环。沙箱环境自动放行测试单,不产生真实资金变动。
POST

/openapi/v2/express/price

快递查价:返回平台标准渠道与费用明细,channel_code 指定渠道下单

POST

/openapi/v2/express/order/create

幂等下单:merchant_order_no 去重(应用维度隔离)

POST

/openapi/v2/express/order/payment-confirm

支付确认发货:月结超重补差后确认放行

POST

/openapi/v2/express/order/query

订单查询:状态 / 运单号 / 费用明细一次拉全

5 分钟跑通

1

获取凭证

登录 开放平台控制台 →「API 对接 → 我的应用」,复制 AppId(即请求头 X-App-Key)与 AppSecret。

2

先测连通(免签名)

GET /openapi/v2/car/ping 可直接调用,用于确认域名与网络可达(不探测任何库表)。

3

发一个真实请求

按下方 cURL 携带 4 个鉴权头调用查价,返回 code=0 即接入成功。

4

配置回调即闭环

在控制台填 Webhook 地址(HTTPS);下单后收到 order.status.changed 推送即完成最小闭环。

最小可跑通示例(复制即用)
# 第 1 步:连通性测试(免签名,仅运车 / 运宠域提供)
curl "https://yunxijuchuang.com/openapi/v2/car/ping"

# 第 2 步:真实业务请求(需 4 个鉴权头,签名算法见「签名算法」章节)
curl -X POST "https://yunxijuchuang.com/openapi/v2/express/price" \
  -H "Content-Type: application/json" \
  -H "X-App-Key: $APP_KEY" \
  -H "X-Timestamp: $(date +%s)" \
  -H "X-Nonce: $NONCE" \
  -H "X-Signature: $SIGNATURE" \
  -d '{"from_city":"昆明市","to_city":"杭州市","weight":1.5}'
👉
不想写代码?打开「在线调试工具」,在浏览器里实时生成签名并直接试跑(密钥不出浏览器、不上传服务器)。

接入流程与准备

从注册到上线的标准路径共 6 步。平台提供沙箱应用,建议先在沙箱完成全链路自测,验证通过后再切换生产密钥正式上线。

1 注册与企业认证 2 创建应用拿密钥 3 配置回调/白名单 4 沙箱联调 5 切换生产密钥 6 上线自检

(第 4 步与第 6 步可点击直达对应章节)

1

注册商户并完成企业认证

在云兔开放平台注册商户账号,完成企业实名认证;认证通过后方可创建应用、开通业务域与充值资金账户。

2

登录控制台,获取应用凭证

登录开放平台控制台 yunxijuchuang.com/open/login,进入「API 对接 → 我的应用」,在「应用凭证」区获取 AppId(即请求头 X-App-Key 的值) 与 AppSecret。AppSecret 默认打码显示,可点「显示」查看、点「重置 Secret」重新生成(重置后旧密钥立即失效)。该页面同时提供「开启调试」与「回调配置」,详见后续章节。

3

配置安全与回调

在应用详情配置 IP 白名单(可选)与 Webhook 回调地址(接收订单状态、轨迹、费用等事件推送,须为 HTTPS 且公网可达)。

4

取得沙箱应用并联调

沙箱应用(预置虚拟资金 10000 元)由平台开通,请向对接人申请;开通后按「查价 → 下单 → 支付 → 查询 → 取消 → 回调接收」跑通全链路。注意:控制台上的「开启调试」不等于沙箱,二者差别见「沙箱联调」章节。

5

切换生产应用

使用生产应用的 app_key / app_secret,将请求基址从沙箱切至生产域名,完成一笔真实小额订单验证。

6

上线与运维

按「上线自检清单」逐项确认;上线后关注限流配额、回调投递与死信,排障时提供响应中的 request_id。

接入前置条件

项目必要性说明
企业实名认证必需创建应用与开通业务域的前置条件
业务域开通必需国内快递 / 汽车托运 / 宠物托运按业务需要申请开通,未开通的域调用返回无权限
回调地址(Webhook)强烈建议须 HTTPS 且公网可达;未配置回调地址时,平台事件推送将直接进入死信,无法自动重投
IP 白名单可选留空表示不限制来源 IP;详见「安全策略」
资金账户运车 / 运宠必需余额支付模式需先充值;可通过「商户余额」接口查询
服务器时钟必需需与标准时间同步(NTP),时间戳偏差超过 300 秒将验签失败

第一次调用(cURL)

快速验证连通性
# 1) 连接测试(免签名,仅运车 / 运宠域提供)
curl "https://yunxijuchuang.com/openapi/v2/car/ping"

# 2) 真实业务请求(需 4 个鉴权头 + JSON body)
curl -X POST "https://yunxijuchuang.com/openapi/v2/express/price" \
  -H "Content-Type: application/json" \
  -H "X-App-Key: ak_8a20c0a00cce4d17" \
  -H "X-Timestamp: 1757824000" \
  -H "X-Nonce: A9B2C30E4F56" \
  -H "X-Signature: 7F3A9C..." \
  -d '{"from_city":"昆明市","to_city":"杭州市","weight":1.5}'
🔧
联调顺序建议:先用「在线调试工具」在浏览器本地生成签名与 cURL,确认鉴权通过后,再接入自己的服务端代码;签名实现务必对照「签名算法」的 canonical 规则。

环境与域名

平台不区分独立沙箱域名:沙箱与生产使用同一套地址,请求由沙箱应用自身的隔离属性自动路由至沙箱环境。

项目说明
生产基址https://yunxijuchuang.com/openapi/v2(唯一基址,请勿使用任何其他前缀)
沙箱使用沙箱应用的 app_key / app_secret 调用同一域名即可,无需切换地址
协议仅 HTTPS,服务端强制校验证书,请勿关闭 SSL 校验
请求方式POST(连接测试为 GET),Content-Type: application/json
字符编码UTF-8,响应不转义中文(JSON_UNESCAPED_UNICODE)
响应头X-API-Version: v2(标识当前命中版本);X-Request-Id 回写请求追踪号
时区Asia/Shanghai;时间字段格式 YYYY-MM-DD HH:mm:ss
金额精度元,两位小数;重量为千克(kg)
建议超时连接 3 秒 / 读取 15 秒(下单等写操作建议 20 秒),请自行实现超时与重试

连接测试

运车与运宠域提供免签名的连接测试端点,仅返回服务信息、不探测任何库表,适合负载均衡探活与连通性自检:

端点鉴权说明
GET /openapi/v2/car/ping免签运车域连通性测试
GET /openapi/v2/pet/ping免签运宠域连通性测试
200 响应
{ "code": 0, "message": "success", "request_id": "...",
  "data": { "service": "openapi-v2", "domain": "car", "time": "2026-09-14 15:10:31", "version": "v2" } }
⚠️
国内快递域未提供 ping 端点。如需验证快递域连通性,请直接调用 POST /openapi/v2/express/price(走完整鉴权与业务链路),以 code=0 判定连通;code=401 说明连通正常但密钥/签名有误,code=1008 说明连通与鉴权均正常、仅该线路未配置价格。

返回结构与错误码

所有端点(含鉴权失败)均返回统一信封 {code, message, request_id, data}——业务结果一律以 code 判断,HTTP 状态码只表达传输与鉴权层语义。
本节汇总:响应信封 · 状态码对照 · 业务码全表 · 常见码速查 · 排障路径 · 处理最佳实践;各业务域专属错误码见对应业务域章节(国内快递 / 汽车托运 / 宠物托运)。

字段类型说明
codeInteger成功恒为 0;失败为业务错误码(如 422 / 404 / 1008 / 2001)
messageString成功默认 success;失败为可读错误文案(可直接提示或落日志)
request_idString请求追踪号。传入 X-Request-Id 则原样返回,否则由平台生成 UUID;排障时必须提供
dataObject / Array / null业务数据;失败时通常为 null,参数校验失败时为 {"errors": {...}}
成功 / 业务失败 / 参数校验失败
// ① 成功(HTTP 200)
{ "code": 0, "message": "success", "request_id": "7c1a9f2e-0b41-4d55-9a1c-2f8e6b3d0451", "data": { ... } }

// ② 业务失败(HTTP 仍为 200,code 区分)
{ "code": 1008, "message": "未找到路线价格: 昆明市 → 拉萨市 (typeid=3),请联系运营配置价格", "request_id": "...", "data": null }

// ③ 参数校验失败(HTTP 仍为 200)
{ "code": 422, "message": "参数验证失败", "request_id": "...",
  "data": { "errors": { "weight": ["重量必须大于 0.01"] } } }

1. HTTP 状态码 × 业务码 对照

HTTPcode含义与处理建议可否重试
2000业务成功,读取 data—
200422参数校验失败 → 读取 data.errors 修正入参后重试否(修正后)
200404 / 1005资源不存在(订单不属当前应用 / 类目车型不存在)→ 不要重试,核对参数否
2001004 / 1008 / 2001 / 2002 / 2003 / 409 / 2600000业务错误 → 逐条处置见下方「3. 常见业务码速查」视 code 而定
401401鉴权失败 → 检查密钥、时间戳、nonce、IP 白名单与签名串构造;不要原样重试否
429429触发限流 → 退避后重试(平台不返回 Retry-After,建议指数退避 + 抖动)退避重试
500500系统异常(生产环境统一文案)→ 可重试,并提供 request_id 联系平台可重试
ℹ️
统一判定范式:if (httpCode === 200 && body.code === 0) 才算成功;只判断 HTTP 状态码会把业务失败误判为成功。
同理,不要用 message 文案做程序判断(文案可能微调),一律以 code 为准。

2. 业务错误码全表(按段位)

区段含义典型 code
0成功—
4xx鉴权 / 参数 / 限流401 鉴权失败 · 404 资源不存在或无权访问 · 422 参数或状态校验失败 · 429 触发限流
1000–1099参数与数据校验1004 参数非法 · 1005 类目 / 订单不存在 · 1008 未配置价格
2000–2099资金与业务状态2001 余额不足 · 2002 状态不允许 · 2003 凭证失效 / 重复操作
5xx · 2600000系统与业务异常兜底500 系统异常 · 2600000 业务异常兜底(报文内 7 位渠道码原样透出)

3. 常见业务码速查(按现象处置)

code典型 message处置动作
422参数验证失败读 data.errors 的字段级明细,修正对应入参
1004参数非法检查格式 / 类型 / 枚举取值(如城市编码、business_type)
1005类目 / 车型 / 订单不存在核对编码;确认订单属于当前应用(跨应用不可见)
1008未找到路线价格该线路未配置价格 → 联系平台运营配价后再试
2001余额不足先充值,再用同一幂等键原样重试
2002状态不允许先查订单最新状态再决策(避免基于旧状态重复操作)
2003报价失效 / 凭证被占用 / 重复操作重新查价获取新凭证后再下单(详见「幂等与重试」)
404订单不存在或无权访问核对单号;确认 merchant_order_no / order_no 归属
429超过每秒 / 每日调用限制指数退避 + 抖动;配额不足见「限流与配额」申请提升
500服务器内部错误退避重试 2–3 次;仍失败携 request_id 联系平台

4. 排障路径(按顺序排查)

① 记录 request_id(响应体字段,等同回调推送的 X-Request-Id) ↓ ② 先看 HTTP 状态码 ├─ 401 → 鉴权层:密钥 / 时间戳 / nonce / IP 白名单 / 签名串构造 ├─ 429 → 限流层:指数退避重试,或申请提升配额 ├─ 500 → 系统层:退避重试 2–3 次,仍失败携 request_id 联系平台 └─ 200 → 进入 ③ ↓ ③ 再看 code ├─ 0 → 成功 ├─ 422 → 读 data.errors 定位到具体字段 ├─ 1004 → 参数格式 / 类型 / 枚举非法 ├─ 1005 → 类目、车型或订单不存在(或不属于当前应用) ├─ 1008 → 该线路未配置价格 → 联系运营配价后再试 ├─ 2001 → 资金账户余额不足 → 充值后原样重试 ├─ 2002 → 当前状态不允许该操作 → 先查询订单最新状态 └─ 2003 → 报价失效 / 凭证被占用 / 重复操作 → 重新查价后重试
ℹ️
排障请提供响应中的 request_id(同时对应平台日志与 Webhook 推送的 X-Request-Id),平台可据此快速定位完整链路。

5. 各业务域专属错误码

下列错误仅发生在特定业务域,通用章节不重复列出:

业务域专属错误示例详见
国内快递渠道编码不存在 · 渠道已被禁用 · 所选渠道当前不可报价或不可下单 · 当前状态不可取消国内快递 → 接入准备
汽车托运余额支付、费用推送与支付、状态流转限制相关汽车托运 → 错误码
宠物托运品种 / 类目校验;与运车域共用状态与支付错误宠物托运 → 差异说明

6. 错误处理最佳实践

  • 判定用 code,不用 HTTP 状态码、更不用 message 文案——业务失败一律返回 HTTP 200 + 非 0 code。
  • 下单必须带幂等键(merchant_order_no):网络超时/抖动时用同一单号重试,平台保证不重复下单、不重复扣款。
  • 区分「可重试」与「不可重试」:422/401/404 与多数 1xxx/2xxx 属业务性问题(修正后再试);429/500 与网络超时属瞬时故障(退避重试)。
  • 退避策略:指数退避 + 抖动(如 1s → 2s → 4s,最多 2–3 次),避免雪崩式重试把配额打满。
  • 错误分级告警:401/429 持续出现 → 检查密钥与配额;500 或 2600000 突增 → 立即携 request_id 联系平台。
  • 日志留全:至少记录 request_id + code + 接口路径 + 时间;排障时平台据此可还原整条链路。
  • 不要吞掉错误:data.errors 的字段级明细应落日志,便于快速定位入参问题。

限流与配额

限流按应用(app_key)维度分桶,共三层:应用级每秒 → 端点级每秒 → 端点级/应用级每日累计。超限统一返回 HTTP 429。

维度计数粒度说明
应用级 · 每秒整个应用所有端点共享阈值取应用配置 per_second_limit;未配置(0)时不启用该维度
端点级 · 每秒按域 + 端点独立计数阈值见下表,应用级配置可覆盖平台模板值
端点级 · 每日按域 + 端点独立累计自然日(Asia/Shanghai)零时重置
应用级 · 每日整个应用所有端点共享阈值取应用配置 daily_limit;未配置(0)时不启用该维度

端点级默认配额(次/秒 · 次/天)

端点每秒每日
express/price · express/bill/query10010,000
express/order/query · express/trace/query20020,000
express/order/create · order/cancel · order/payment-confirm303,000
car|pet/category/list · car|pet/price/query10010,000
car|pet/order/query · car|pet/track/query20020,000
car|pet/order/create · order/pay · order/cancel · fee/pay303,000
car|pet/fee/push · car|pet/merchant/balance505,000
429 响应
// HTTP 429
{ "code": 429,
  "message": "超过接口调用限制(express.order/create 30 次/秒)",
  "request_id": "...",
  "data": null }
⚠️
无 Retry-After 头。触发 429 请自行实现指数退避 + 随机抖动(如 0.5s / 1s / 2s / 4s,叠加 0–300ms 抖动),避免集中重试造成二次冲高;批量下单请自行做队列削峰,不要并发打满 order/create 配额。

安全策略与 IP 白名单

平台在传输、鉴权、防重放、来源限制四个层面提供保护,商户侧需配合做好密钥保管与回调验签。

层面平台机制商户侧要求
传输安全全站 HTTPS,服务端强制校验证书请勿关闭 SSL 校验,勿降级到 HTTP
身份鉴权HMAC-SHA256 请求签名(兼容 MD5 旧应用)妥善保管 app_secret,严禁写入前端代码或公开仓库
防重放时间戳容差 300 秒 + 同一应用 nonce 300 秒内不可重复每次请求生成全新随机 nonce,并保证服务器时钟同步(NTP)
来源限制可选:按应用配置的 IP 白名单校验来源(见下)由平台侧配置——如需启用请联系平台对接人
回调安全推送请求携带签名头,支持事件级开关必须验签后再执行业务,并做 event_id 幂等

IP 白名单规则

配置值行为
留空 / [] / null / -不限制来源 IP(全部放行)
*不限制来源 IP(全部放行)
一个或多个 IP仅放行列出的 IP;分隔符支持逗号、空格、分号、换行
⚠️
白名单为「精确 IP 全等匹配」,不支持 CIDR 网段/通配符(如 203.0.113.0/24 或 203.0.113.* 均无效)。本项由平台侧配置:如需启用,请联系平台对接人提供出口 IP;若出口 IP 为动态地址,建议暂不启用。配置错误会导致所有请求返回 HTTP 401「IP 不在白名单内」。
  • 密钥保管:app_secret 仅保存在服务端,禁止下发给客户端、小程序或浏览器。密钥一旦泄露请立即在开发者中心重置。
  • 密钥轮换:建议定期轮换;轮换后旧密钥失效,需在业务低峰期完成切换。
  • nonce 随机性:使用密码学安全随机数(如 random_bytes / secrets.token_hex),不要用时间戳自增或订单号代替。
  • 回调验签:即使回调地址未公开,也必须验签,防止被伪造推送触发业务动作。
  • 日志脱敏:日志中避免完整打印 app_secret 与客户手机号(平台侧订单接口已对手机号做掩码输出)。

幂等与重试

所有下单接口以 merchant_order_no(商户订单号)做幂等键。网络超时或响应丢失时,用同一单号重试即可安全恢复,平台会返回首次创建的订单。

项目规则
幂等键merchant_order_no,商户侧业务单号,全局唯一
作用范围按应用 / 商户维度隔离,不同商户可使用相同单号互不影响
命中行为返回原订单(不再重复创建、不重复扣款);运车/运宠域响应含 idempotent=true,快递域 message 为「订单已存在(幂等返回)」
未命中场景原订单已取消(运车/运宠)或已取消/已退款(快递)时不视为命中,可复用同一单号重新下单
建议生成方式{业务前缀}{yyyyMMddHHmmss}{4位随机},长度建议 ≤ 32,仅用字母数字与下划线
📌
查价与下单的关系:运车/运宠查价返回的 quote_id 为锁价凭证,报价有有效期且会被占用,请「即查即用」;若返回 2003 报价已失效或被占用,请重新查价,需重新调用查价获取新报价后再下单。

重试策略

HTTP场景是否可重试建议
—连接超时 / 读取超时 / 网络中断可重试用同一 merchant_order_no 重试,幂等保护不会重复下单
200code=0—成功,无需重试
200code=422/1004/1005不可入参或数据问题,修正后再调用
200code=2001 余额不足不可先充值,再原样重试
200code=2003 报价失效需换凭证重新查价获取新 quote_id 后下单
200code=1008 无路线价不可联系运营配置价格
200code=2002/409 状态不允许不可先查询订单当前状态再做决策
401鉴权失败不可修复密钥/签名/时钟问题,非瞬时故障
429触发限流退避重试指数退避 + 抖动
500系统异常可重试退避重试 2–3 次,仍失败携 request_id 联系平台
⚠️
查询接口天然幂等(order/query、trace/query、bill/query、merchant/balance、category/list)可放心重试;写接口(order/create、order/pay、fee/pay、order/cancel)请务必携带幂等键或先查询状态,避免重复提交。

沙箱联调

沙箱应用可跑通完整业务链路,不产生真实资金变动、不触发真实派单,是上线前必做的验证环节。

★ 「调试模式」已下架(2026-09-17)

控制台原有的「开启调试」开关已下架。为统一联调入口、避免概念混淆,请统一使用沙箱应用进行联调验证。

⚠️
现在请统一使用「沙箱应用」:沙箱为独立隔离环境,不产生真实业务单据与资金变动,且不受 24 小时限制。
开通方式:联系平台对接人,由平台在总后台「API管理 → 我的应用」中把该应用切换为沙箱(商户工作台只读展示当前环境)。

沙箱应用属性

项目说明
获取方式由平台开通(联系对接人;控制台当前未提供自助申请入口)。开通后应用标识与商户前缀为 SBX
虚拟资金自动入金 10000 元至沙箱资金账户,可真实走余额支付与费用支付流程
识别方式请求头与鉴权流程与生产完全一致,平台按应用属性自动路由
数据隔离沙箱订单标记为测试单(is_test=1),与生产数据互不可见

各业务域的沙箱行为

业务域沙箱行为识别标记
国内快递查价 / 下单 / 取消 / 轨迹 / 支付确认均在沙箱环境内完成,不产生真实业务单据响应含 sandbox: true;沙箱运单号以 SBX 开头
汽车托运本地资金链真实可跑(扣减的是沙箱虚拟资金),订单走完整状态流转订单标记 is_test=1
宠物托运同运车域,本地资金链真实可跑订单标记 is_test=1
⏱️
可配置响应延迟:平台支持为沙箱响应注入延时(用于验证下游超时与重试逻辑),如需开启请在联调前向平台申请,默认无延迟。

沙箱与生产差异

对比项沙箱生产
请求地址同一域名同一域名
密钥沙箱应用密钥生产应用密钥
物流渠道沙箱环境内完成,无真实物流动作真实下单并派单
资金虚拟资金,不进真实账真实扣款 / 退款
运单号SBX 前缀示例运单号渠道真实运单号
回调推送真实推送(可用于验证验签与幂等)真实推送
限流配额与生产一致与沙箱一致
⚠️
切生产三件事:① 替换为生产应用的 app_key / app_secret;② 确认生产 IP 白名单已包含出口 IP;③ 确认回调地址为生产环境 HTTPS 地址(切勿沿用测试域名),否则事件将进入死信。

签名算法

所有请求需携带 4 个鉴权 Header,签名采用 HMAC-SHA256,结果转大写十六进制:

Header说明
X-App-Key平台分配的应用 Key(ak_ 前缀)
X-TimestampUnix 秒级时间戳,偏差 ≤ 300 秒
X-Nonce随机串,长度 ≤ 64(防重放,同一应用下 300 秒内不可重复)
X-SignatureHMAC-SHA256(app_key + timestamp + nonce + body_json, app_secret),大写十六进制
X-Request-Id选填。请求追踪号,不传由平台生成 UUID
⚠️
v2 与 v1 的差异:v2 签名串包含 nonce(v1 仅为 app_key + timestamp + body_json),请务必确认使用 v2 规则,否则一律验签失败。
sign_demoPHP · Python · Java · Node.js
<?php
// 1. 请求体:键递归升序 ksort 后 JSON(不转义中文与斜杠)
$body = ['merchant_order_no' => 'YT20260914000001', 'channel_code' => '100057', 'weight' => 1.5];
ksort($body);
$bodyJson = json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

// 2. 签名串 = app_key + timestamp + nonce + body_json(v2 含 nonce)
$appKey    = 'ak_8a20c0a00cce4d17';                   // 平台分配
$appSecret = 'sk_****************';                  // 平台分配,仅创建时展示一次
$timestamp = time();                                    // Unix 秒
$nonce     = bin2hex(random_bytes(8));                  // 随机串,长度 ≤ 64
$signStr   = $appKey . $timestamp . $nonce . $bodyJson;

// 3. HMAC-SHA256 → 大写十六进制
$sign = strtoupper(hash_hmac('sha256', $signStr, $appSecret));

// 4. 发送:Header 携带 4 个鉴权参数,Body 为 $bodyJson
//    X-App-Key: $appKey  X-Timestamp: $timestamp  X-Nonce: $nonce  X-Signature: $sign
⚠️
防重放:同一应用下 300 秒内重复使用同一 X-Nonce 将返回 HTTP 401「重复请求(Nonce 已被使用)」;时间戳与平台偏差超 300 秒返回 HTTP 401「时间戳无效或已过期」。全部鉴权失败文案见下方「验签失败排查」。

canonical 签名串精确规则

规则项要求
拼接顺序严格为 app_key + timestamp + nonce + body_json,四段首尾直连、不加任何分隔符
body_json 形态请求体 JSON 字符串:键递归升序(字符串序 ksort)、不转义中文、不转义斜杠
JSON 紧凑性不得含多余空格/换行(PHP json_encode 默认紧凑;Python 需 separators=(",", ":"))
摘要算法HMAC-SHA256,结果转大写十六进制(64 位)
MD5 兼容历史应用若仍用 MD5 算法,结果为小写 32 位;新接入一律使用 HMAC-SHA256
空请求体无参请求时 body_json 取 {},不要传空字符串

各业务类型签名示例(canonical 精准对照)

签名算法与业务类型无关——差异只在 body_json 的内容。下列为典型形态(也可在 在线调试工具中改参数直接生成):

端点body(请求体)示例签名要点
POST /openapi/v2/express/order/query
订单查询(**推荐首次联调用它**)
{"merchant_order_no":"YT20260917000001"} 单键最简形态,用于快速验证签名通路
POST /openapi/v2/express/price
查价
{"from_city":"昆明市","from_province":"云南省","to_city":"杭州市","to_province":"浙江省","weight":1.5} 数值型(weight)不要加引号,否则与平台的 JSON 串不一致
POST /openapi/v2/express/order/create
下单(含嵌套对象)
{"channel_code":"SF","merchant_order_no":"YT20260917000001","receiver":{...},"sender":{...},"weight":1.5} 嵌套对象必须递归排序;merchant_order_no 同时作为幂等键
POST /openapi/v2/car/price
运车查价
{"car_type_id":3,"from_city":"昆明市","quantity":1,"to_city":"杭州市"} 与快递域算法完全一致,仅参数不同
POST /openapi/v2/car/category/list
无参接口
{} ⚠️ 无参时 body_json 必须取 {},不要传空字符串,否则验签失败

各语言易错点对照(逐项核对,90% 的 401 出自这里)

语言键排序中文 / 斜杠转义最常见坑
PHPksort()(嵌套需自己递归)JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES漏了 UNESCAPED_SLASHES → 斜杠变 \/,签名不一致
Pythonsort_keys=Trueensure_ascii=False漏 separators=(",", ":") → 默认带空格,签名不一致
Java需自行实现(无内置排序)统一 UTF-8Jackson 未开启键排序;getBytes() 未指定 UTF-8
Node.js必须自己递归排序(JSON.stringify 不排序)默认不转义 ✔最易踩:以为会自动排序 → 结果一律 401
🧪
签名自检建议:接入阶段先用「订单查询」这类单键 body 打通签名,再换复杂 body——这样能立刻区分"是签名错"还是"是参数错"。

验签失败排查(HTTP 401)

返回 message常见原因处置建议
缺少认证参数(X-App-Key / X-Nonce / X-Signature)未携带鉴权头;自定义头被网关/Nginx 丢弃确认自定义 Header 已放行透传,勿被反向代理过滤
X-Nonce 长度超过 64 位用了长 UUID、时间戳拼接等超长随机串缩短至 ≤ 64 字符
时间戳无效或已过期服务器时钟不准;误用毫秒时间戳启用 NTP 校时,确认使用秒级 Unix 时间戳
AppKey 不存在密钥填写错误;沙箱密钥用于生产应用;应用已删除核对 app_key 与目标环境是否匹配
应用已被禁用应用被后台停用联系平台确认应用状态
IP 不在白名单内出口 IP 未加入白名单;白名单填了 CIDR 网段补入精确出口 IP,或清空白名单
请求体不是合法的 JSONbody 非法 JSON、空 body、以表单方式提交以 application/json 提交合法 JSON
签名校验失败canonical 与平台不一致:键未排序、JSON 含空格、中文被转义、签名串顺序错误本地打印 canonical 与 body 逐字符比对(见上方示例代码)
重复请求(Nonce 已被使用)重试时复用了同一个 nonce每次请求生成全新随机 nonce

核心端点

三大业务域(国内快递 / 汽车托运 / 宠物托运)共用一套鉴权与响应结构。以国内快递为例:

端点说明
POST /openapi/v2/express/price快递查价:返回平台标准渠道报价与费用明细
POST /openapi/v2/express/order/create创建订单(merchant_order_no 幂等)
POST /openapi/v2/express/order/query订单查询:状态 / 运单号 / 费用明细
POST /openapi/v2/express/order/cancel取消订单
POST /openapi/v2/express/order/payment-confirm支付确认发货(月结补差后放行)
POST /openapi/v2/express/trace/query轨迹查询(支持主动同步)
POST /openapi/v2/express/bill/query计费查询:预估 / 实际 / 差价三层快照
📚
完整接口文档见左侧分组:
· 国内快递(7 端点):查价、下单、支付确认发货、订单查询、取消订单、轨迹查询、计费查询 + 回调推送 + 附录;
· 汽车托运(11 端点,含电动车 / 摩托车):类目、查价、下单、余额支付、订单查询、取消、轨迹、费用推送、费用支付、商户余额 + 状态字典;
· 宠物托运(11 端点):类目与品种、宠物查价、宠物下单 + 与车域共用的支付 / 查询 / 取消 / 轨迹 / 费用 / 余额。

POST/openapi/v2/express/price — 查价响应示例

200 响应示例
{
  "code": 0,
  "message": "success",
  "request_id": "7c1a9f2e-0b41-4d55-9a1c-2f8e6b3d0451",
  "data": {
    "total": 2,
    "sandbox": false,
    "quotes": [
      {
        "quote_no": "QUO20260914103000123",
        "channel_id": 2001, "channel_code": "100057",
        "platform_company_code": "SFSY", "platform_company_name": "顺丰速运",
        "platform_product_code": "SFSY-KD-01", "platform_product_name": "顺丰标快",
        "platform_channel_code": "100057", "platform_channel_name": "顺丰速运-标准渠道",
        "biz_type": "express", "settlement_mode": "online", "payment_type": "MONTH",
        "freight": 12.80, "insurance_fee": 3.00, "other_fee": 0, "total_fee": 15.80, "original_price": 18.00,
        "light_goods": 6000, "calc_fee_type": "discount", "supports_payment_confirm": true
      },
      {
        "quote_no": "QUO20260914103000456",
        "channel_id": 2010, "channel_code": "100112",
        "platform_company_code": "YTOD", "platform_company_name": "圆通速递",
        "platform_product_code": "YTOD-KD-01", "platform_product_name": "圆通标快",
        "platform_channel_code": "100112", "platform_channel_name": "圆通速递-电商特惠",
        "biz_type": "express", "settlement_mode": "online", "payment_type": "MONTH",
        "freight": 9.80, "insurance_fee": 0, "other_fee": 0, "total_fee": 9.80, "original_price": 12.00,
        "light_goods": 6000, "calc_fee_type": "ladder", "supports_payment_confirm": false
      }
    ]
  }
}

回调机制与验签

平台在订单状态变更、轨迹更新、计费定案、费用产生等节点,主动向应用配置的回调地址(Webhook)推送事件。接收方返回 HTTP 2xx 即视为投递成功。

投递机制

项目规则
请求方式POST,Content-Type: application/json,body 为事件报文 JSON
成功判定接收方返回 HTTP 2xx 即成功(平台不校验响应体内容)
超时单次投递读取超时 15 秒,请勿在回调中做耗时业务处理
重试失败自动重试 3 次,间隔 10 / 30 / 60 秒
死信保护重试仍失败写入死信队列,可在后台查看与手动重推;未配置回调地址时事件直接进入死信
幂等键event_id(UUID,全局唯一,重试时保持不变)——接收方必须据此去重
事件开关可按应用配置订阅哪些事件,未订阅的事件不推送

推送请求头

Header说明
Content-Type固定为 application/json
X-App-Key接收方应用 Key,用于定位对应 app_secret
X-Timestamp推送时刻的 Unix 秒级时间戳
X-Nonce随机串(16 位),每次投递均不同
X-SignatureHMAC-SHA256 大写签名,算法与请求签名完全一致(见下方验签)
X-Request-Id等于本次事件的 event_id,用于全链路追踪与日志关联
⚠️
回调地址必须为 HTTPS 且公网可达;请勿使用自签证书(平台会校验服务端证书),也勿把回调地址指向需要登录态或加白名单以外的内网地址。

事件清单(按业务域隔离,互不干扰)

每个业务域拥有独立的事件命名空间,下游只订阅自己业务域的事件,互不影响:

业务域event触发时机
国内快递
express.*
express.status.changed快递状态变更(下单、支付、取件、运输、派送、签收、取消等)
express.trace.updated物流轨迹更新(每条新轨迹推送一次)
express.fee.updated费用变更(fee_type:supplement 超重补差 / refund 超轻退差 / paid 补差支付完成)
express.pickup.updated揽收信息(快递员 / 取件码 / 站点)
express.order.changed订单变更(换单 / 改单)
express.workorder.updated工单更新(上游处理结果 / 双向沟通)
汽车托运 / 宠物托运
order.* 与 fee.*
order.status_changed订单状态变更(下单、支付、取件、运输、签收等)
order.cancel_requested已支付在途订单发起取消申请(待平台审批)
order.cancelled订单取消完成(含退款结果)
fee.supplement产生补差单 / 其他费用(待商户支付)
fee.paid补差或费用支付完成
ℹ️
国内快递域 不产生 order.* / fee.* 事件;汽车与宠物域 不产生 express.* 事件。订阅与事件开关均按域独立生效。

报文结构

事件报文(示例)
{
  "event_id": "b3f1c2d4-5e6a-4b7c-8d9e-0f1a2b3c4d5e",
  "event": "express.status.changed",
  "timestamp": 1757824000,
  "order_no": "YT20260914000001",
  "merchant_order_no": "SHOP20260914001",
  "waybill_no": "SF1234567890",
  "status": "transit",
  "data": { "status_text": "运输中", "event_time": "2026-09-14 15:30:00" }
}
ℹ️
除上述统一字段外,各事件会在 data 内追加业务字段(如费用类事件含 pay_amount / remaining_amount / balance_after / fee_type);报文自动携带 merchant_order_no 与 event_time。各域事件明细见「国内快递 → 回调推送」与「汽车托运 / 宠物托运 → 回调事件」。

回调验签(必做)

验签算法与请求签名完全一致:使用该应用的 app_secret,对 回调 body 的 JSON 对象 重算 HMAC-SHA256。

步骤要求
① 取原始 body读取回调请求的原始 JSON body 并 json_decode 为数组(不要直接对原始字符串签名)
② 递归键排序对解析后的数组做递归升序排序(字符串序 ksort),与平台签名前的处理一致
③ 构造 canonicalX-App-Key + X-Timestamp + X-Nonce + 排序后 JSON(不转义中文与斜杠)
④ 计算并比对HMAC-SHA256 后转大写,与请求头 X-Signature 做时间恒定比较
⑤ 校验时间戳建议校验 X-Timestamp 与本地时间偏差(如 ≤ 300 秒),防重放
verify_callback.php
<?php
// 1) 原始 body → 数组(关键:必须重新编码,不能直接签名原字符串)
$raw     = file_get_contents('php://input');
$payload = json_decode($raw, true) ?: [];

// 2) 递归 ksort(与平台一致:字符串序)
$sort = function (array &$arr) use (&$sort) {
    ksort($arr, SORT_STRING);
    foreach ($arr as &$v) { if (is_array($v)) $sort($v); }
};
$sort($payload);
$bodyJson = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

// 3) 构造 canonical 并计算签名
$appKey    = $_SERVER['HTTP_X_APP_KEY']   ?? '';
$timestamp = $_SERVER['HTTP_X_TIMESTAMP'] ?? '';
$nonce     = $_SERVER['HTTP_X_NONCE']     ?? '';
$signature = $_SERVER['HTTP_X_SIGNATURE'] ?? '';
$mySign    = strtoupper(hash_hmac('sha256', $appKey . $timestamp . $nonce . $bodyJson, $appSecret));

// 4) 恒定时间比较 + 时间戳容差
if (!hash_equals($mySign, $signature)) { http_response_code(401); exit('invalid signature'); }
if (abs(time() - (int) $timestamp) > 300)  { http_response_code(401); exit('expired'); }

// 5) 幂等:event_id 去重(缓存 / 唯一索引,TTL 建议 ≥ 7 天)
$eventId = $payload['event_id'] ?? '';
if (!$eventId || Cache::has('hook:' . $eventId)) { echo 'ok'; exit; }
Cache::put('hook:' . $eventId, 1, 86400 * 7);

// 6) 先落库、后异步处理,确保 15 秒内返回
dispatch(new HandleOpenApiEvent($payload));
http_response_code(200);
echo 'success';
⚠️
三个高频坑:① 直接对原始 body 字符串签名 → 必然验签失败,必须解析后递归排序再编码;② 用 == 而非恒定时间比较;③ 在回调里做耗时任务导致超过 15 秒 → 触发无意义重试。请务必先落库、再异步处理。

回调排障

现象可能原因处置
完全收不到推送未配置回调地址;地址非公网 / 非 HTTPS;事件未订阅检查应用回调配置与事件订阅开关;未配置时事件会直接进死信
收到重复推送前次未在 15 秒内返回 2xx,平台按 10/30/60 秒重试用 event_id 幂等,重复事件直接忽略
验签始终失败对原始字符串签名;未递归排序;未转大写;密钥取错按上方示例重写验签;打印 canonical 比对
回调地址返回 500接收方自身异常修复后由平台自动重试,或在后台手动重推
验签通过但业务状态不对未按 event 分派;乱序到达按 event 精确分派(各域事件见上方清单),以 status 为最终态,必要时调用订单查询接口兜底校准

在线调试工具

本地生成签名(Web Crypto API,密钥不出浏览器、不上传服务器)+ 生成 PHP / Python / Java / Node.js 四种语言请求示例(承接原「SDK 与示例代码」),并可选在浏览器内直接试跑。

🧭
第一次接入?建议先看 「接口概述 → 5 分钟跑通」(含复制即用的 cURL)和 「接入流程与准备」;本工具适合在浏览器里快速验证签名与参数。
目标域名:当前页面域名
⚠️ 试跑会向「真实环境」发起调用:若你填的是生产应用的密钥,可能产生真实订单与真实资金变动。
请务必先在「沙箱应用」上试跑(沙箱为独立隔离环境,不产生真实业务单据)。签名仍只在本地生成,密钥不会被存储。
← 在左侧填写参数,点击「生成签名与请求示例」查看结果(含 4 种语言完整示例);如需真实调用,再点「▶ 直接试跑」。
🔒
签名在你的浏览器本地计算,App Secret 不会被发送或存储。试跑使用当前页面所在域名(),以避免 http/https 混用被浏览器拦截;从本机文件或本地服务打开时请自行确认目标地址。生产环境请先在沙箱验证。

帮助中心

接入常见问题速查 —— 点击问题展开答案,或输入关键词搜索。

更新日志

2026-09-17
文档治理 + 「调试模式」下架

① 「调试模式」已下架,联调统一使用「沙箱应用」(沙箱为独立隔离环境,不产生真实业务单据与资金变动);② 文档去除内部实现描述;③ 左侧菜单合并「汽车 / 电动车 / 摩托车托运」(三者共用同一套接口);④ 新增「SDK 与示例代码」章节;⑤ 重复章节收敛为「通用区为唯一源 + 业务域引用」。

2026-09-14
调用基址唯一化(当前版本)

开放平台对外基址收敛为唯一入口 https://yunxijuchuang.com/openapi/v2。原 /api/openapi/v2 兼容别名已下线(历史遗留,经核对无任何实际调用方);历史 v1 接口(/api/openapi/v1/*)同步彻底下线。请勿使用任何其他前缀——多前缀并存会造成限流计数与请求日志口径分裂。

2026-09-14
「接入指引」全量上线

新增接入流程与准备、环境与域名、公共返回结构、限流与配额、安全策略与 IP 白名单、幂等与重试、沙箱联调、订单状态枚举、城市与行政区编码、回调机制与验签、上线自检清单等 11 个接入章节,覆盖接入全生命周期;同步公开端点级限流配额、鉴权失败文案、回调签名校验算法与重试死信策略。

2026-09-14
三大业务域接口文档全量发布

「国内快递」7 个端点(查价 / 下单 / 支付确认发货 / 订单查询 / 取消订单 / 轨迹查询 / 计费查询)与「汽车托运」「宠物托运」各 11 个端点全文发布(含入参契约、响应字段、错误码、回调事件与附录);统一平台标准公司 / 产品编码与订单状态字典,报价与订单输出仅返回平台标准信息,不暴露任何渠道侧内部数据。

2026-09-13
安全加固

Webhook 测试端点纳入签名鉴权;强制 HTTPS 证书校验;推送重试与死信策略文档化。

2026-09-03
B3 企业级规范发布

express / car / pet 三域 27 个端点;merchant_order_no 幂等;channel_code 渠道锁定;计费三层快照;沙箱支持。

2026-08-13
支付确认发货上线

支持月结超重补差后确认放行。

订单状态枚举

三大业务域各自维护状态字典:国内快递使用 status / status_text,汽车托运与宠物托运使用 order_status / order_status_text。业务判断请以英文状态码为准,中文文案仅用于展示。

国内快递(status · 11 种)

statusstatus_text说明
pending待支付订单已创建,等待支付 / 确认
quoted已报价已完成报价
paid已支付已完成支付
submitted取件中已提交渠道,等待上门取件
accepted已取件渠道已揽收
transit运输中在途 / 转运
delivered已完成已派送
signed已完成已签收
cancelled已取消已取消
refunding已取消取消后退款处理中
refunded已取消取消并已退款
pending ──支付/确认──▶ paid ──提交渠道──▶ submitted ──渠道揽收──▶ accepted ──▶ transit ──▶ delivered / signed │ │ └────── 取消 ──────▶ cancelled ◀────── 取消 ──────┘(已支付取消:refunding → refunded)

汽车托运 / 宠物托运(order_status · 14 种)

ℹ️
共 14 种,主链路:negotiating 待议价 → waiting_pay 待支付 → waiting_pickup 待取件 → picking_up 取件中 → picked_up 已取件 → in_transit 运输中 → arrived 已到达 → delivering 配送中 → completed 已完成;另有 pending_cancel 待取消、partial_pay 部分已付、exception 异常处理、cancelled 已取消、paid 历史过渡态。
完整字典(含中文名与说明)见 「汽车托运 → 状态字典」。
negotiating ──议价──▶ waiting_pay ──余额支付──▶ waiting_pickup ──▶ picking_up ──▶ picked_up ──▶ in_transit ──▶ arrived ──▶ delivering ──▶ completed │ pending_cancel(申请取消,待审批;回显原状态) │ partial_pay(部分已付) exception(异常处理) │ cancelled(已取消,含退款结果) ◀────────────────┘
ℹ️
运车 / 运宠域另有 payment_status(unpaid / partial / paid)描述支付进度;旧同义码 picking / picked / transporting / pending 仅用于读取历史数据归一化,平台不再新产,但订单查询的过滤参数兼容传这些旧码。完整字典见「汽车托运 → 状态字典」。
🎯
最佳实践:不要依赖状态流转的到达顺序(Webhook 与轮询可能乱序)。建议以「终态优先」(cancelled / completed / signed 等终态一旦到达即锁定)+「状态查询兜底」的方式维护本地订单状态。

城市与行政区编码

全部接口的寄收地址均以中文行政区名称传递(省 / 市 / 区三级),无需自行维护城市编码;平台内部会完成标准化与匹配。

字段必填说明
from_province / to_province是省级名称,如 云南省(可省略「省」后缀)
from_city / to_city是市级名称,如 昆明市(可省略「市」后缀);直辖市统一写作 北京市 / 上海市 / 天津市 / 重庆市
from_district / to_district否区 / 县名称,如 盘龙区;运车 / 运宠【查价】可为空,【下单】需按各接口要求填写
from_address / to_address视接口详细地址(街道、门牌号)

名称规范化规则

输入平台标准化结果
云南 / 云南省统一按省级名称处理
昆明 / 昆明市统一按市级名称处理(自动补「市」)
北京标准化为 北京市(直辖市补「市」)
内蒙古自治区 / 广西壮族自治区按自治区全称处理,请勿简写为「内蒙古」以外的自定义简称
ℹ️
建议统一传标准全称(如 云南省 / 昆明市 / 盘龙区),可最大程度避免匹配歧义;平台会先做名称标准化再匹配价格。

价格匹配顺序(运车 / 运宠)

查价请求(from_province / from_city / to_province / to_city + 车型类目) ↓ ① 名称规范化(补省 / 市后缀、直辖市补「市」) ↓ ② 按【城市名称】精确匹配价格表(star_city_name / end_city_name) ↓ 未命中 ③ 按【城市编码】兜底匹配(star_city_code / end_city_code) ↓ 仍未命中 ④ 返回 code=1008 · 同城:同城运输暂未配置价格,请联系平台客服 · 异城:未找到路线价格: A → B (typeid=N),请联系运营配置价格
⚠️
国内快递域不参与本地城市匹配:快递查价的省 / 市 / 区字段会原样透传给渠道做可达性与报价判断,因此基层行政区(尤其偏远地区)填写越准确越好;1008 类错误在快递域通常表现为渠道不可达或不可报价。
常见问题原因与处置
查价返回 1008 同城未配置同城线路未维护价格 → 联系运营配置;如属误判同城,请检查省 / 市名称是否规范
查价返回 1008 路线价缺失该城市对未维护价格 → 提供起止城市与车型类目给运营配价
名称正确但仍未命中可能使用了俗称(如「深圳」写作「鹏城」)或区县错配 → 改为标准行政区全称
运宠重量段不匹配宠物按公斤段计价,重量需落在平台维护的公斤段区间内,否则报「未找到价格」

上线自检清单

正式切换生产前,请逐项确认。任一项未通过都可能造成资金损失或订单状态不一致。

正在统计清单项… 清空勾选 导出 Markdown 打印

接入与鉴权

  • 密钥隔离:生产使用独立应用的 app_key / app_secret,且密钥仅存于服务端配置文件,未写入前端或代码仓库。
  • 时钟同步:服务器已启用 NTP,时间戳偏差稳定在 300 秒以内。
  • 签名正确:canonical 拼接顺序正确、body 键已递归升序、中文与斜杠未被转义、HMAC-SHA256 输出大写。
  • nonce 唯一:每次请求生成全新密码学随机 nonce,重试时不复用。
  • IP 白名单:生产出口 IP 已加入白名单(或确认留空不限制),且未误填 CIDR 网段。
  • HTTPS 校验:客户端未关闭 SSL 证书校验。

业务链路

  • 沙箱全链路:已在沙箱完成「查价 → 下单 → 支付 → 订单查询 → 轨迹 → 取消 / 费用」完整闭环。
  • 幂等键:下单统一使用业务侧唯一 merchant_order_no,且超时重试复用同一单号。
  • 报价时效:运车 / 运宠已实现「即查即用」,并对 2003 做自动重新查价。
  • 余额监控:已接入「商户余额」查询并配置低余额预警(阈值 1000 元),避免 2001 导致下单失败。
  • 状态映射:已按英文状态码建立本地状态映射,未硬编码中文文案。
  • 取消分支:已处理「未支付直接取消」「已支付转待审批(pending_cancel)」「审批通过后取消并退款」三种结果。

回调与容错

  • 回调地址:生产 HTTPS 地址已配置且公网可达,证书受信任。
  • 验签:已按「回调机制与验签」实现(解析 body → 递归排序 → 重算 HMAC → 恒定时间比较)。
  • 幂等:已用 event_id 去重,重复推送不产生重复业务动作。
  • 快速应答:回调在 15 秒内返回 HTTP 2xx,耗时逻辑已改为异步(先落库、后处理)。
  • 乱序兜底:已实现「终态优先 + 主动查询校准」,不依赖事件到达顺序。
  • 死信关注:已有人关注后台死信队列并具备手动重推能力。

运维与排障

  • 日志留痕:完整记录 request_id、请求参数、响应 code/message,且日志已脱敏。
  • 退避重试:已实现 429 / 500 的指数退避 + 抖动,并有重试上限。
  • 配额评估:已评估业务峰值是否触及端点级每秒配额,必要时提前申请提升。
  • 监控告警:已对下单失败率、鉴权失败、429、回调失败建立监控告警。
  • 应急联系人:已明确平台侧对接人与商户侧值班人,故障时可快速联动(提供 request_id)。
✅
切换生产建议:先以少量真实订单灰度(如单城市、单渠道)验证资金与回调链路,观察 24 小时无异常后再全量放开。

国内快递接口

1 接入准备

查价、下单、订单查询、取消、支付确认发货、轨迹查询、计费查询、工单接口(2.8,含 2.8.0 工单类型清单)共 13 个端点,配套全量回调推送(3 回调说明,含 3.6 工单回调)。统一鉴权(HMAC-SHA256)、统一响应结构、统一报价口径。

ℹ️
签名鉴权、限流配额、幂等重试、回调验签、错误码与排障等三大业务域通用规则见左侧「接入指引」;本域仅描述快递专属的端点契约与业务规则。
📦 国内快递 · OpenAPI v2更新时间:2026-09-14 11:30
项目说明
接口基址https://yunxijuchuang.com/openapi/v2/express
请求方式POST(application/json)
字符编码UTF-8(响应不转义中文)
鉴权方式HMAC-SHA256 请求签名(见下)
响应头X-API-Version: v2
金额 / 重量元(两位小数)/ 千克 kg(两位小数)
接入顺序查价 → 下单 → 订单查询 / 轨迹 / 计费 → 取消 / 支付确认(按业务),回调接收为必需

请求签名(4 个请求头)

ℹ️
本节为速查摘要;完整签名算法、四语言示例代码、验签失败原因与处置见 「鉴权与安全 → 签名算法」。
Header必填说明
X-App-Key是平台分配的应用 Key
X-Timestamp是Unix 秒级时间戳,与平台时间偏差 ≤ 300 秒
X-Nonce是随机串,长度 ≤ 64;同一应用下 300 秒内不可重复(防重放)
X-Signature是HMAC-SHA256 签名,大写十六进制(兼容 MD5 小写旧应用)
X-Request-Id否请求追踪号,不传由平台生成 UUID

签名串构造(canonical)

canonical 组成
canonical = app_key + timestamp + nonce + body_json
// body_json:请求体 JSON(键递归升序 ksort、不转义中文与斜杠)
signature = strtoupper(hash_hmac('sha256', canonical, app_secret))
// 示例
// app_key=ak_8a20c0a00cce4d17, timestamp=1757824000, nonce=A9B2C30E4F56
// signature=7F3A9C...(64 位大写十六进制)
⚠️
与 v1 的差异:v2 签名串包含 nonce(v1 仅 app_key + timestamp + body),请在接入前确认使用 v2 规则。

统一响应结构

ℹ️
完整字段说明、HTTP 状态码 × code 对照见 「鉴权与安全 → 公共返回结构」。
字段类型说明
codeInteger成功固定 0;失败为业务错误码
messageString成功默认 success;失败为错误文案
request_idString请求追踪号(排障请提供)
dataObject / Array业务数据;失败时为 null
成功 / 失败
{ "code": 0, "message": "success", "request_id": "a1b2c3d4-...", "data": { ... } }

// 失败(HTTP 200,业务码区分)
{ "code": 422, "message": "参数验证失败", "request_id": "a1b2c3d4-...", "data": { "errors": { "weight": ["重量必须大于 0.01"] } } }

鉴权失败(HTTP 401)

触发条件message
缺少 X-App-Key / X-Nonce / X-Signature缺少认证参数(X-App-Key / X-Nonce / X-Signature)
X-Nonce 长度超过 64 位X-Nonce 长度超过 64 位
时间戳为空或偏差 > 300 秒时间戳无效或已过期
AppKey 不存在AppKey 不存在
应用被禁用应用已被禁用
IP 不在白名单IP 不在白名单内
请求体非法 JSON请求体不是合法的 JSON
验签失败签名校验失败
Nonce 已被使用重复请求(Nonce 已被使用)

业务错误码

codemessage说明
422参数验证失败入参校验失败,data.errors 返回字段级明细
404订单不存在或无权访问订单不属于当前应用(仅可操作自有订单)
404渠道编码不存在下单 channel_code 与平台渠道不匹配
422渠道已被禁用所选渠道当前不可用
422所选渠道当前不可报价或不可下单渠道报价失败,data.errors 含原因
422当前状态[xx]不可取消已取消/已退款/已签收订单不可取消
422该渠道不支持支付确认发货渠道未开通支付确认能力
500服务器内部错误,请稍后再试系统异常(生产环境统一文案)
2600000—业务异常兜底码
ℹ️
HTTP 状态码:业务失败(含参数校验 422 与各业务错误码)仍返回 HTTP 200,请以 code 判断;鉴权失败返回 HTTP 401,触发限流返回 HTTP 429,系统级异常返回 HTTP 500(生产环境统一文案)。沙箱:沙箱应用查价 / 下单 / 支付确认均在隔离环境内完成,响应含 sandbox: true,沙箱运单号以 SBX 开头,不产生真实资金与真实派单。

2.1 查价

POST/openapi/v2/express/price复制

按寄收地址、重量与业务维度返回可用渠道报价。报价即商户可下单价格,返回的 channel_code 用于指定渠道下单。

参数名类型必填说明
from_provinceString是寄件省
from_cityString是寄件市
from_districtString否寄件区/县
from_addressString是寄件详细地址(不含省市区)
from_name / from_phoneString否寄件人姓名 / 电话
to_provinceString是收件省
to_cityString是收件市
to_districtString否收件区/县
to_addressString是收件详细地址(不含省市区)
to_name / to_phoneString否收件人姓名 / 电话
goods_typeString是物品类型,如 文件 / 服装 / 日用品
weightDecimal是重量(kg),须 > 0.01
insurance_valueDecimal否物品价值(保价金额,元);传了才计保价费
biz_typeString否业务类型:express 快递 / freight 快运 / cold_chain 冷链,默认 express(机动车托运请走运车域 /car/*,宠物托运请走运宠域 /pet/*)
settlement_modeString否结算模式:online 线上月结 / offline 现付·到付,默认 online
shipping_scenarioString否寄件场景:standard 标准 / merchant_fixed 商家固定 / dewu_fixed 平台专线 / international 国际,默认 standard
payment_typeString否支付方式:MONTH 月结 / PRESENT 现付 / REACH 到付(传了将精准过滤对应渠道)
channel_idsArray否指定渠道 ID 列表(仅查这些渠道)

响应参数

字段类型说明
data.totalInteger可用渠道数
data.sandboxBoolean是否沙箱应用(沙箱响应标识)
data.quotesArray渠道报价列表
quotes[] 渠道报价
quote_noString报价单号
channel_id / channel_codeInteger / String渠道 ID / 平台渠道唯一编码(下单使用 channel_code)
platform_company_code / platform_company_nameString平台标准快递公司编码 / 名称
platform_product_code / platform_product_nameString平台标准产品编码 / 名称
platform_channel_code / platform_channel_nameString平台渠道编码 / 名称(platform_channel_code 与 channel_code 同值,均为平台渠道唯一编码)
biz_type / biz_type_labelString业务类型及标识(express/freight/…)
settlement_mode / settlement_mode_labelString结算模式(monthly 月结 / offline 现付到付)
shipping_scenarioString寄件场景
payment_type / payment_type_labelString支付方式(monthly/cash/collect)
supported_pay_types / _labelArray该渠道支持的支付方式(全列出)
supports_insurance / supports_cod / supports_pickup / supports_sign_returnBoolean渠道能力:保价 / 代收货款 / 上门揽收 / 签收回单
insurance_max_amount / insurance_min / insurance_rateDecimal保价上限 / 保价最低费 / 保价费率
goods_value / insurance_feeDecimal物品价值(回显)/ 保价费(已含在总费用中)
insurance_tipString平台保价提示(平台自建文案,含保额超限提醒)
visibility / is_active / remarkString / Boolean / String渠道可见性 / 是否启用 / 渠道备注
estimated_days / delivery_typeInteger / String预计时效(天)/ 派送类型
freightDecimal纯运费(不含保价费)
other_fee / total_fee / original_priceDecimal其他费用 / 总费用(运费+保价+其他)/ 门市参考原价
first_weight / first_weight_price / additional_weight / additional_weight_priceDecimal首重 / 首重价 / 续重 / 续重价
weight / volume_weightDecimal实重 / 抛重
min_charge / max_weightDecimal最低一票价 / 渠道限重
light_goods / calc_fee_typeDecimal / String抛比系数(如 6000/8000)/ 计费方式
supports_payment_confirmBoolean渠道是否支持支付确认发货(月结超重补差放行)
📐
金额口径:freight 为纯运费(不含保价费等增值费用);total_fee = freight + insurance_fee + other_fee;original_price 为门市参考价,仅用于展示比价。所有金额均为商户可下单价格,下单与计费同口径。
请求示例
{
  "from_province": "云南省", "from_city": "昆明市", "from_district": "盘龙区",
  "from_address": "北京路924号财智心景大厦", "from_name": "王先生", "from_phone": "13800001111",
  "to_province": "浙江省", "to_city": "杭州市", "to_district": "西湖区",
  "to_address": "三墩镇亲亲家园二期", "to_name": "李女士", "to_phone": "13900002222",
  "goods_type": "服装",
  "weight": 1.5,
  "insurance_value": 3000,
  "biz_type": "express",
  "settlement_mode": "online",
  "payment_type": "MONTH"
}
200 响应示例
{
  "code": 0, "message": "success", "request_id": "7c1a9f2e-0b41-4d55-9a1c-2f8e6b3d0451",
  "data": {
    "total": 2,
    "sandbox": false,
    "quotes": [
      {
        "quote_no": "QUO20260914103000123",
        "channel_id": 2001, "channel_code": "100057",
        "platform_company_code": "SFSY", "platform_company_name": "顺丰速运",
        "platform_product_code": "SFSY-KD-01", "platform_product_name": "顺丰标快",
        "platform_channel_code": "100057", "platform_channel_name": "顺丰速运-标准渠道",
        "biz_type": "express", "biz_type_label": "express",
        "settlement_mode": "online", "settlement_mode_label": "monthly",
        "shipping_scenario": "standard",
        "payment_type": "MONTH", "payment_type_label": "monthly",
        "supported_pay_types": ["MONTH", "PRESENT"],
        "supports_insurance": true, "supports_cod": false,
        "supports_pickup": true, "supports_sign_return": false,
        "insurance_max_amount": 300000, "insurance_min": 1, "insurance_rate": 0.005,
        "goods_value": 3000, "insurance_fee": 3.00,
        "insurance_tip": "已按物品价值 3000 元申报保价,保价费 3 元,最高可保 300000 元。",
        "visibility": "all", "is_active": true, "remark": "",
        "estimated_days": 2, "delivery_type": "",
        "freight": 12.80, "other_fee": 0, "total_fee": 15.80, "original_price": 18.00,
        "first_weight": 1, "first_weight_price": 12.80,
        "additional_weight": 1, "additional_weight_price": 5.00,
        "weight": 1.5, "volume_weight": 0,
        "min_charge": 0, "max_weight": 60,
        "light_goods": 6000, "calc_fee_type": "discount",
        "supports_payment_confirm": true
      },
      {
        "quote_no": "QUO20260914103000456",
        "channel_id": 2010, "channel_code": "100112",
        "platform_company_code": "YTOD", "platform_company_name": "圆通速递",
        "platform_product_code": "YTOD-KD-01", "platform_product_name": "圆通标快",
        "platform_channel_code": "100112", "platform_channel_name": "圆通速递-电商特惠",
        "biz_type": "express", "settlement_mode": "online", "payment_type": "MONTH",
        "insurance_fee": 0, "goods_value": 0,
        "estimated_days": 2,
        "freight": 9.80, "other_fee": 0, "total_fee": 9.80, "original_price": 12.00,
        "light_goods": 6000, "calc_fee_type": "ladder",
        "supports_payment_confirm": false
      }
    ]
  }
}

2.2 下单

POST/openapi/v2/express/order/create复制

以 merchant_order_no 为幂等键创建订单;平台重新计价并锁定渠道报价后提交,成功返回订单摘要(含平台订单号、运单号、费用快照)。

参数名类型必填说明
merchant_order_noString是商家订单号(≤64 位,幂等键:同一商户重复提交返回原订单)
channel_codeString是渠道锁定:平台渠道唯一编码(取自「查价」返回的 channel_code)
sender_name / sender_phoneString是寄件人姓名 / 电话
sender_province / sender_cityString是寄件省 / 市
sender_districtString否寄件区/县
sender_addressString是寄件详细地址(不含省市区)
receiver_name / receiver_phoneString是收件人姓名 / 电话
receiver_province / receiver_cityString是收件省 / 市
receiver_districtString否收件区/县
receiver_addressString是收件详细地址(不含省市区)
goods_nameString是物品名称
goods_typeString否物品类型,默认 普通货物
weightDecimal是重量(kg),须 > 0.01
quantityInteger否件数,默认 1
volume / length / width / heightDecimal否体积(m³)/ 长宽高(cm)
insurance_valueDecimal否物品价值(保价金额,元),传了才计保价费
packagingString否包装要求
delivery_typeString否派送方式要求
biz_typeString否业务类型(同「查价」,默认 express)
settlement_modeString否online / offline,默认 online
shipping_scenarioString否standard / merchant_fixed / dewu_fixed / international
payment_typeString否MONTH 月结 / PRESENT 现付 / REACH 到付(须与查价所选一致)
pickup_start_time / pickup_end_timeString否预约取件时间窗,格式 Y-m-d H:i:s
pay_confirmString否Y 需要支付确认(月结 + 渠道支持时生效)/ N 默认
remarkString否商户备注(≤500)

响应参数(订单摘要)

字段类型说明
order_noString平台订单号
merchant_order_noString商家订单号(回显)
waybill_noString运单号(可能为空,由回调携带)
sandboxBoolean沙箱标记(沙箱运单号以 SBX 开头)
status / status_textString订单状态与中文描述(见附录 3)
biz_type / payment_type / settlement_modeString业务类型 / 支付方式 / 结算模式(原样回显)
channelObjectchannel_id / channel_code / company_code / company_name(平台标准公司)
sender / receiverObjectname / phone(已脱敏)/ city / district / address
goodsObjectname / type / weight / volume / quantity
feesObjectquote_total_fee 预估总费用 / actual_total_fee 实际总费用 / difference_amount 差价 / difference_status 差价状态 / merchant_prepaid / merchant_actual
courierObjectname / phone(脱敏)取件员信息
timesObjectcreated_at / submitted_at / pickup_start_time / pickup_end_time / signed_at / delivered_at / cancel_reason
💡
幂等返回:相同 merchant_order_no 再次提交(原单非取消/退款状态)不会重复下单,直接返回原订单摘要,message 为「订单已存在(幂等返回)」。
请求示例
{
  "merchant_order_no": "YT20260914000001",
  "channel_code": "100057",
  "biz_type": "express",
  "settlement_mode": "online",
  "payment_type": "MONTH",
  "sender_name": "王先生", "sender_phone": "13800001111",
  "sender_province": "云南省", "sender_city": "昆明市", "sender_district": "盘龙区",
  "sender_address": "北京路924号财智心景大厦1614",
  "receiver_name": "李女士", "receiver_phone": "13900002222",
  "receiver_province": "浙江省", "receiver_city": "杭州市", "receiver_district": "西湖区",
  "receiver_address": "三墩镇亲亲家园二期",
  "goods_name": "服装", "goods_type": "服装",
  "weight": 1.5, "quantity": 1, "insurance_value": 3000,
  "pickup_start_time": "2026-09-15 09:00:00", "pickup_end_time": "2026-09-15 11:00:00",
  "pay_confirm": "Y", "remark": "轻拿轻放"
}
200 响应示例
{
  "code": 0,
  "message": "下单成功",
  "request_id": "5a2c8e1b-77d0-4a9c-8f31-9b2e5c7a0112",
  "data": {
    "order_no": "YT2609140000123456",
    "merchant_order_no": "YT20260914000001",
    "waybill_no": "SF1234567890123",
    "sandbox": false,
    "status": "submitted", "status_text": "取件中",
    "biz_type": "express", "payment_type": "MONTH", "settlement_mode": "online",
    "channel": {
      "channel_id": 2001, "channel_code": "100057",
      "company_code": "SFSY", "company_name": "顺丰速运"
    },
    "sender": { "name": "王先生", "phone": "138****1111", "city": "昆明市", "district": "盘龙区", "address": "北京路924号财智心景大厦1614" },
    "receiver": { "name": "李女士", "phone": "139****2222", "city": "杭州市", "district": "西湖区", "address": "三墩镇亲亲家园二期" },
    "goods": { "name": "服装", "type": "服装", "weight": 1.5, "volume": 0, "quantity": 1 },
    "fees": {
      "quote_total_fee": 15.80, "actual_total_fee": null,
      "difference_amount": 0, "difference_status": "none",
      "merchant_prepaid": 15.80, "merchant_actual": 0
    },
    "courier": { "name": "", "phone": "" },
    "times": {
      "created_at": "2026-09-14 10:30:12", "submitted_at": "2026-09-14 10:30:14",
      "pickup_start_time": "2026-09-15 09:00:00", "pickup_end_time": "2026-09-15 11:00:00",
      "signed_at": null, "delivered_at": null, "cancel_reason": ""
    }
  }
}

2.5 支付确认发货

POST/openapi/v2/express/order/payment-confirm复制

月结超重补差场景:实际计费高于预估产生差价,商户补足差价后调用本接口,平台通知渠道放行发货(未完成补差前,渠道不放行发货)。

参数名类型必填说明
order_noString3 选 1平台订单号
merchant_order_noString3 选 1商家订单号
waybill_noString3 选 1运单号

业务规则

场景处理
现付 / 到付渠道(payment_type 为 PRESENT/REACH 或 settlement_mode=offline)幂等成功,返回「现付/到付渠道无需支付确认」(快递公司向收件人收款,平台不承担差价风险)
月结渠道 + supports_payment_confirm=false返回 422「该渠道不支持支付确认发货」
订单无差价(difference_amount=0)幂等成功,返回「订单无补差价,无需支付确认」
月结 + 渠道支持 + 存在差价调用渠道支付确认,成功后订单状态更新为 pending_pickup(待揽收·已确认补差),并推送 express.status.changed
订单已取消 / 已退款 / 已完成返回 422「当前状态[xx]不可进行支付确认」

响应参数

字段类型说明
order_no / waybill_noString平台订单号 / 运单号
status / status_textString确认后状态(如 pending_pickup / 待揽收(已确认补差))
confirmedBoolean是否确认成功
sandboxBoolean沙箱标记
request_idString渠道请求追踪号
💡
查价与下单返回的 supports_payment_confirm(报价)/ pay_confirm=Y(下单)共同决定该订单是否需要支付确认。
200 响应示例(月结超重补差确认成功)
{
  "code": 0,
  "message": "支付确认发货成功",
  "request_id": "9b2e5c7a-0112-4c8e-9a41-7d3f0b6e2233",
  "data": {
    "order_no": "YT2609140000123456",
    "waybill_no": "SF1234567890123",
    "status": "pending_pickup",
    "status_text": "待揽收(已确认补差)",
    "confirmed": true,
    "sandbox": false
  }
}

2.3 订单查询

POST/openapi/v2/express/order/query复制

按 order_no / merchant_order_no / waybill_no 三选一查询自有订单,返回完整订单摘要(状态、渠道、费用、寄收信息、时间线)。建议作为回调的兜底对账手段。

参数名类型必填说明
order_noString3 选 1平台订单号
merchant_order_noString3 选 1商家订单号
waybill_noString3 选 1运单号
🔒
归属校验:仅可查询当前应用所属商户的订单,其他订单返回 404 订单不存在或无权访问;三者都未传返回 422。
请求示例
{ "merchant_order_no": "YT20260914000001" }
200 响应示例(订单摘要,字段同「下单」)
{
  "code": 0, "message": "success", "request_id": "e41c7a90-2b6d-4f8a-9c10-3a5e7d2b6601",
  "data": {
    "order_no": "YT2609140000123456",
    "merchant_order_no": "YT20260914000001",
    "waybill_no": "SF1234567890123",
    "sandbox": false,
    "status": "transit", "status_text": "运输中",
    "biz_type": "express", "payment_type": "MONTH", "settlement_mode": "online",
    "channel": {
      "channel_id": 2001, "channel_code": "100057",
      "company_code": "SFSY", "company_name": "顺丰速运"
    },
    "sender": { "name": "王先生", "phone": "138****1111", "city": "昆明市", "district": "盘龙区", "address": "北京路924号财智心景大厦1614" },
    "receiver": { "name": "李女士", "phone": "139****2222", "city": "杭州市", "district": "西湖区", "address": "三墩镇亲亲家园二期" },
    "goods": { "name": "服装", "type": "服装", "weight": 1.5, "volume": 0, "quantity": 1 },
    "fees": {
      "quote_total_fee": 15.80, "actual_total_fee": 16.20,
      "difference_amount": 0.40, "difference_status": "supplement",
      "merchant_prepaid": 15.80, "merchant_actual": 16.20
    },
    "courier": { "name": "张师傅", "phone": "138****4321" },
    "times": {
      "created_at": "2026-09-14 10:30:12", "submitted_at": "2026-09-14 10:30:14",
      "pickup_start_time": "2026-09-15 09:00:00", "pickup_end_time": "2026-09-15 11:00:00",
      "signed_at": null, "delivered_at": null, "cancel_reason": ""
    }
  }
}

2.4 取消订单

POST/openapi/v2/express/order/cancel复制

取消自有订单:平台先向渠道发起取消(若已生成渠道运单号),成功后订单状态更新为 cancelled(已取消)并记录取消原因。

参数名类型必填说明
order_noString3 选 1平台订单号
merchant_order_noString3 选 1商家订单号
waybill_noString3 选 1运单号
reasonString否取消原因(≤200,记录到订单供售后追溯)

业务规则

场景处理
订单已是 cancelled / refunded / signed返回 422「当前状态[xx]不可取消」
已生成渠道运单号先调用渠道取消,渠道失败返回 422「渠道取消失败」
取消成功订单状态置 cancelled / 已取消,返回订单摘要;平台推送 order.cancelled
200 响应示例
{
  "code": 0,
  "message": "取消成功",
  "request_id": "b7d0e411-8c62-4a3f-9e05-1d4c7a90bb02",
  "data": {
    "order_no": "YT2609140000123456",
    "merchant_order_no": "YT20260914000001",
    "waybill_no": "SF1234567890123",
    "sandbox": false,
    "status": "cancelled", "status_text": "已取消",
    "fees": { "quote_total_fee": 15.80, "actual_total_fee": null, "difference_amount": 0, "difference_status": "none" },
    "times": { "created_at": "2026-09-14 10:30:12", "cancel_reason": "客户临时取消寄件" }
  }
}

2.6 轨迹查询

POST/openapi/v2/express/trace/query复制

查询自有订单的物流轨迹;sync=true 时平台先主动向渠道拉取最新轨迹再返回(适合要求实时性的场景,未开启则返回平台已同步的轨迹)。

参数名类型必填说明
order_noString3 选 1平台订单号
merchant_order_noString3 选 1商家订单号
waybill_noString3 选 1运单号
syncBoolean否是否主动同步最新轨迹,默认 false

响应参数

字段类型说明
order_no / waybill_noString平台订单号 / 运单号
statusString订单状态(平台状态字典,见附录 3)
syncObject / null本次主动同步结果;sync=false 时为 null。含 success 同步是否成功 / new_traces 新增节点数 / status 渠道状态 / request_id 渠道追踪号;同步失败时仅含 success:false 与 message(不影响本接口正常返回,此时 traces 为平台已落库轨迹)
totalInteger轨迹条数
tracesArray轨迹节点,按时间正序
traces[].trace_timeString节点时间 Y-m-d H:i:s
traces[].locationString节点位置(网点/中转场)
traces[].descriptionString轨迹描述
traces[].statusString节点状态
请求示例
{ "waybill_no": "SF1234567890123", "sync": true }
200 响应示例
{
  "code": 0, "message": "success", "request_id": "3f9a1c05-6e27-4b18-8d70-2c4f9a3e7755",
  "data": {
    "order_no": "YT2609140000123456",
    "waybill_no": "SF1234567890123",
    "status": "transit",
    "sync": { "success": true, "new_traces": 2, "status": "transit", "request_id": "TR20260915142231" },
    "total": 3,
    "traces": [
      { "trace_time": "2026-09-14 18:05:12", "location": "昆明市盘龙区", "description": "快件已揽收", "status": "已揽收" },
      { "trace_time": "2026-09-14 23:41:08", "location": "昆明转运中心", "description": "已发出,下一站【杭州转运中心】", "status": "运输中" },
      { "trace_time": "2026-09-15 14:22:31", "location": "杭州转运中心", "description": "已到达", "status": "运输中" }
    ]
  }
}

2.7 计费查询

POST/openapi/v2/express/bill/query复制

返回订单计费三层快照:预估费用(下单报价)、实际费用(渠道定案)、差价(补收/退还),以及实重/计费重与商户三层明细,用于对账与差价确认。

参数名类型必填说明
order_noString3 选 1平台订单号
merchant_order_noString3 选 1商家订单号
waybill_noString3 选 1运单号

响应参数

字段类型说明
order_no / waybill_no / statusString订单号 / 运单号 / 订单状态
billedBoolean是否已出账(实际总费用 > 0)
estimatedObject预估:freight_fee 运费 / insurance_fee 保价费 / other_fee 其他费 / total_fee 合计
actualObject实际:字段同上(unbilled 时 total_fee 为 null)
difference.amountDecimal差价金额(正数补收 / 负数退还)
difference.statusString差价状态:none 无差价 / supplement 待补差 / 其他业务态
weight.actual_weight / weight.charge_weightDecimal实际重量 / 计费重量(kg)
merchantObject商户层明细:prepaid_fee 预付 / actual_fee 实际 / difference 差价 / freight_fee / insurance_fee / other_fee
userObject用户层明细(结构同 merchant,手机号等信息已做掩码)
🔒
差价闭环:difference.status=supplement 时平台推送 express.fee.updated(fee_type=supplement),商户补款后平台推送 express.fee.updated(fee_type=paid),再调用「支付确认发货」放行(月结渠道);超轻时 difference.status=refund,平台自动退差并推送 express.fee.updated(fee_type=refund)。
200 响应示例
{
  "code": 0, "message": "success", "request_id": "c2e8b740-9f13-4d6a-b5c8-0e7a1f9d3321",
  "data": {
    "order_no": "YT2609140000123456",
    "waybill_no": "SF1234567890123",
    "status": "signed",
    "billed": true,
    "estimated": { "freight_fee": 12.80, "insurance_fee": 3.00, "other_fee": 0, "total_fee": 15.80 },
    "actual":    { "freight_fee": 13.20, "insurance_fee": 3.00, "other_fee": 0, "total_fee": 16.20 },
    "difference": { "amount": 0.40, "status": "supplement" },
    "weight": { "actual_weight": 1.58, "charge_weight": 2.0 },
    "merchant": { "prepaid_fee": 15.80, "actual_fee": 16.20, "difference": 0.40, "freight_fee": 13.20, "insurance_fee": 3.00, "other_fee": 0 },
    "user":     { "prepaid_fee": 18.00, "actual_fee": 18.50, "difference": 0.50, "freight_fee": 15.00, "insurance_fee": 3.50, "other_fee": 0 }
  }
}

2.8 工单接口

售后问题全流程:创建工单 → 平台处理 → 双方回复沟通 → 完结。工单状态每次变化(平台回复 / 完结等)都会通过 3.6 工单回调 实时推送。工单号 work_order_no 为平台内部编号(WOS 前缀),不含任何上游信息。

2.8.0 工单类型清单

POST/openapi/v2/express/work-orders/types需签名

创建工单前先获取平台统一工单类型。平台采用统一类型体系(各上游差异由平台内部适配,对商户透明),返回 types 为 类型标识 => 平台标准中文名 的映射。

类型标识平台标准中文名
pickup_urge / trace_urge / delivery_urge催揽收 / 催物流 / 催派送
weight_check重量核实(对计费重量有异议)
damage / lost / wrong_item / signed_not_received破损理赔 / 遗失理赔 / 错件 / 签收未收到货
fake_pickup / trace_stall / courier_reassign虚假揽收 / 物流停滞 / 重新分配快递员
offline_charge / payment_change / consumable / other_fee线下收费 / 修改付款方式 / 耗材费 / 其他费用
return_reason / waybill_cancel / intercept_return / receiver_info_change核实退回原因 / 取消运单 / 拦截退回 / 更改收件信息
other其他

响应参数

字段类型说明
typesObject类型标识 => 平台标准中文名(type_name 参数的合法取值)

2.8.1 创建工单

POST/openapi/v2/express/work-orders/create需签名

对指定订单发起售后工单(如破损、丢失、派送异常等),平台客服将在工作时间内处理并通过回调 / 回复接口反馈进展。

参数名类型必填说明
order_noString是平台订单号
type_nameString否工单类型(2.8.0 类型标识或中文名,默认 other 其他)
contentString是问题描述(10~1000 字)
imagesArray否图片 URL 数组(凭证,最多 9 张)

响应参数

字段类型说明
work_order_noString平台工单号(后续回复 / 查询 / 回调均使用此号)
state / state_textInt / String工单状态值与中文说明
请求示例
{
  "order_no": "YT2609140000123456",
  "content": "外包装破损,内件商品有划痕,请协助处理",
  "images": ["https://cdn.merchant.com/evidence/1.jpg"]
}

2.8.2 回复工单

POST/openapi/v2/express/work-orders/reply需签名

在工单处理过程中补充说明 / 追加凭证。平台回复同样进入沟通记录,并通过 3.6 工单回调 推送。

参数名类型必填说明
work_order_noString是平台工单号
contentString是回复内容(1~1000 字)

2.8.3 工单列表 / 详情 / 完结

POST/openapi/v2/express/work-orders/list需签名
参数名类型必填说明
page / page_sizeInt否分页(默认 1 / 20)
stateInt否按工单状态过滤
POST/openapi/v2/express/work-orders/detail需签名

参数:work_order_no(必填)。返回工单全量字段 + 沟通记录 exchanges(每条含 direction 方向 / content / images / created_at)。

POST/openapi/v2/express/work-orders/finish需签名

参数:work_order_no(必填)。商户确认问题解决后主动完结工单;完结后不可再回复。

🔔
工单回调:工单状态变化(平台回复 / 完结 / 关闭)时,平台推送 express.workorder.updated 事件,payload 结构见 3.6 工单回调。建议接入方以回调为准、列表接口做兜底轮询。

3 回调说明

平台在应用配置的 Webhook 地址上以 POST application/json 推送业务事件,出站请求同样携带签名头,接收方可用相同规则验签。快递域共 6 个事件,全部使用同一份报文结构,统一使用平台标准状态码 + 中文语句。

ℹ️
签名鉴权、限流配额、幂等重试、IP 白名单等 通用规则见 「接入指引 → 回调机制与验签」;本节仅描述快递域事件契约与接入方实现要求。

推送机制

项目说明
请求方式POST(Content-Type: application/json)
出站请求头X-App-Key / X-Timestamp / X-Nonce(16 位)/ X-Signature / X-Request-Id(= 事件 ID)
验签规则与请求签名一致:HMAC-SHA256(app_key + timestamp + nonce + body_json) 大写
成功判定接收方返回 HTTP 2xx 即视为成功(不校验响应体内容)
超时15 秒(建议先落库再异步处理,尽快返回 2xx)
重试策略失败自动重试 3 次,延迟阶梯 10 / 30 / 60 秒;仍失败进入死信(dead),可在后台「推送监控」查看报文与手动重推
未配置 Webhook应用未配置 Webhook 地址时,事件不投递并直接标记死信(dead)
幂等payload 含 event_id(UUID),同一下发事件重复推送请按 event_id 去重(重试与补推时 event_id 保持不变)
事件顺序同一 order_no 的事件按发生顺序下发,报文携带 seq(该订单内事件序号,从 1 起单调递增)。接收方请按 seq 升序处理,不要依赖到达顺序(网络重试可能造成到达乱序)
暂停与恢复应用可暂停 / 恢复推送。暂停期间事件以 paused 状态保留(不判死、不消耗重试次数、不丢失);恢复后按「订单 → seq」顺序依次补发
补推平台支持按时间范围 / 事件类型 / 订单号手动补推。补推报文 is_replay=true,event_id 与原事件一致,接收方按 event_id 幂等即可(无需特殊处理,但可据此打标或观察)
日志状态queued 排队 / sending 投递中 / success 成功 / failed 待重试 / dead 死信 / paused 暂停中

事件总览

事件(event)触发时机幂等键
express.status.changed订单状态变更:取件中 / 已取件 / 运输中 / 派送中 / 已到站 / 已完成,以及已取消 / 异常处理 / 揽收失败 / 已作废 / 下单失败event_id
(UUID,重试与补推时保持不变)
express.fee.updated计费更新:超重补收 / 超轻退还 / 其他费用(出账口径变更时推送)
express.pickup.updated揽收信息就绪:取件员 / 取件码 / 取件网点
express.order.changed订单变更:换单(运单号变更)/ 渠道变更 仅部分渠道支持,未收到属正常
express.trace.updated物流轨迹新增(按批推送,按时间升序)
express.workorder.updated工单(售后)状态变化或产生新留言

推送报文结构(6 个事件通用)

字段类型说明
event_idString事件 ID(UUID,幂等键,同时作为出站请求头 X-Request-Id)
eventString事件名(6 个事件之一,见「事件总览」)
event_timeString事件时间 YYYY-MM-DD HH:mm:ss(平台推送时刻)
is_replayBoolean是否补推:false 实时事件 / true 补推(重放)事件
seqInteger该订单内事件序号,从 1 起单调递增(同一 order_no 内唯一)
order_noString平台订单号
waybill_noString运单号(未生成时为空串)
statusString平台统一状态码(取值见「平台标准语句词典」)
status_textString状态中文标准语句,可直接展示(无需自建词典)
channel_codeString平台渠道编码
channel_nameString平台渠道名称
company_codeString平台标准快递公司编码(见附录 1)
company_nameString平台标准快递公司名称
pickupObject揽收信息:courier_name / courier_phone / pickup_code / site_name;无内容时为 {}
dataObject事件业务数据,字段随事件不同(见「事件详情」);无附加数据时为 {}
ℹ️
报文全部为平台标准字段(平台订单号 / 平台渠道 / 平台标准公司 / 平台统一状态码),不包含任何第三方平台的编码或字段名;金额单位元(两位小数)、重量单位 kg。涉及联系人的字段(courier_phone、轨迹描述等)平台已脱敏后下发(手机号形如 138****0000)。

事件详情

以下 6 个事件均使用上节通用报文结构,差异仅在 data(揽收类事件另在 pickup)内,示例均为可直接对照的完整报文。

事件模型 v2 · 旧事件名迁移对照(历史对接方必读)

旧事件名(v1,已停发)新事件名(v2)
order.status_changed→express.status.changed(取消场景 = status: pending_cancel / cancelled,不再单独发事件)
track.updated→express.trace.updated
fee.supplement→express.fee.updated(fee_type: supplement / refund)
fee.paid→express.fee.updated(fee_type: paid)
bill.updated / price.diff✂已废弃(从未实际推送,无对接影响)
⚠️
迁移规则:event_id 保持幂等键职责不变;请改按 event ∈ express.* 前缀 分派,费用类按 fee_type 区分补差 / 退差 / 已支付。汽车托运 / 宠物托运域的事件(order.* / fee.*)不受本迁移影响。

3.1 express.status.changed · 快递状态变更

字段类型说明
statusString变更后的平台统一状态码(见「平台标准语句词典」)
status_textString变更后的中文标准语句,可直接展示
data.status_beforeString变更前状态码(该订单首个事件时为空串)
data.status_before_textString变更前中文标准语句
data.occurred_atString业务发生时间(可能与 event_time 不同,判定先后以 seq 为准)
data.descriptionString状态描述(已脱敏,可直接展示)
express.status.changed 报文示例
{
  "event_id": "8f4d1a2b-0c3e-4f57-9a61-2b7c8d9e0f12",
  "event": "express.status.changed",
  "event_time": "2026-09-18 10:30:00",
  "is_replay": false,
  "seq": 3,
  "order_no": "EXP2026091800000123",
  "waybill_no": "7734567890123",
  "status": "picked_up",
  "status_text": "已取件",
  "channel_code": "100014",
  "channel_name": "STKD-标快-AAAR",
  "company_code": "STKD",
  "company_name": "申通快递",
  "pickup": { "courier_name": "张三", "courier_phone": "138****0000", "pickup_code": "123456", "site_name": "杭州西湖网点" },
  "data": {
    "status_before": "picking_up",
    "status_before_text": "取件中",
    "occurred_at": "2026-09-18 10:28:41",
    "description": "快递员已揽收,运单进入分拣中心"
  }
}

3.2 express.fee.updated · 费用变更(补差/退差/支付)

字段类型说明
data.fee_typeString计费变更类型:overweight 超重补收 / underweight 超轻退还 / other 其他费用
data.fee_type_textString计费变更类型中文
data.charge_weightNumber计费重量(kg,两位小数)
data.freight_feeNumber运费(元,两位小数)
data.insurance_feeNumber保价费(元,两位小数)
data.other_feeNumber其他费用(元,两位小数)
data.total_feeNumber计费总额(元,两位小数)
data.difference_amountNumber相较下单预估价(estimated)的差额(元):正数=待补收、负数=待退还、0=无差价
data.difference_statusStringnone 无差价 / supplement 待补差 / refund 待退还
data.occurred_atString业务发生时间
ℹ️
本事件是出账口径的更新(超重 / 超轻 / 其他费)。生成补差单与补款结果仍通过「计费查询」与相关资金接口确认;月结渠道需补差后方可调用「支付确认发货」放行。
express.fee.updated 报文示例(超重补收 1.20 元)
{
  "event_id": "1c7e5b90-4a2d-4e83-b7f1-6d9a3c5e2b44",
  "event": "express.fee.updated",
  "event_time": "2026-09-18 10:36:05",
  "is_replay": false,
  "seq": 4,
  "order_no": "EXP2026091800000123",
  "waybill_no": "7734567890123",
  "status": "picked_up",
  "status_text": "已取件",
  "channel_code": "100014",
  "channel_name": "STKD-标快-AAAR",
  "company_code": "STKD",
  "company_name": "申通快递",
  "pickup": {},
  "data": {
    "fee_type": "overweight",
    "fee_type_text": "超重补收",
    "charge_weight": 2.50,
    "freight_fee": 14.00,
    "insurance_fee": 3.00,
    "other_fee": 0.00,
    "total_fee": 17.00,
    "difference_amount": 1.20,
    "difference_status": "supplement",
    "occurred_at": "2026-09-18 10:35:12"
  }
}

3.3 express.pickup.updated · 揽收信息

字段类型说明
pickup.courier_nameString取件员姓名
pickup.courier_phoneString取件员电话(已脱敏,形如 138****0000)
pickup.pickup_codeString取件码(部分渠道不提供,为空串)
pickup.site_nameString取件网点名称
pickup.pickup_statusStringpending 待上门 / arrived 已上门 / collected 已揽收
pickup.pickup_status_textString揽收状态中文
pickup.estimated_pickup_timeString预计上门时间(可能为空串)
data.occurred_atString业务发生时间
ℹ️
揽收信息可能分多次推送(先给取件员与网点、后续补取件码);请以最新(seq 最大)的一份为准,字段缺失时保留上一次的取值。
express.pickup.updated 报文示例
{
  "event_id": "2d9f0a31-5c8b-4a17-9e42-73c1b8d5a960",
  "event": "express.pickup.updated",
  "event_time": "2026-09-18 09:52:11",
  "is_replay": false,
  "seq": 2,
  "order_no": "EXP2026091800000123",
  "waybill_no": "7734567890123",
  "status": "picking_up",
  "status_text": "取件中",
  "channel_code": "100014",
  "channel_name": "STKD-标快-AAAR",
  "company_code": "STKD",
  "company_name": "申通快递",
  "pickup": {
    "courier_name": "张三",
    "courier_phone": "138****0000",
    "pickup_code": "123456",
    "site_name": "杭州西湖网点",
    "pickup_status": "arrived",
    "pickup_status_text": "已上门",
    "estimated_pickup_time": "2026-09-18 10:30:00"
  },
  "data": { "occurred_at": "2026-09-18 09:50:03" }
}

3.4 express.order.changed · 订单变更(换单)

字段类型说明
waybill_noString变更后的运单号(顶层字段恒为最新值)
data.change_typeStringwaybill_changed 换单(运单号变更)/ product_changed 渠道(产品)变更
data.change_type_textString变更类型中文
data.waybill_no_beforeString变更前运单号(无变更时为空串)
data.channel_code_beforeString变更前平台渠道编码(无变更时为空串)
data.channel_name_beforeString变更前平台渠道名称
data.occurred_atString业务发生时间
⚠️
仅部分渠道支持本事件:未收到属正常,请以「订单查询」返回的 waybill_no / channel_code 作为最终值;收到本事件时请以最新运单号覆盖本地旧值(不要把旧运单号当作有效单号继续查询或对账)。
express.order.changed 报文示例(换单)
{
  "event_id": "5b3c7e02-9f14-4d68-a0c7-2e8f4b6d1a35",
  "event": "express.order.changed",
  "event_time": "2026-09-18 11:05:20",
  "is_replay": false,
  "seq": 5,
  "order_no": "EXP2026091800000123",
  "waybill_no": "7734567890999",
  "status": "in_transit",
  "status_text": "运输中",
  "channel_code": "100014",
  "channel_name": "STKD-标快-AAAR",
  "company_code": "STKD",
  "company_name": "申通快递",
  "pickup": {},
  "data": {
    "change_type": "waybill_changed",
    "change_type_text": "换单",
    "waybill_no_before": "7734567890123",
    "channel_code_before": "",
    "channel_name_before": "",
    "occurred_at": "2026-09-18 11:03:58"
  }
}

3.5 express.trace.updated · 轨迹更新

字段类型说明
data.tracesArray本次新增轨迹列表(按时间升序),元素结构见下
data.traces[].occurred_atString轨迹发生时间
data.traces[].statusString该节点对应的平台统一状态码
data.traces[].status_textString该节点状态中文
data.traces[].descriptionString轨迹描述(已脱敏:姓名 / 手机号不回传原文)
data.traces[].site_nameString所在网点 / 中转场(可能为空串)
ℹ️
顶层 status / status_text 为最新一条轨迹对应的订单状态;轨迹可能分批推送,接收方请按 occurred_at 去重合并(建议以 occurred_at + description 作为合并键)。
express.trace.updated 报文示例
{
  "event_id": "9e1b4d76-2a30-4c85-8f9b-1d7e5a0c3b62",
  "event": "express.trace.updated",
  "event_time": "2026-09-18 14:20:33",
  "is_replay": false,
  "seq": 6,
  "order_no": "EXP2026091800000123",
  "waybill_no": "7734567890123",
  "status": "in_transit",
  "status_text": "运输中",
  "channel_code": "100014",
  "channel_name": "STKD-标快-AAAR",
  "company_code": "STKD",
  "company_name": "申通快递",
  "pickup": {},
  "data": {
    "traces": [
      { "occurred_at": "2026-09-18 11:40:00", "status": "in_transit", "status_text": "运输中", "description": "快件已离开【杭州转运中心】,发往【上海转运中心】", "site_name": "杭州转运中心" },
      { "occurred_at": "2026-09-18 14:18:00", "status": "in_transit", "status_text": "运输中", "description": "快件已到达【上海转运中心】", "site_name": "上海转运中心" }
    ]
  }
}

3.6 express.workorder.updated · 工单回调

字段类型说明
data.work_order_noString平台工单号(与 order_no 共同定位一张工单)
data.work_order_statusStringpending 待处理 / replied 待回复 / processing 处理中 / finished 已完成
data.work_order_status_textString工单状态中文
data.directionString最新一条对话的来源方:user 用户 / platform 平台 / service 客服
data.contentString最新一条留言内容(已脱敏,可直接展示)
data.occurred_atString业务发生时间
express.workorder.updated 报文示例
{
  "event_id": "6a0d2f84-7b91-4e35-bc08-3f5a1d9e7c20",
  "event": "express.workorder.updated",
  "event_time": "2026-09-18 16:02:47",
  "is_replay": false,
  "seq": 7,
  "order_no": "EXP2026091800000123",
  "waybill_no": "7734567890123",
  "status": "in_transit",
  "status_text": "运输中",
  "channel_code": "100014",
  "channel_name": "STKD-标快-AAAR",
  "company_code": "STKD",
  "company_name": "申通快递",
  "pickup": {},
  "data": {
    "work_order_no": "WO20260918000001",
    "work_order_status": "processing",
    "work_order_status_text": "处理中",
    "direction": "service",
    "content": "已反馈网点核实,预计 2 小时内回复",
    "occurred_at": "2026-09-18 16:01:10"
  }
}

平台标准语句词典(status → status_text)

所有事件的 status / data.traces[].status / status_before 均取自下表;status_text 为平台下发的中文标准语句,接入方无需自建词典。

statusstatus_text阶段说明
negotiating待议价订单已提交,等待价格确认
waiting_pay待支付价格已确认,等待支付
partial_pay部分已付已部分支付
paid已支付支付完成(等待渠道揽收)
picking_up取件中已提交渠道,等待上门取件
picked_up已取件渠道已揽收
pickup_failed揽收失败揽收未成功(需人工介入或改约)
in_transit运输中在途 / 转运
delivering派送中已到达派送网点,正在派送
arrived已到站已到达目的地站点
completed已完成已签收 / 服务完成
exception异常处理运输或派送异常,平台介入处理中
pending_cancel待取消取消申请已提交,等待处理
voided已作废运单在渠道侧作废(非用户取消)
create_failed下单失败渠道下单未成功(非用户取消)
cancelled已取消用户 / 商户主动取消(含退款流程)
ℹ️
请以 status 做业务判断(status_text 仅用于展示,中文文案可能微调)。
语义区分:cancelled(主动取消)、voided(渠道作废)、create_failed(下单失败)为三种不同结果,请勿合并处理。
历史报文可能出现旧状态码(如取件中 / 已取件 / 运输中的早期写法),平台已统一归一到上表标准码;如遇表中未列出的取值,请按 data.occurred_at 顺序落库并联系平台确认。

接入方实现指引

步骤要求
① 验签(必做)校验 X-Signature(HMAC-SHA256 大写;canonical = app_key + timestamp + nonce + 递归排序后的 body JSON),并校验 X-Timestamp 与本地时间偏差(建议 ≤ 300 秒)
② 立即返回 2xx15 秒内返回 HTTP 2xx(不校验响应体);务必先落库、再异步处理,请勿在回调内做耗时业务或外呼
③ 幂等去重以 event_id 去重(重试与补推时 event_id 不变),建议 TTL ≥ 7 天
④ 按 seq 排序同一 order_no 内按 seq 升序处理;seq 跳跃(中间事件未到)时可短暂等待,或用「订单查询」兜底校准
⑤ 识别补推is_replay=true 表示补推事件,按 event_id 幂等处理即可;如需审计可单独打标
⑥ 事件分派按 event 分派处理逻辑,未知事件名请忽略并返回 2xx(平台后续可能新增事件,勿因未知事件报错)
⑦ 状态兜底以最新 seq 的事件为最终态;如与本地不一致,调用「订单查询」校准(避免乱序导致状态回退)
receive_express_event.php(验签 + 幂等 + 顺序 + 应答)
<?php
// ① 验签:算法与入站请求签名完全一致(详见「接入指引 → 回调机制与验签」)
$raw     = file_get_contents('php://input');
$payload = json_decode($raw, true) ?: [];

$sort = function (array &$a) use (&$sort) { ksort($a, SORT_STRING); foreach ($a as &$v) { if (is_array($v)) $sort($v); } };
$body = $payload; $sort($body);
$canonical = ($_SERVER['HTTP_X_APP_KEY'] ?? '') . ($_SERVER['HTTP_X_TIMESTAMP'] ?? '') . ($_SERVER['HTTP_X_NONCE'] ?? '')
           . json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
if (!hash_equals(strtoupper(hash_hmac('sha256', $canonical, $appSecret)), $_SERVER['HTTP_X_SIGNATURE'] ?? '')) {
    http_response_code(401); exit;
}

// ② 幂等:按 event_id 去重(本地缓存 / 唯一索引,TTL 建议 ≥ 7 天)
$eventId = $payload['event_id'] ?? '';
if (!$eventId || Cache::has('express:' . $eventId)) { echo 'ok'; exit; }
Cache::put('express:' . $eventId, 1, 86400 * 7);

// ③ 顺序:同一 order_no 内按 seq 升序处理(迟到事件直接忽略)
$orderNo = $payload['order_no'] ?? '';
$seq     = (int) ($payload['seq'] ?? 0);
$maxSeq  = (int) Cache::get('express:seq:' . $orderNo, 0);
if ($seq <= $maxSeq) { echo 'ok'; exit; }            // 迟到的旧事件:忽略
if ($seq > $maxSeq + 1) {                             // seq 跳跃:登记 pending,或用「订单查询」兜底
    // Cache::put('express:pending:' . $orderNo . ':' . $seq, $payload, 3600);
}
Cache::put('express:seq:' . $orderNo, $seq, 86400 * 7);

// ④ 先落库、后异步处理,15 秒内返回 2xx
dispatch(new HandleExpressEvent($payload, (bool) ($payload['is_replay'] ?? false)));
http_response_code(200);
echo 'success';
本地调试(验证真实报文)
# 方式一(推荐):在开放平台控制台「推送监控」中,按订单号 / 时间范围 / 事件类型触发「补推」,
#   即可收到 is_replay=true 的真实报文,用于验证验签、幂等与顺序处理逻辑。

# 方式二:用 cURL 模拟一次回调请求(签名需按 canonical 规则自行计算)
curl -X POST "https://your-domain.com/webhook/express" \
  -H "Content-Type: application/json" \
  -H "X-App-Key: {app_key}" -H "X-Timestamp: {timestamp}" \
  -H "X-Nonce: {nonce}" -H "X-Signature: {signature}" \
  -H "X-Request-Id: 8f4d1a2b-0c3e-4f57-9a61-2b7c8d9e0f12" \
  -d '{ "event_id": "8f4d1a2b-0c3e-4f57-9a61-2b7c8d9e0f12", "event": "express.status.changed", "seq": 3, "order_no": "EXP2026091800000123", "status": "picked_up", "status_text": "已取件" }'
接收方应答(HTTP 2xx 即成功)
// 推荐返回
{ "success": true }

// 注意:平台仅校验 HTTP 状态码(2xx),非 2xx 或超时会触发重试直至死信

4 附录

附录 1 · 平台标准公司编码(platform_company_code)

platform_company_code公司名称简称业务属性
SFSY顺丰速运顺丰快递
YTOD圆通速递圆通快递
ZTOY中通快递中通快递 / 快运
STOD申通快递申通快递
JTSD极兔速递极兔快递
YUND韵达速递韵达快递
JDKD京东快递京东快递快递
JDWL京东物流京东物流快运
DRO德邦快递德邦快递 / 快运
EMS邮政 EMS邮政快递
KYEX跨越速运跨越快运
ANES安能物流安能快运
BEST百世快运百世快运
CNSD菜鸟速递菜鸟速递快递
SXJD顺心捷达顺心捷达快运
YMDD壹米滴答壹米滴答快运

附录 2 · 平台标准产品(节选)

platform_product_code所属公司产品名称业务类型
SFSY-KD-01顺丰速运顺丰标快快递
SFSY-KD-02顺丰速运顺丰特快快递
YTOD-KD-01圆通速递圆通标快快递
ZTOY-KD-01中通快递中通标快快递
ZTOY-KY-01中通快递中通快运快运
STOD-KD-01申通快递申通标快快递
JTSD-KD-01极兔速递极兔标快快递
YUND-KD-01韵达速递韵达标快快递
JDKD-KD-01京东快递京东特快送快递
JDWL-ZH-01京东物流京东特快重货快运
DRO-KH-01德邦快递德邦精准卡航快运
DRO-KD-01德邦快递德邦标准快递快递
EMS-BK-01邮政 EMS邮政特快专递快递
KYEX-KY-01跨越速运跨越隔日达快运
ANES-KY-01安能物流安能物流快运
BEST-KY-01百世快运百世快运快运
CNSD-BK-01菜鸟速递菜鸟速递快递
SXJD-KY-01顺心捷达顺心捷达零担快运
YMDD-KY-01壹米滴答壹米滴答标快快运
ℹ️
平台标准产品与渠道以「查价」返回的 platform_product_code/name、platform_channel_code/name 为准(按应用授权范围实时返回),本表仅作编码参考。

附录 3 · 订单状态字典(status)

statusstatus_text说明
pending待支付订单已创建,等待支付/确认
quoted已报价已完成报价
paid已支付已完成支付
submitted取件中已提交渠道,等待上门取件
accepted已取件渠道已揽收
transit运输中在途 / 转运
delivered / signed已完成已派送 / 已签收
cancelled / refunding / refunded已取消已取消(含退款中 / 已退款)
ℹ️
请以 status 做业务判断(status_text 仅用于展示,中文文案可能调整)。

附录 4 · 业务维度字典

字段取值
biz_typeexpress 快递 / freight 快运 / cold_chain 冷链
机动车托运(汽车/电动车/摩托车)走运车域 /openapi/v2/car/*;宠物托运走运宠域 /openapi/v2/pet/*,均不通过快递域承载
settlement_modeonline 线上月结 / offline 现付·到付
shipping_scenariostandard 标准 / merchant_fixed 商家固定 / dewu_fixed 平台专线 / international 国际
payment_typeMONTH 月结(label monthly)/ PRESENT 现付(label cash)/ REACH 到付(label collect)
difference_statusnone 无差价 / supplement 待补差(以实际返回为准)

附录 5 · 计费与精度口径

项目口径
金额精度元,保留 两位小数(freight / insurance_fee / other_fee / total_fee)
重量精度千克(kg);weight 为实重、volume_weight 为抛重、charge_weight 为计费重
计费重量进位由渠道按公斤段规则进位确定,以「计费查询」返回的 charge_weight 为准
三层快照estimated(下单报价)/ actual(渠道定案)/ difference(差价),见「计费查询」
保价费由渠道按 insurance_rate / 保额区间计取,返回 insurance_fee(已含在总费用)
报价口径报价字段即商户可下单价格;下单、计费、对账均以此口径为准

5 注意事项(必读)

1. 保价

是否支持保价以报价返回的 supports_insurance 为准,保额上限见 insurance_max_amount,平台会在 insurance_tip 中给出可读提示(如超出上限)。快运等部分渠道存在最低投保金额要求(如按 2000 元起保)。

2. 预约取件时间

(1)pickup_start_time / pickup_end_time 会透传渠道,部分渠道必须预约,不传可能导致无法分配取件员;
(2)预约时间须在取件网点营业时间范围内,否则下单失败并返回渠道错误信息;
(3)取件员可在下单后通过回调/查询获取(courier 字段)。

3. 取消订单

(1)cancelled / refunded / signed 状态的订单不可取消;
(2)已生成渠道运单号的订单需渠道侧取消成功,渠道失败会返回 422;
(3)取消成功后平台推送 order.cancelled 事件,可在「订单查询」确认状态。

4. 支付方式与差价

(1)下单 payment_type 须与查价所选一致,否则可能报到错渠道或报错;
(2)月结渠道超重产生差价时,需商户补款后调用「支付确认发货」放行;现付/到付渠道由快递公司向收件人/寄件人收款,无需确认。

5. 沙箱与联调

沙箱应用的查价 / 下单 / 支付确认均在隔离环境内完成:响应含 sandbox: true,沙箱运单号以 SBX 开头,不产生真实资金变动与真实派单;建议上线前先用沙箱完成全链路自测。
开通方式与各业务域行为详见 「快速开始 → 沙箱联调」。

6. 代收货款(COD)

是否支持以报价返回的 supports_cod 为准;未开通的渠道不支持代收货款业务。

汽车托运接口

运车(car)域共 11 个端点:类目、查价(quote_id 锁价)、下单、余额支付、订单查询(单笔 + 列表分页)、取消(三分支退款)、轨迹、费用推送(双模式)、费用支付(支持部分支付)、商户余额,连接测试免签。

ℹ️
签名鉴权、限流配额、幂等重试、回调验签、城市编码规则等通用规则见左侧「接入指引」;本域仅描述运车专属的端点契约与业务规则。
🚗
适用范围:汽车、电动车、摩托车等机动车托运统一使用本域接口(biz_type 由平台按类目隔离),不经国内快递渠道;合作方无需为不同车型接入不同域名。
🚗 汽车托运 · OpenAPI v2更新时间:2026-09-14 12:10
端点说明
GET /openapi/v2/car/ping连接测试(免签,不探测数据库)
POST /openapi/v2/car/category/list类目列表(一级类目 + 车型/货物类型树)
POST /openapi/v2/car/price/query查价(返回 quote_id 用于锁价下单)
POST /openapi/v2/car/order/create下单(merchant_order_no 幂等)
POST /openapi/v2/car/order/pay余额支付(资金账户行锁扣减 + 流水)
POST /openapi/v2/car/order/query订单查询(单笔 / 列表过滤 + 统一分页)
POST /openapi/v2/car/order/cancel取消订单(三分支:直接退款 / 待审批 / 未支付直接取消)
POST /openapi/v2/car/track/query轨迹查询(含进度百分比)
POST /openapi/v2/car/fee/push其他费用:查询明细 / 推送费用(双模式)
POST /openapi/v2/car/fee/pay费用支付(仅余额,支持部分支付)
POST /openapi/v2/car/merchant/balance商户余额(统一资金账户口径)
ℹ️
鉴权(4 头)、签名串、响应信封({code,message,request_id,data})、限流与沙箱均与「国内快递」一致,见其「接入准备」。本域业务错误码区间见 错误码。
📌
单号格式:订单号 YT+YmdHis+4 位随机;运单号(transport_no)YTWL+YmdHis+4 位随机;费用批次 FP+YmdHis+8 位大写 hex;资金流水 TXN+YmdHis+6 位大写 hex。

连接测试

GET/openapi/v2/car/ping复制

免签名(置于鉴权中间件之外),仅返回服务信息,不做任何库表探测,适合负载均衡探活与连通性自检。

200 响应
{ "code": 0, "message": "success", "request_id": "...",
  "data": { "service": "openapi-v2", "domain": "car", "time": "2026-09-14 12:10:31", "version": "v2" } }

类目列表

POST/openapi/v2/car/category/list复制

返回「一级类目(goods_category)→ 车型/货物类型(goods_type)」两级树,含基础价与木架/送货固定费,用于前端级联选择。

参数名类型必填说明
category_idInteger否按一级类目过滤(别名 cate_id)
cate_idInteger否category_id 的兼容别名
响应字段类型说明
categories[]Arraycategory_id / category_name / category_code / icon / sort / types[]
types[]Arraytype_id / type_name / category_id / base_price / fixed_yoke_fee(木架费,商户免木架时为 0)/ fixed_delivery_fee(送货费)/ description / sort
totalInteger类目总数

查价

POST/openapi/v2/car/price/query复制

按类目 + 城市路线返回报价与折扣明细,返回 quote_id(有效期 300 秒)供下单锁价;折扣仅作用于基础运费,木架费与送货费不打折。

参数名类型必填说明
cate_id / category_idInteger是一级类目 ID(二者其一)
typeid / type_idInteger是车型/货物类型 ID(二者其一)
packing_methodInteger否是否木架包装:1 是 / 0 否(别名 wood_frame_flag)
delivery_typeInteger否1 送货上门(默认)/ 2 网点自提
from_name / from_phoneString是寄件人姓名 / 电话
from_province / from_cityString是寄件省 / 市(城市名自动标准化)
from_district / from_addressString否寄件区县 / 详细地址
to_name / to_phoneString是收件人姓名 / 电话
to_province / to_cityString是收件省 / 市
to_district / to_addressString否收件区县 / 详细地址
has_other_itemsInteger否是否随车物品:1 是 / 0 否
other_items_descString否随车物品说明
appointment_timeString否预约时间
响应字段类型说明
quote_id / expire_time / query_timeString报价单号(Q+YmdHis+8 位 hex)/ 失效时间 / 查询时间
categoryObjectcategory_id / category_name / type_id / type_name
routeObject寄收省市区 + transit_time(预计运输时长)
priceObjectbase_price 折后价 / original_price 牌价 / discount_rate / discount_text / discount_amount / wood_frame_fee / delivery_fee / total_price / original_total
price_detailObjectbase_price_source / discount_source / discount_note / merchant_level_id / channel_type_id
optionsObject可选项回显:packing_method[] / delivery_type[] / has_other_items[]({value,name,fee})
appointment_time / has_other_items / other_items_desc—入参回显
200 响应示例
{
  "code": 0, "message": "success", "request_id": "a1b2c3d4-1111-4a2b-9c3d-4e5f60718293",
  "data": {
    "quote_id": "Q20260914121031A1B2C3D4",
    "expire_time": "2026-09-14 12:15:31",
    "query_time": "2026-09-14 12:10:31",
    "category": { "category_id": 1, "category_name": "轿车", "type_id": 11, "type_name": "小型轿车" },
    "route": {
      "from_province": "云南省", "from_city": "昆明市", "from_district": "盘龙区",
      "to_province": "广东省", "to_city": "深圳市", "to_district": "南山区",
      "transit_time": "2-3天"
    },
    "price": {
      "base_price": 1260.00, "original_price": 1800.00,
      "discount_rate": 0.7, "discount_text": "7折", "discount_amount": 540.00,
      "wood_frame_fee": 200.00, "delivery_fee": 300.00,
      "total_price": 1760.00, "original_total": 2300.00
    },
    "price_detail": {
      "base_price_source": "city_price", "discount_source": "merchant_levels",
      "discount_note": "只有基础运费打折,增值费不打折", "merchant_level_id": 3, "channel_type_id": null
    },
    "options": {
      "packing_method": [{ "value": 1, "name": "木架包装", "fee": 200 }, { "value": 0, "name": "无", "fee": 0 }],
      "delivery_type": [{ "value": 1, "name": "送货上门", "fee": 300 }, { "value": 2, "name": "网点自提", "fee": 0 }],
      "has_other_items": [{ "value": 1, "name": "有" }, { "value": 0, "name": "无" }]
    }
  }
}

下单

POST/openapi/v2/car/order/create复制

入参 = 查价全部入参 + 下单专属字段;from_address / to_address 变为必填。传 quote_id 时以报价金额锁价(并发占用返回 2003)。

参数名类型必填说明
merchant_order_noString否商家订单号(≤64,幂等键;重复提交返回原单 + idempotent:true)
quote_idString否查价返回的报价单号(锁价);失效/占用返回 2003
查价全部入参——cate_id/typeid/packing_method/delivery_type/from_*/to_*/has_other_items/other_items_desc/appointment_time
from_address / to_addressString是详细地址(下单必填)
weightDecimal否车辆重量(kg,可选)
item_countInteger否车辆数量,默认 1
item_remark / remarkString否车辆备注 / 订单备注(≤500)
响应字段类型说明
order_no / merchant_order_noString平台订单号 / 商家订单号
order_status / payment_statusString下单后为 waiting_pay / unpaid
paid_amount / need_pay_amountDecimal已付(0.00)/ 应付金额
is_testBoolean是否测试单(应用开启 debug_mode 且在有效期内)
priceObjectbase_price / original_price / discount_rate / packing_fee / delivery_fee / total_price
categoryObject类目与车型回显
appointment_time / created_atString预约时间 / 创建时间
💡
下单成功即推送 order.status_changed(order_status=waiting_pay / 待支付)。
200 响应示例
{
  "code": 0, "message": "success", "request_id": "b7d0e411-8c62-4a3f-9e05-1d4c7a90bb02",
  "data": {
    "order_no": "YT202609141215337421",
    "merchant_order_no": "MY202609140001",
    "order_status": "waiting_pay", "payment_status": "unpaid",
    "paid_amount": 0, "need_pay_amount": 1760.00,
    "is_test": false,
    "price": { "base_price": 1260.00, "original_price": 1800.00, "discount_rate": 0.7, "packing_fee": 200.00, "delivery_fee": 300.00, "total_price": 1760.00 },
    "category": { "category_id": 1, "category_name": "轿车", "type_id": 11, "type_name": "小型轿车" },
    "appointment_time": "2026-09-15 09:00",
    "created_at": "2026-09-14 12:15:33"
  }
}

余额支付

POST/openapi/v2/car/order/pay复制

使用商户余额支付订单(资金账户行锁 + 流水,禁止负余额)。支付成功后订单状态 paid、payment_status=paid,并生成运单号。

参数名类型必填说明
order_no / merchant_order_noString2 选 1平台订单号 / 商家订单号
pay_amountDecimal否支付金额,默认全额;与应付差额 >0.01 返回 1004
响应字段类型说明
order_no / transport_noString订单号 / 运单号(YTWL 前缀)
order_status / payment_status / payment_methodStringpaid / paid / balance
paid_amount / payment_time / balance_afterDecimal / String / Decimal支付金额 / 支付时间 / 支付后余额
200 响应示例
{
  "code": 0, "message": "success",
  "data": {
    "order_no": "YT202609141215337421", "transport_no": "YTWL202609141216083190",
    "order_status": "paid", "payment_status": "paid", "payment_method": "balance",
    "paid_amount": 1760.00, "payment_time": "2026-09-14 12:16:08", "balance_after": 28240.00
  }
}
ℹ️
余额不足返回 2001 余额不足,当前余额: X,需支付: Y;重复支付 / 状态不允许返回 2002。

订单查询

POST/openapi/v2/car/order/query复制

传 order_no 或 merchant_order_no 走单笔查询;只传过滤条件则走列表(统一分页),列表固定按 id 倒序。

参数名类型必填说明
order_no / merchant_order_noString否任一存在 → 单笔查询
order_statusString否状态过滤(兼容旧码归一:picking→picking_up、picked→picked_up、transporting→in_transit、pending→waiting_pay)
start_date / end_dateString否创建日期范围 Y-m-d(含首尾日)
page / page_sizeInteger否页码(默认 1)/ 每页(默认 20,最大 100)
响应字段类型说明
单笔:直接返回订单对象(字段见下)
列表:{ list[], total, page, page_size, total_pages }
order_no / merchant_order_no / transport_noString订单号 / 商家单号 / 运单号
order_status / order_status_textString状态码 / 中文(见 状态字典)
payment_status / payment_status_text / payment_type / payment_timeStringunpaid/partial/paid 及支付方式与时间
sender / receiverObject{name,phone,province,city,district,address}
itemObjectcategory_code / category_name / count / weight / remark
feeObjectbase_original / base_discount / packing_fee / delivery_fee / other_fee / total_original / total_discount / paid_amount / remaining_amount / actual_total_fee / discount_rate
fee_items[]Array{fee_type,fee_name,fee_amount,remark,batch_no,created_at}(其他费用明细)
courierObjectagent_name / agent_phone(已脱敏)
logistics.current_progressString/Number当前物流进度
timesObjectcreated_at / updated_at / payment_at / appointment_time
cancel_apply_statusString取消审批中时返回 pending_approval

取消订单

POST/openapi/v2/car/order/cancel复制
参数名类型必填说明
order_no / merchant_order_noString2 选 1平台订单号 / 商家订单号
cancel_reasonString否取消原因(≤200)
empty_run_feeDecimal否空跑费(已支付场景可扣,不得超过已支付金额,否则 1004)

三分支处理

场景结果
① 已支付且未开始服务直接取消 + 退款:refund_amount = paid_amount − empty_run_fee,退款流水 order_refund(正号),返回 refund_status;推送 order.cancelled
② 已支付且在途(需平台审批)订单置 pending_cancel,返回 cancel_status=pending_approval 并提示「取消申请已提交,等待平台审批」;推送 order.cancel_requested
③ 未支付直接取消,refund_amount=0;推送 order.cancelled
ℹ️
已取消/已完成订单不可取消(返回 2003 / 2002)。取消审批通过后由平台推送最终 order.cancelled。
200 响应示例(分支① 直接退款)
{
  "code": 0, "message": "success",
  "data": {
    "order_no": "YT202609141215337421",
    "order_status": "cancelled",
    "cancel_time": "2026-09-14 13:02:11",
    "cancel_reason": "客户临时取消",
    "empty_run_fee": 200.00,
    "paid_amount": 1760.00,
    "refund_amount": 1560.00,
    "refund_status": "refunded"
  }
}

轨迹查询

POST/openapi/v2/car/track/query复制
参数名类型必填说明
order_noString3 选 1平台订单号
transport_noString3 选 1运单号
merchant_order_noString3 选 1商家订单号
响应字段类型说明
order_no / transport_no / order_status / status_textString订单标识与状态
current_progressDecimal当前进度百分比(0-100)
sender_city / receiver_cityString起讫城市
estimated_arrival_time / actual_arrival_timeString预计到达 / 实际到达(未到为 null)
track_list[]Array{time,status,desc,city,progress}(正序)
track_countInteger轨迹条数

费用推送(双模式)

POST/openapi/v2/car/fee/push复制

只传 order_no → 查询其他费用明细与待付;同时传 fee_items → 推送费用并返回幂等批次号 batch_no。

参数名类型必填说明
order_noString是平台订单号
fee_items[]Array否费用项:fee_type / fee_name / fee_amount(>0)/ fee_remark
apply_remark / operator_nameString否申请备注 / 操作人(默认「系统」)

fee_type 取值(7 类)

fee_type含义
insurance保险费
warehouse仓储费
loading装卸费
storage保管费
supplement补收费
other其他费用
empty_run空跑费
响应字段类型说明
查询模式
order_no / order_status / order_id—订单标识
total_other_fee / actual_total_fee / remaining_amount / paid_amountDecimal其他费用合计 / 订单实付总额 / 待付 / 已付
fee_count / fee_summary / fee_list[]Integer / Object / Array条数 / 按类型汇总 / 明细列表
推送模式
batch_noString幂等批次号(FP+YmdHis+8 位 hex),重复推送请以 batch_no 查询
push_amount / fee_items[] / status—本次推送合计 / 明细 / pushed
💡
推送成功即推送 fee.supplement(含 batch_no、按类型汇总的 fee_summary、total_amount);订单已完成/已取消不可加费(2002)。

费用支付

POST/openapi/v2/car/fee/pay复制

仅支持余额支付,支持部分支付:支付后未清零 payment_status=partial,清零后 paid。

参数名类型必填说明
order_no / merchant_order_noString2 选 1平台订单号 / 商家订单号
pay_amountDecimal是支付金额(>0,不得超过待付金额)
pay_methodString是固定 balance(B3 仅余额)
out_trade_no / paid_atString否外部交易号 / 支付时间
响应字段类型说明
order_no / pay_amount / paid_at—订单号 / 本次支付 / 支付时间
paid_amount / remaining_amountDecimal累计已付 / 剩余待付
payment_statusStringpaid 或 partial
balance_after / messageDecimal / String支付后余额 / 结果文案(部分支付会提示仍待付金额)
200 响应示例(部分支付)
{
  "code": 0, "message": "success",
  "data": {
    "order_no": "YT202609141215337421", "pay_amount": 300.00,
    "paid_amount": 300.00, "remaining_amount": 120.00,
    "payment_status": "partial", "pay_method": "balance",
    "paid_at": "2026-09-14 13:20:05", "balance_after": 27940.00,
    "message": "部分支付成功,仍待付: ¥120.00"
  }
}
ℹ️
余额不足 2001;已付完(remaining<=0)返回 2003;订单已取消/已完成返回 2002。

商户余额

POST/openapi/v2/car/merchant/balance复制

无入参。统一资金账户口径(无账户时返回零值结构,is_warning=true)。

响应字段类型说明
merchant_id / company_name—商户 ID / 公司名称
balance / available_balance / frozen_balanceDecimal余额 / 可用 / 冻结(当前为 0)
deposit_amountDecimal保证金(当前为 0)
total_recharge / total_consume / total_refundDecimal累计充值 / 消费 / 退款
balance_warning / is_warningDecimal / Boolean预警阈值(1000.00)/ 是否低于阈值
last_recharge_time / last_consume_timeString最近充值 / 消费时间

状态字典(运车 / 运宠通用)

汽车托运与宠物托运共用同一状态字典,订单查询返回的 order_status / order_status_text 均以此为准。

order_statusorder_status_text说明
negotiating待议价订单待平台议价
waiting_pay待支付下单成功,等待余额支付
waiting_pickup待取件已支付,等待上门取件
picking_up取件中取件进行中
picked_up已取件已完成取件
in_transit运输中在途运输
arrived已到达已到达目的城市
delivering配送中派送中
completed已完成已签收 / 已交付
pending_cancel待取消取消申请待平台审批;对外订单查询回显申请前原状态并追加 cancel_apply_status=pending_approval
partial_pay部分已付发生部分支付
exception异常处理异常处理中
cancelled已取消已取消(含退款结果)
paid已支付历史过渡态(已支付未揽收),仅用于读取旧数据

支付状态(payment_status)

payment_statuspayment_status_text说明
unpaid未支付尚未支付
partial部分已付部分支付(费用支付支持)
paid已支付已结清
ℹ️
旧同义码(picking / picked / transporting / pending)仅用于读取历史数据时的展示归一化,平台不再新产;订单查询的 order_status 过滤参数兼容这些旧码。

错误码

codemessage(示例)触发条件
1004寄件人电话格式不正确 / 收件人电话格式不正确手机号不符合 ^1[3-9]\d{9}$
1004支付金额不匹配,需支付: X,传入: Yorder/pay 金额与应付差额 >0.01
1004空跑费不能超过已支付金额,已支付: X,空跑费: Yorder/cancel 空跑费超限
1004fee_items[i].fee_type 无效,有效值: insurance,warehouse,loading,storage,supplement,other,empty_run费用类型不在枚举
1005未找到对应的类目信息,请检查cate_id和typeid类目/车型不存在或停用
1005订单不存在订单不属于当前商户或不存在
1008同城运输暂未配置价格,请联系平台客服同城路线价缺失
1008未找到路线价格: A → B (typeid=X),请联系运营配置价格异城路线价缺失
2001余额不足,当前余额: X,需支付: Y余额不足以支付
2002订单状态不允许支付,当前状态: X非 waiting_pay / 已取消 / 已完成
2002订单已支付,无需重复支付重复支付
2002订单状态不允许推送费用,当前状态: X已完成/已取消订单加费
2003报价已失效或被占用,请重新查价quote_id 过期/已用
2003报价已被占用,请重新查价并发占用同一报价
2003订单无待支付金额,remaining_amount=0费用已付完
409取消申请已提交,等待平台审批已支付在途订单取消(转 pending_cancel)
ℹ️
参数校验失败统一 422 参数验证失败(data.errors 字段级明细);HTTP 状态码仍为 200(鉴权失败 401 除外)。

回调事件

car 域经统一推送服务下发(签名头、重试 3 次、死信机制与「国内快递 → 回调推送」一致),事件级开关可在后台按应用配置。

event触发时机data 主要字段
order.status_changed下单成功order_no / transport_no / order_status=waiting_pay / status_text=待支付
order.status_changed支付成功transport_no / order_status=paid / status_text=已支付 / paid_amount
order.cancel_requested已支付在途申请取消order_status=pending_cancel / status_text=待取消 / cancel_before_status
order.cancelled取消完成(含退款)order_status=cancelled / refund_amount(有退款时)/ empty_run_fee(有时)
fee.supplement费用推送成功batch_no / fee_summary(按类型汇总)/ total_amount
fee.paid费用支付成功pay_amount / remaining_amount / payment_status / balance_after / fee_summary
ℹ️
报文统一含 event_id / event / timestamp / order_no / waybill_no / status / data,并自动追加 merchant_order_no 与 event_time。本域不产生 track.updated / bill.updated / price.diff。

宠物托运接口

运宠(pet)域共 11 个端点:连接测试、类目与品种、查价、下单、余额支付、订单查询(单笔 + 列表分页)、取消、轨迹、费用推送(双模式)、费用支付(支持部分支付)、商户余额。其中「类目 / 查价 / 下单」为宠物专属服务,其余端点与「汽车托运」共用同一服务抽象与统一响应结构。

ℹ️
签名鉴权、限流配额、幂等重试、回调验签、城市编码规则等通用规则见左侧「接入指引」;状态字典与「汽车托运」共用,见 订单状态枚举。
🐾 宠物托运 · OpenAPI v2更新时间:2026-09-14 15:10
端点说明
GET /openapi/v2/pet/ping连接测试(免签,不探测数据库)
POST /openapi/v2/pet/category/list类目与品种(类目树 / 品类品种树 / 公斤段 / 选项)
POST /openapi/v2/pet/price/query查价(按公斤段计价,含送货费与笼子费)
POST /openapi/v2/pet/order/create下单(merchant_order_no 幂等,下单即出运单号)
POST /openapi/v2/pet/order/pay余额支付(资金账户行锁扣减 + 流水)
POST /openapi/v2/pet/order/query订单查询(单笔 / 列表过滤 + 统一分页)
POST /openapi/v2/pet/order/cancel取消订单(三分支:直接退款 / 待审批 / 未支付直接取消)
POST /openapi/v2/pet/track/query轨迹查询(含进度百分比)
POST /openapi/v2/pet/fee/push其他费用:查询明细 / 推送费用(双模式)
POST /openapi/v2/pet/fee/pay费用支付(仅余额,支持部分支付)
POST /openapi/v2/pet/merchant/balance商户余额(统一资金账户口径)
ℹ️
鉴权(4 头)、签名串、响应信封({code,message,request_id,data})、限流与沙箱均与「国内快递」一致,见其「接入准备」。本域订单以 biz_type='pet' 隔离归属,仅可查询 / 操作本域自有订单;状态字典与「汽车托运」共用,见 状态字典。
📌
单号格式:订单号 YP+YmdHis+4 位随机;运单号 YPWB+YmdHis+4 位随机(下单即生成);费用批次 FP+YmdHis+8 位大写 hex;资金流水 TXN+YmdHis+6 位大写 hex。

连接测试

GET/openapi/v2/pet/ping复制

免签名(置于鉴权中间件之外),仅返回服务信息,不做任何库表探测,适合负载均衡探活与连通性自检。

200 响应
{ "code": 0, "message": "success", "request_id": "...",
  "data": { "service": "openapi-v2", "domain": "pet", "time": "2026-09-14 15:10:31", "version": "v2" } }

类目与品种

POST/openapi/v2/pet/category/list复制

返回「一级类目 → 二级类目(含公斤区间与固定送货费)」与「一级品类 → 二级品种」两棵树,以及可用公斤段与送货 / 笼子选项字典,用于前端级联选择与下单校验。

参数名类型必填说明
category_idInteger否按一级类目过滤(别名 cate_id)
cate_idInteger否category_id 的兼容别名
species_idInteger否按一级品类过滤(返回该品类下的品种)
响应字段类型说明
categories[]Arraycategory_id / category_name / icon / intro / sort / types[]
categories[].types[]Arraytype_id / type_name / weight_min / weight_max(重量档区间)/ weight_limit / base_price / fixed_delivery_fee(送货费)/ fixed_packaging_fee / intro / sort
species[]Arrayspecies_id / species_name / icon / sort / breeds[]
species[].breeds[]Arraybreed_id / breed_name / species_id / sort
weight_rangesArray可下单公斤段(如 1-3 / 3-10 / 10+)
delivery_optionsArray{value,name,description}:1 送货上门 / 2 网点自提
cage_optionsArray{value,name,warning}:1 有笼子·航空箱 / 0 没有笼子
total_categoriesInteger返回的一级类目数
ℹ️
类目与品种的职责区分:categories(一级 / 二级类目)是计价与下单的必填依据;species(品类 / 品种)仅用于信息展示与下单校验(不参与查价)。字典类数据平台侧有 1 小时缓存,变更后最长 1 小时生效。

查价

POST/openapi/v2/pet/price/query复制

按类目 + 品类 + 重量档 + 城市路线返回宠物托运报价(含折扣、送货费、笼子费)。本接口不返回 quote_id、不做锁价,下单时平台按同一计价服务实时重算。

参数名类型必填说明
category_id / cate_idInteger是一级类目 ID(二者其一)
type_id / typeidInteger是二级类目 ID(二者其一)
species_idInteger是一级品类 ID(下单时校验)
breed_id / breed_nameInteger / String否二级品种 ID / 自定义品种名称(下单时二者至少传一个)
weightDecimal是宠物重量(kg,>0),须落在该二级类目的重量档区间内
cage_providedInteger否是否自备笼子:1 有笼子 / 0 没有笼子(默认 0,为 0 时计笼子费)
delivery_typeInteger否1 送货上门(默认,计送货费)/ 2 网点自提(免送货费)
from_name / from_phoneString是寄件人姓名 / 电话
from_province / from_cityString是寄件省 / 市(城市名自动标准化)
from_districtString否寄件区/县
to_name / to_phoneString是收件人姓名 / 电话
to_province / to_cityString是收件省 / 市
to_districtString否收件区/县
响应字段类型说明
categoryObjectcategory_id / category_name / type_id / type_name
routeObject寄收省市区 + transit_time(预计运输时长)
weight_infoObjectweight 本次重量 / weight_range 命中的公斤段
priceObjectoriginal_price 基础运费牌价 / discount_price 折后基础运费 / discount_rate / discount_text / discount_amount / delivery_fee 送货费 / cage_fee 笼子费 / total_price 合计 / total_original 未折合计
price_detailObject计价来源说明:base_price_source / delivery_fee_source / cage_fee_source / discount_source / discount_note
optionsObject可选项回显:delivery_type[] / cage_provided[]({value,name,fee|warning})
cage_warningString未自备笼子时的提醒文案(自备时为空串)
query_timeString查询时间

计价口径

pet_price 计价公式
// 基础运费(按公斤段匹配 pet_price 行:首重 7kg / 续重 1kg)
base = 首重价 + 续重价 × ceil(max(0, weight − 首重) / 续重)
// 送货费:送货上门才收(取自 pet_type.fixed_delivery_fee)
delivery_fee = delivery_type == 1 ? fixed_delivery_fee : 0
// 笼子费:未自备笼子才收(取自 pet_price.cage_price)
cage_fee = cage_provided == 0 ? cage_price : 0
// 合计(折扣只作用于基础运费,送货费与笼子费不打折)
total = base × discount_rate + delivery_fee + cage_fee
200 响应示例
{
  "code": 0, "message": "success", "request_id": "1f4b7d92-3c58-4e21-a6b0-8d9c2f5e7043",
  "data": {
    "category": { "category_id": 1, "category_name": "宠物猫", "type_id": 5, "type_name": "小型猫(1-5kg)" },
    "route": {
      "from_province": "云南省", "from_city": "昆明市", "from_district": "盘龙区",
      "to_province": "浙江省", "to_city": "杭州市", "to_district": "西湖区",
      "transit_time": "3-5天"
    },
    "weight_info": { "weight": 4, "weight_range": "1-5" },
    "price": {
      "original_price": 480.00, "discount_price": 432.00,
      "discount_rate": 0.9, "discount_text": "9折", "discount_amount": 48.00,
      "delivery_fee": 100.00, "cage_fee": 80.00,
      "total_price": 612.00, "total_original": 660.00
    },
    "price_detail": {
      "base_price_source": "pet_price (weight_range: 1-5)",
      "delivery_fee_source": "pet_type.fixed_delivery_fee",
      "cage_fee_source": "pet_price.cage_price",
      "discount_source": "merchant_levels",
      "discount_note": "只有基础运费打折,送货费/笼子费不打折"
    },
    "options": {
      "delivery_type": [{ "value": 2, "name": "网点自提", "fee": 0 }, { "value": 1, "name": "送货上门", "fee": 100 }],
      "cage_provided": [{ "value": 1, "name": "有笼子/航空箱" }, { "value": 0, "name": "没有笼子", "warning": "请提前准备好笼子,以免额外产生笼子费用" }]
    },
    "cage_warning": "请提前准备好笼子,以免额外产生笼子费用",
    "query_time": "2026-09-14 15:12:04"
  }
}
ℹ️
错误码:1005 一级/二级类目不存在;1008 宠物重量不在该二级类目范围内,或该路线未配置价格(message 会给出城市、type_id 与重量,便于运营定位)。

下单

POST/openapi/v2/pet/order/create复制

宠物托运下单:平台按同一计价服务实时重算金额后落单,下单即生成运单号,订单初始状态 waiting_pay(待支付)。

参数名类型必填说明
merchant_order_noString否商家订单号(≤64,幂等键;重复提交返回原单 + idempotent:true)
quote_idString否平台收下但不锁价,下单金额以实时重算为准
category_id / cate_idInteger是一级类目 ID(二者其一)
type_id / typeidInteger是二级类目 ID(二者其一)
species_idInteger是一级品类 ID
breed_id / breed_nameInteger / String2 选 1二级品种 ID / 自定义品种名称(至少传一个;breed_id 查不到且有 breed_name 时按自定义品种放行)
weightDecimal是宠物重量(kg,>0),须落在二级类目重量档区间内
cage_providedInteger否1 有笼子 / 0 没有笼子(默认 0)
delivery_typeInteger否1 送货上门(默认)/ 2 网点自提
from_name / from_phoneString是寄件人姓名 / 电话(手机号需符合 ^1[3-9]\d{9}$)
from_province / from_city / from_addressString是寄件省 / 市 / 详细地址
from_districtString否寄件区/县
to_name / to_phoneString是收件人姓名 / 电话
to_province / to_city / to_addressString是收件省 / 市 / 详细地址
to_districtString否收件区/县
appointment_timeString否预约时间
remarkString否订单备注(≤500)
响应字段类型说明
order_no / waybill_no / merchant_order_noString平台订单号(YP 前缀)/ 运单号(YPWB 前缀)/ 商家订单号
order_status / payment_statusString下单后固定 waiting_pay / unpaid
paid_amount / need_pay_amountDecimal已付(0.00)/ 应付金额
pet_infoObjectspecies_id / species_name / breed_id / breed_name / weight / weight_range / cage_provided / cage_warning
priceObjectcost_price 折后基础运费 / original_price 牌价 / discount_rate / cage_fee / delivery_fee / total_fee
categoryObject类目与二级类目回显
deliveryObjectdelivery_type / delivery_name(送货上门 / 网点自提)
created_atString创建时间
💡
下单成功即推送 order.status_changed(order_status=waiting_pay / 待支付);支付成功后订单进入待取件并再次推送。
请求示例
{
  "merchant_order_no": "PET20260914000001",
  "category_id": 1, "type_id": 5,
  "species_id": 2, "breed_id": 18, "breed_name": "英国短毛猫",
  "weight": 4, "cage_provided": 0, "delivery_type": 1,
  "from_name": "王先生", "from_phone": "13800001111",
  "from_province": "云南省", "from_city": "昆明市", "from_district": "盘龙区",
  "from_address": "北京路924号财智心景大厦1614",
  "to_name": "李女士", "to_phone": "13900002222",
  "to_province": "浙江省", "to_city": "杭州市", "to_district": "西湖区",
  "to_address": "三墩镇亲亲家园二期",
  "appointment_time": "2026-09-15 09:00", "remark": "请勿剧烈颠簸"
}
200 响应示例
{
  "code": 0, "message": "success", "request_id": "a7c31e58-0d94-4b72-8f16-5e2d9a4c3307",
  "data": {
    "order_no": "YP202609141513227431", "waybill_no": "YPWB202609141513229902",
    "merchant_order_no": "PET20260914000001",
    "order_status": "waiting_pay", "payment_status": "unpaid",
    "paid_amount": 0, "need_pay_amount": 612.00,
    "pet_info": {
      "species_id": 2, "species_name": "猫",
      "breed_id": 18, "breed_name": "英国短毛猫",
      "weight": 4, "weight_range": "1-5", "cage_provided": 0,
      "cage_warning": "请提前准备好笼子,以免额外产生笼子费用"
    },
    "price": { "cost_price": 432.00, "original_price": 480.00, "discount_rate": 0.9, "cage_fee": 80.00, "delivery_fee": 100.00, "total_fee": 612.00 },
    "category": { "category_id": 1, "category_name": "宠物猫", "type_id": 5, "type_name": "小型猫(1-5kg)" },
    "delivery": { "delivery_type": 1, "delivery_name": "送货上门" },
    "created_at": "2026-09-14 15:13:22"
  }
}
ℹ️
错误码:1004 寄件人/收件人电话格式不正确、重量超出类目区间、breed_id 与 breed_name 同时为空;1005 一级品类 / 二级品种不存在;1008 该路线未配置价格。

支付 / 查询 / 取消 / 轨迹 / 费用 / 余额

以下端点与「汽车托运」共用同一服务抽象与统一响应结构,仅归属域(biz_type='pet')不同:入参、出参、业务规则、错误码与状态字典完全一致,请直接参照汽车托运对应章节。

端点参数参照章节
POST /openapi/v2/pet/order/payorder_no / merchant_order_no(2 选 1)、pay_amount余额支付
POST /openapi/v2/pet/order/query单笔:order_no / merchant_order_no;列表:order_status / start_date / end_date / page / page_size订单查询
POST /openapi/v2/pet/order/cancelorder_no / merchant_order_no、cancel_reason、empty_run_fee取消订单
POST /openapi/v2/pet/track/queryorder_no / transport_no / merchant_order_no(3 选 1)轨迹查询
POST /openapi/v2/pet/fee/pushorder_no 必填;fee_items[] / apply_remark / operator_name费用推送
POST /openapi/v2/pet/fee/payorder_no / merchant_order_no、pay_amount、pay_method=balance、out_trade_no / paid_at费用支付
POST /openapi/v2/pet/merchant/balance无入参商户余额

本域差异说明

项目说明
运单号字段宠物域运单号在下单时即生成(YPWB 前缀),因此轨迹查询、取消订单可直接使用运单号;订单查询返回字段名同为 transport_no。
订单查询「物品」字段在通用 item 基础上追加宠物专属字段:species_id / species_name / breed_id / breed_name / breed_custom(是否自定义品种)/ weight_range / cage_provided。
费用字段映射宠物域 fee.cage_fee 落库为 fee.packing_fee(笼子费与「包装费」同列口径),下单响应中的 price.cage_fee 与之一致。
取消三分支与汽车托运一致:已支付未开始服务 → 直接取消 + 退款;已支付在途 → pending_cancel 待平台审批;未支付 → 直接取消。
状态与支付状态见 状态字典(运车 / 运宠通用)。
订单查询 200 响应示例(节选)
{
  "code": 0, "message": "success",
  "data": {
    "order_no": "YP202609141513227431", "merchant_order_no": "PET20260914000001",
    "transport_no": "YPWB202609141513229902",
    "order_status": "waiting_pay", "order_status_text": "待支付",
    "payment_status": "unpaid", "payment_status_text": "未支付",
    "item": {
      "category_code": "5", "category_name": "小型猫(1-5kg)", "count": 1, "weight": 4,
      "species_id": 2, "species_name": "猫", "breed_id": 18, "breed_name": "英国短毛猫",
      "breed_custom": 0, "weight_range": "1-5", "cage_provided": 0
    },
    "fee": { "base_original": 480.00, "base_discount": 432.00, "packing_fee": 80.00, "delivery_fee": 100.00, "total_discount": 612.00, "paid_amount": 0, "remaining_amount": 612.00 },
    "times": { "created_at": "2026-09-14 15:13:22", "appointment_time": "2026-09-15 09:00:00" }
  }
}

回调事件

宠物托运经统一推送服务下发(签名头、成功判定、重试 3 次、死信机制均与「国内快递 → 回调推送」一致),事件级开关可在后台按应用配置。

event触发时机data 主要字段
order.status_changed下单成功order_no / transport_no / order_status=waiting_pay / status_text=待支付
order.status_changed支付成功transport_no / order_status / status_text / paid_amount
order.cancel_requested已支付在途申请取消order_status=pending_cancel / status_text=待取消 / cancel_before_status
order.cancelled取消完成(含退款)order_status=cancelled / refund_amount(有退款时)/ empty_run_fee(有时)
fee.supplement费用推送成功batch_no / fee_summary(按类型汇总)/ total_amount
fee.paid费用支付成功pay_amount / remaining_amount / payment_status / balance_after / fee_summary
ℹ️
报文统一含 event_id / event / timestamp / order_no / waybill_no / status / data,并自动追加 merchant_order_no 与 event_time。本域不产生 track.updated / bill.updated / price.diff。