开发文档 / 接入指引 / 接口概述
开放平台开发文档
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
订单查询:状态 / 运单号 / 费用明细一次拉全
接入流程与准备
从注册到上线的标准路径共 6 步。平台提供沙箱应用,建议先在沙箱完成全链路自测,验证通过后再切换生产密钥正式上线。
1
注册商户并完成企业认证
在云兔开放平台注册商户账号,完成企业实名认证;认证通过后方可创建应用、开通业务域与充值资金账户。
2
创建应用,获取密钥
在「开发者中心 → 应用管理」创建应用,获得 app_key 与 app_secret。app_secret 仅在创建时展示一次,请立即妥善保管;遗失需重置密钥。
3
配置安全与回调
在应用详情配置 IP 白名单(可选)与 Webhook 回调地址(接收订单状态、轨迹、费用等事件推送,须为 HTTPS 且公网可达)。
4
创建沙箱应用并联调
申请沙箱应用(environment=sandbox,预置虚拟资金 10000 元),按「查价 → 下单 → 支付 → 查询 → 取消 → 回调接收」跑通全链路。
5
切换生产应用
使用生产应用的 app_key / app_secret,将请求基址从沙箱切至生产域名,完成一笔真实小额订单验证。
6
上线与运维
按「上线自检清单」逐项确认;上线后关注限流配额、回调投递与死信,排障时提供响应中的 request_id。
接入前置条件
| 项目 | 必要性 | 说明 |
| 企业实名认证 | 必需 | 创建应用与开通业务域的前置条件 |
| 业务域开通 | 必需 | 国内快递 / 汽车托运 / 宠物托运按业务需要申请开通,未开通的域调用返回无权限 |
| 回调地址(Webhook) | 强烈建议 | 须 HTTPS 且公网可达;未配置回调地址时,平台事件推送将直接进入死信,无法自动重投 |
| IP 白名单 | 可选 | 留空表示不限制来源 IP;详见「安全策略」 |
| 资金账户 | 运车 / 运宠必需 | 余额支付模式需先充值;可通过「商户余额」接口查询 |
| 服务器时钟 | 必需 | 需与标准时间同步(NTP),时间戳偏差超过 300 秒将验签失败 |
第一次调用(cURL)
快速验证连通性
# 1) 连接测试(免签名,仅运车 / 运宠域提供)
curl "https://api.yuntu-wl.com/openapi/v2/car/ping"
# 2) 真实业务请求(需 4 个鉴权头 + JSON body)
curl -X POST "https://api.yuntu-wl.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 规则。
环境与域名
平台不区分独立沙箱域名:沙箱与生产使用同一套地址,由应用的 environment 属性决定请求走沙箱模拟还是真实链路。
| 项目 | 说明 |
| 生产基址 | https://api.yuntu-wl.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},无 HTTP 状态码差异化的业务语义——请以 code 判断业务结果。
| 字段 | 类型 | 说明 |
code | Integer | 成功恒为 0;失败为业务错误码(如 422 / 404 / 1008 / 2001) |
message | String | 成功默认 success;失败为可读错误文案(可直接提示或落日志) |
request_id | String | 请求追踪号。传入 X-Request-Id 则原样返回,否则由平台生成 UUID;排障时必须提供 |
data | Object / 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"] } } }
HTTP 状态码 × code 对照
| HTTP | code | 含义与处理建议 |
| 200 | 0 | 业务成功,读取 data |
| 200 | 422 | 参数校验失败 → 读取 data.errors 修正入参后重试 |
| 200 | 404 / 1005 | 资源不存在(订单不属当前应用 / 类目车型不存在)→ 不要重试,核对参数 |
| 200 | 1004 / 1008 / 2001 / 2002 / 2003 / 409 / 2600000 | 业务错误 → 按「错误码与排障」处置;2003(报价失效)等需重新查价 |
| 401 | 401 | 鉴权失败 → 检查密钥、时间戳、nonce、IP 白名单与签名串构造;不要原样重试 |
| 429 | 429 | 触发限流 → 退避后重试(平台不返回 Retry-After,建议指数退避) |
| 500 | 500 | 系统异常(生产环境统一文案)→ 可重试,并提供 request_id 联系平台 |
ℹ️
统一判定范式:if (httpCode === 200 && body.code === 0) 才算成功;仅判断 HTTP 状态码会把业务失败误判为成功。
限流与配额
限流按应用(app_key)维度分桶,共三层:应用级每秒 → 端点级每秒 → 端点级/应用级每日累计。超限统一返回 HTTP 429。
| 维度 | 计数粒度 | 说明 |
| 应用级 · 每秒 | 整个应用所有端点共享 | 阈值取应用配置 per_second_limit;未配置(0)时不启用该维度 |
| 端点级 · 每秒 | 按域 + 端点独立计数 | 阈值见下表,应用级配置可覆盖平台模板值 |
| 端点级 · 每日 | 按域 + 端点独立累计 | 自然日(Asia/Shanghai)零时重置 |
| 应用级 · 每日 | 整个应用所有端点共享 | 阈值取应用配置 daily_limit;未配置(0)时不启用该维度 |
端点级默认配额(次/秒 · 次/天)
| 端点 | 每秒 | 每日 |
express/price · express/bill/query | 100 | 10,000 |
express/order/query · express/trace/query | 200 | 20,000 |
express/order/create · order/cancel · order/payment-confirm | 30 | 3,000 |
car|pet/category/list · car|pet/price/query | 100 | 10,000 |
car|pet/order/query · car|pet/track/query | 200 | 20,000 |
car|pet/order/create · order/pay · order/cancel · fee/pay | 30 | 3,000 |
car|pet/fee/push · car|pet/merchant/balance | 50 | 5,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 白名单拦截(见下) | 生产环境建议显式配置出口 IP |
| 回调安全 | 推送请求携带签名头,支持事件级开关 | 必须验签后再执行业务,并做 event_id 幂等 |
IP 白名单规则
| 配置值 | 行为 |
留空 / [] / null / - | 不限制来源 IP(全部放行) |
* | 不限制来源 IP(全部放行) |
| 一个或多个 IP | 仅放行列出的 IP;分隔符支持逗号、空格、分号、换行 |
⚠️
白名单为「精确 IP 全等匹配」,不支持 CIDR 网段/通配符(如 203.0.113.0/24 或 203.0.113.* 均无效)。若你的出口 IP 为动态地址,请使用固定出口 NAT 或暂不配置白名单;配置错误会导致所有请求返回 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 重试,幂等保护不会重复下单 |
| 200 | code=0 | — | 成功,无需重试 |
| 200 | code=422/1004/1005 | 不可 | 入参或数据问题,修正后再调用 |
| 200 | code=2001 余额不足 | 不可 | 先充值,再原样重试 |
| 200 | code=2003 报价失效 | 需换凭证 | 重新查价获取新 quote_id 后下单 |
| 200 | code=1008 无路线价 | 不可 | 联系运营配置价格 |
| 200 | code=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)请务必携带幂等键或先查询状态,避免重复提交。
沙箱联调
沙箱应用(environment=sandbox)可跑通完整业务链路,不产生真实资金变动、不触发真实派单,是上线前必做的验证环节。
| 项目 | 说明 |
| 创建方式 | 在开发者中心申请沙箱应用(应用标识与商户前缀为 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-Timestamp | Unix 秒级时间戳,偏差 ≤ 300 秒 |
X-Nonce | 随机串,长度 ≤ 64(防重放,同一应用下 300 秒内不可重复) |
X-Signature | HMAC-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
<?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
import hmac, hashlib, json, time, secrets
body = {"merchant_order_no": "YT20260914000001", "channel_code": "100057", "weight": 1.5}
body_json = json.dumps(body, ensure_ascii=False, separators=(",", ":"), sort_keys=True)
timestamp = int(time.time())
nonce = secrets.token_hex(8) # 随机串,长度 ≤ 64
sign_str = f"{app_key}{timestamp}{nonce}{body_json}"
sign = hmac.new(app_secret.encode(), sign_str.encode(), hashlib.sha256).hexdigest().upper()
# headers = {"X-App-Key": app_key, "X-Timestamp": str(timestamp), "X-Nonce": nonce, "X-Signature": sign}
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(appSecret.getBytes(UTF_8), "HmacSHA256"));
// signStr = appKey + timestamp + nonce + bodyJson(UTF-8,不转义中文与斜杠)
String signature = Hex.encodeHexString(mac.doFinal(signStr.getBytes(UTF_8))).toUpperCase();
⚠️
防重放:同一应用下 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 取 {},不要传空字符串 |
验签失败排查(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,或清空白名单 |
| 请求体不是合法的 JSON | body 非法 JSON、空 body、以表单方式提交 | 以 application/json 提交合法 JSON |
| 签名校验失败 | canonical 与平台不一致:键未排序、JSON 含空格、中文被转义、签名串顺序错误 | 本地打印 canonical 与 body 逐字符比对(见上方示例代码) |
| 重复请求(Nonce 已被使用) | 重试时复用了同一个 nonce | 每次请求生成全新随机 nonce |
错误码与排障
响应统一为 {code, message, request_id, data}:code=0 为成功,其余为失败。请以 code 判断业务结果,并同时参考 HTTP 状态码。
| HTTP | code | message | 说明 |
| 200 | 0 | success | 业务成功(data 为业务数据) |
| 200 | 422 | 参数验证失败 | 入参校验失败,data.errors 返回字段级明细 |
| 200 | 404 | 订单不存在或无权访问 / 渠道编码不存在 | 订单不属于当前应用;或下单 channel_code 与平台渠道不匹配 |
| 200 | 1004 · 1005 · 1008 · 2001 · 2002 · 2003 | 业务错误码(中文) | 运车 / 运宠域业务错误码,明细见「汽车托运 → 错误码」 |
| 200 | 2600000(或渠道 7 位码) | 业务异常文案 | 业务异常兜底码;报文内含 7 位数字错误码时原样透出 |
| 401 | — | 缺少认证参数(X-App-Key / X-Nonce / X-Signature)· X-Nonce 长度超过 64 位 · 时间戳无效或已过期 · AppKey 不存在 · 应用已被禁用 · IP 不在白名单内 · 请求体不是合法的 JSON · 签名校验失败 · 重复请求(Nonce 已被使用) | 鉴权失败:HTTP 401 专属场景,逐条排查见「签名算法 → 验签失败排查」 |
| 429 | 429 | 超过每秒调用限制 / 超过接口调用限制 / 超过接口每日调用限制 / 超过每日调用限制 | 触发应用级或端点级配额,退避后重试,见「限流与配额」 |
| 500 | 500 | 服务器内部错误,请稍后再试 | 系统级异常(生产环境统一文案),请联系平台并提供 request_id |
错误码分段
| 区段 | 含义 | 典型 code |
0 | 成功 | — |
4xx | 鉴权 / 参数 / 限流 | 401 鉴权失败 · 404 资源不存在或无权访问 · 422 参数或状态校验失败 · 429 限流 |
1000–1099 | 参数与数据校验 | 1004 参数非法 · 1005 类目 / 订单不存在 · 1008 未配置价格 |
2000–2099 | 资金与业务状态 | 2001 余额不足 · 2002 状态不允许 · 2003 凭证失效 / 重复操作 |
5xx · 2600000 | 系统与业务异常兜底 | 500 系统异常 · 2600000 业务异常兜底 |
排障路径
① 记录 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),平台可据此快速定位完整链路。
核心端点
三大业务域(国内快递 / 汽车托运 / 宠物托运)共用一套鉴权与响应结构。以国内快递为例:
| 端点 | 说明 |
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": "SFSY-KD-01-AAAA", "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": "YTOD-KD-01-AAAA", "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
}
]
}
}
支付确认发货(防亏损锁)
🔒
月结渠道实际重量超重产生补差 → 商户补足差价后,平台才通知渠道放行发货;否则货发走、差价未收 = 平台亏损。现付/到付渠道由快递公司向收件人/寄件人收款,平台赚返佣,不产生扣款、无需本接口。
资金闭环:bill.updated(计费定案)→ 平台按商户成本价生成补差单并推送 fee.supplement → 商户补款 → 平台推送 fee.paid → 商户调用 /openapi/v2/express/order/payment-confirm 放行发货。
回调机制与验签
平台在订单状态变更、轨迹更新、计费定案、费用产生等节点,主动向应用配置的回调地址(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-Signature | HMAC-SHA256 大写签名,算法与请求签名完全一致(见下方验签) |
X-Request-Id | 等于本次事件的 event_id,用于全链路追踪与日志关联 |
⚠️
回调地址必须为 HTTPS 且公网可达;请勿使用自签证书(平台会校验服务端证书),也勿把回调地址指向需要登录态或加白名单以外的内网地址。
事件清单
| event | 适用域 | 触发时机 |
order.status_changed | 全部 | 订单状态变更(下单、支付、取件、运输、签收等) |
order.cancel_requested | 全部 | 已支付在途订单发起取消申请(待平台审批) |
order.cancelled | 全部 | 订单取消完成(含退款结果) |
track.updated | 快递 | 物流轨迹更新 |
bill.updated | 快递 | 计费定案(实际费用出账) |
price.diff | 快递 | 产生差价(超重补收 / 超轻退还) |
fee.supplement | 全部 | 产生补差单 / 其他费用(待商户支付) |
fee.paid | 全部 | 补差或费用支付完成 |
报文结构
事件报文(示例)
{
"event_id": "b3f1c2d4-5e6a-4b7c-8d9e-0f1a2b3c4d5e",
"event": "order.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 内追加业务字段(如 fee.paid 含 pay_amount / remaining_amount / balance_after);报文自动携带 merchant_order_no 与 event_time。各域事件明细见「国内快递 → 回调推送」与「汽车托运 → 回调事件」。
回调验签(必做)
验签算法与请求签名完全一致:使用该应用的 app_secret,对 回调 body 的 JSON 对象 重算 HMAC-SHA256。
| 步骤 | 要求 |
| ① 取原始 body | 读取回调请求的原始 JSON body 并 json_decode 为数组(不要直接对原始字符串签名) |
| ② 递归键排序 | 对解析后的数组做递归升序排序(字符串序 ksort),与平台签名前的处理一致 |
| ③ 构造 canonical | X-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 分派;乱序到达 | 以 order.status_changed 的 status 为最终态,必要时调用订单查询接口兜底校准 |
在线调试工具
填写应用凭据与业务参数,纯前端实时生成签名(Web Crypto API,密钥不出浏览器、不上传服务器)。
🔒
签名在你的浏览器本地计算,App Secret 不会被发送或存储。将生成的请求发往 https://api.yuntu-wl.com/openapi/v2/... 即为真实调用;生产环境请先在沙箱验证。
帮助中心
接入常见问题速查 —— 点击问题展开答案,或输入关键词搜索。
更新日志
2026-09-14
调用基址唯一化(当前版本)开放平台对外基址收敛为唯一入口 https://api.yuntu-wl.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 种)
| status | status_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 种)
| order_status | order_status_text | 说明 |
negotiating | 待议价 | 订单待平台议价 |
waiting_pay | 待支付 | 下单成功,等待余额支付 |
waiting_pickup | 待取件 | 已支付,等待上门取件 |
picking_up | 取件中 | 取件进行中 |
picked_up | 已取件 | 已完成取件 |
in_transit | 运输中 | 在途运输 |
arrived | 已到达 | 已到达目的城市 |
delivering | 配送中 | 派送中 |
completed | 已完成 | 已签收 / 已交付 |
partial_pay | 部分已付 | 发生部分支付(费用支付支持部分付款) |
pending_cancel | 待取消 | 取消申请待平台审批;对外回显申请前原状态并追加 cancel_apply_status=pending_approval |
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 路线价缺失 | 该城市对未维护价格 → 提供起止城市与车型类目给运营配价 |
| 名称正确但仍未命中 | 可能使用了俗称(如「深圳」写作「鹏城」)或区县错配 → 改为标准行政区全称 |
| 运宠重量段不匹配 | 宠物按公斤段计价,重量需落在平台维护的公斤段区间内,否则报「未找到价格」 |
上线自检清单
正式切换生产前,请逐项确认。任一项未通过都可能造成资金损失或订单状态不一致。
接入与鉴权
- 密钥隔离:生产使用独立应用的
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 小时无异常后再全量放开。
国内快递接口
查价、下单、订单查询、取消、支付确认发货、轨迹查询、计费查询共 7 个端点,配套全量回调推送。统一鉴权(HMAC-SHA256)、统一响应结构、渠道报价脱敏输出(仅返回平台标准信息)。
ℹ️
签名鉴权、限流配额、幂等重试、回调验签、错误码与排障等
三大业务域通用规则见左侧「
接入指引」;本域仅描述快递专属的端点契约与业务规则。
📦 国内快递 · OpenAPI v2更新时间:2026-09-14 11:30
| 项目 | 说明 |
| 接口基址 | https://api.yuntu-wl.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)
sign_demoPHP · Python · Java
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 规则。
统一响应结构
| 字段 | 类型 | 说明 |
code | Integer | 成功固定 0;失败为业务错误码 |
message | String | 成功默认 success;失败为错误文案 |
request_id | String | 请求追踪号(排障请提供) |
data | Object / 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 已被使用) |
业务错误码
| code | message | 说明 |
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 开头,不产生真实资金与真实派单。
查价
POST/openapi/v2/express/price复制
按寄收地址、重量与业务维度返回可用渠道报价。报价为平台标准输出(仅含平台维护的渠道 / 公司 / 产品信息,不含任何外部平台信息与内部成本),返回的 channel_code 用于指定渠道下单。
| 参数名 | 类型 | 必填 | 说明 |
from_province | String | 是 | 寄件省 |
from_city | String | 是 | 寄件市 |
from_district | String | 否 | 寄件区/县 |
from_address | String | 是 | 寄件详细地址(不含省市区) |
from_name / from_phone | String | 否 | 寄件人姓名 / 电话 |
to_province | String | 是 | 收件省 |
to_city | String | 是 | 收件市 |
to_district | String | 否 | 收件区/县 |
to_address | String | 是 | 收件详细地址(不含省市区) |
to_name / to_phone | String | 否 | 收件人姓名 / 电话 |
goods_type | String | 是 | 物品类型,如 文件 / 服装 / 日用品 |
weight | Decimal | 是 | 重量(kg),须 > 0.01 |
insurance_value | Decimal | 否 | 物品价值(保价金额,元);传了才计保价费 |
biz_type | String | 否 | 业务类型:express 快递 / freight 快运 / cold_chain 冷链,默认 express(机动车托运请走运车域 /car/*,宠物托运请走运宠域 /pet/*) |
settlement_mode | String | 否 | 结算模式:online 线上月结 / offline 现付·到付,默认 online |
shipping_scenario | String | 否 | 寄件场景:standard 标准 / merchant_fixed 商家固定 / dewu_fixed 平台专线 / international 国际,默认 standard |
payment_type | String | 否 | 支付方式:MONTH 月结 / PRESENT 现付 / REACH 到付(传了将精准过滤对应渠道) |
channel_ids | Array | 否 | 指定渠道 ID 列表(仅查这些渠道) |
响应参数
| 字段 | 类型 | 说明 |
data.total | Integer | 可用渠道数 |
data.sandbox | Boolean | 是否沙箱应用(沙箱报价由平台合成,不触真实链路) |
data.quotes | Array | 渠道报价列表 |
| quotes[] 渠道报价 |
quote_no | String | 报价单号 |
channel_id / channel_code | Integer / String | 渠道 ID / 平台渠道唯一编码(下单使用 channel_code) |
platform_company_code / platform_company_name | String | 平台标准快递公司编码 / 名称 |
platform_product_code / platform_product_name | String | 平台标准产品编码 / 名称 |
platform_channel_code / platform_channel_name | String | 平台渠道编码 / 名称 |
biz_type / biz_type_label | String | 业务类型及标识(express/freight/…) |
settlement_mode / settlement_mode_label | String | 结算模式(monthly 月结 / offline 现付到付) |
shipping_scenario | String | 寄件场景 |
payment_type / payment_type_label | String | 支付方式(monthly/cash/collect) |
supported_pay_types / _label | Array | 该渠道支持的支付方式(全列出) |
supports_insurance / supports_cod / supports_pickup / supports_sign_return | Boolean | 渠道能力:保价 / 代收货款 / 上门揽收 / 签收回单 |
insurance_max_amount / insurance_min / insurance_rate | Decimal | 保价上限 / 保价最低费 / 保价费率 |
goods_value / insurance_fee | Decimal | 物品价值(回显)/ 保价费(已含在总费用中) |
insurance_tip | String | 平台保价提示(平台自建文案,含保额超限提醒) |
visibility / is_active / remark | String / Boolean / String | 渠道可见性 / 是否启用 / 渠道备注 |
estimated_days / delivery_type | Integer / String | 预计时效(天)/ 派送类型 |
freight | Decimal | 纯运费(商户成本价,不含保价费) |
other_fee / total_fee / original_price | Decimal | 其他费用 / 总费用(运费+保价+其他)/ 门市参考原价 |
first_weight / first_weight_price / additional_weight / additional_weight_price | Decimal | 首重 / 首重价 / 续重 / 续重价(商户成本价) |
weight / volume_weight | Decimal | 实重 / 抛重 |
min_charge / max_weight | Decimal | 最低一票价 / 渠道限重 |
light_goods / calc_fee_type | Decimal / String | 抛比系数(如 6000/8000)/ 计费方式 |
supports_payment_confirm | Boolean | 渠道是否支持支付确认发货(月结超重补差放行) |
📐
金额口径: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": "SFSY-KD-01-AAAA", "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": "YTOD-KD-01-AAAA", "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
}
]
}
}
下单
POST/openapi/v2/express/order/create复制
以 merchant_order_no 为幂等键创建订单;平台重新计价并锁定渠道报价后提交,成功返回订单摘要(含平台订单号、运单号、费用快照)。
| 参数名 | 类型 | 必填 | 说明 |
merchant_order_no | String | 是 | 商家订单号(≤64 位,幂等键:同一商户重复提交返回原订单) |
channel_code | String | 是 | 渠道锁定:平台渠道唯一编码(取自「查价」返回的 channel_code) |
sender_name / sender_phone | String | 是 | 寄件人姓名 / 电话 |
sender_province / sender_city | String | 是 | 寄件省 / 市 |
sender_district | String | 否 | 寄件区/县 |
sender_address | String | 是 | 寄件详细地址(不含省市区) |
receiver_name / receiver_phone | String | 是 | 收件人姓名 / 电话 |
receiver_province / receiver_city | String | 是 | 收件省 / 市 |
receiver_district | String | 否 | 收件区/县 |
receiver_address | String | 是 | 收件详细地址(不含省市区) |
goods_name | String | 是 | 物品名称 |
goods_type | String | 否 | 物品类型,默认 普通货物 |
weight | Decimal | 是 | 重量(kg),须 > 0.01 |
quantity | Integer | 否 | 件数,默认 1 |
volume / length / width / height | Decimal | 否 | 体积(m³)/ 长宽高(cm) |
insurance_value | Decimal | 否 | 物品价值(保价金额,元),传了才计保价费 |
packaging | String | 否 | 包装要求 |
delivery_type | String | 否 | 派送方式要求 |
biz_type | String | 否 | 业务类型(同「查价」,默认 express) |
settlement_mode | String | 否 | online / offline,默认 online |
shipping_scenario | String | 否 | standard / merchant_fixed / dewu_fixed / international |
payment_type | String | 否 | MONTH 月结 / PRESENT 现付 / REACH 到付(须与查价所选一致) |
pickup_start_time / pickup_end_time | String | 否 | 预约取件时间窗,格式 Y-m-d H:i:s |
pay_confirm | String | 否 | Y 需要支付确认(月结 + 渠道支持时生效)/ N 默认 |
remark | String | 否 | 商户备注(≤500) |
响应参数(订单摘要)
| 字段 | 类型 | 说明 |
order_no | String | 平台订单号 |
merchant_order_no | String | 商家订单号(回显) |
waybill_no | String | 运单号(可能为空,由回调携带) |
sandbox | Boolean | 沙箱标记(沙箱运单号以 SBX 开头) |
status / status_text | String | 订单状态与中文描述(见附录 3) |
biz_type / payment_type / settlement_mode | String | 业务类型 / 支付方式 / 结算模式(原样回显) |
channel | Object | channel_id / channel_code / company_code / company_name(平台标准公司) |
sender / receiver | Object | name / phone(已脱敏)/ city / district / address |
goods | Object | name / type / weight / volume / quantity |
fees | Object | quote_total_fee 预估总费用 / actual_total_fee 实际总费用 / difference_amount 差价 / difference_status 差价状态 / merchant_prepaid / merchant_actual |
courier | Object | name / phone(脱敏)取件员信息 |
times | Object | created_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": ""
}
}
}
支付确认发货
POST/openapi/v2/express/order/payment-confirm复制
月结超重补差场景:实际计费高于预估产生差价,商户补足差价后调用本接口,平台通知渠道放行发货(防亏损锁:不确认则货不发)。
| 参数名 | 类型 | 必填 | 说明 |
order_no | String | 3 选 1 | 平台订单号 |
merchant_order_no | String | 3 选 1 | 商家订单号 |
waybill_no | String | 3 选 1 | 运单号 |
业务规则
| 场景 | 处理 |
现付 / 到付渠道(payment_type 为 PRESENT/REACH 或 settlement_mode=offline) | 幂等成功,返回「现付/到付渠道无需支付确认」(快递公司向收件人收款,平台不承担差价风险) |
月结渠道 + supports_payment_confirm=false | 返回 422「该渠道不支持支付确认发货」 |
订单无差价(difference_amount=0) | 幂等成功,返回「订单无补差价,无需支付确认」 |
| 月结 + 渠道支持 + 存在差价 | 调用渠道支付确认,成功后订单状态更新为 pending_pickup(待揽收·已确认补差),并推送 order.status_changed |
| 订单已取消 / 已退款 / 已完成 | 返回 422「当前状态[xx]不可进行支付确认」 |
响应参数
| 字段 | 类型 | 说明 |
order_no / waybill_no | String | 平台订单号 / 运单号 |
status / status_text | String | 确认后状态(如 pending_pickup / 待揽收(已确认补差)) |
confirmed | Boolean | 是否确认成功 |
sandbox | Boolean | 沙箱标记 |
request_id | String | 渠道请求追踪号 |
💡
查价与下单返回的 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
}
}
订单查询
POST/openapi/v2/express/order/query复制
按 order_no / merchant_order_no / waybill_no 三选一查询自有订单,返回完整订单摘要(状态、渠道、费用、寄收信息、时间线)。建议作为回调的兜底对账手段。
| 参数名 | 类型 | 必填 | 说明 |
order_no | String | 3 选 1 | 平台订单号 |
merchant_order_no | String | 3 选 1 | 商家订单号 |
waybill_no | String | 3 选 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": ""
}
}
}
取消订单
POST/openapi/v2/express/order/cancel复制
取消自有订单:平台先向渠道发起取消(若已生成渠道运单号),成功后订单状态更新为 cancelled(已取消)并记录取消原因。
| 参数名 | 类型 | 必填 | 说明 |
order_no | String | 3 选 1 | 平台订单号 |
merchant_order_no | String | 3 选 1 | 商家订单号 |
waybill_no | String | 3 选 1 | 运单号 |
reason | String | 否 | 取消原因(≤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": "客户临时取消寄件" }
}
}
轨迹查询
POST/openapi/v2/express/trace/query复制
查询自有订单的物流轨迹;sync=true 时平台先主动向渠道拉取最新轨迹再返回(适合要求实时性的场景,未开启则返回平台已同步的轨迹)。
| 参数名 | 类型 | 必填 | 说明 |
order_no | String | 3 选 1 | 平台订单号 |
merchant_order_no | String | 3 选 1 | 商家订单号 |
waybill_no | String | 3 选 1 | 运单号 |
sync | Boolean | 否 | 是否主动同步最新轨迹,默认 false |
响应参数
| 字段 | 类型 | 说明 |
order_no / waybill_no | String | 平台订单号 / 运单号 |
status | String | 订单状态(平台状态字典,见附录 3) |
sync | Object / null | 本次主动同步结果;sync=false 时为 null。含 success 同步是否成功 / new_traces 新增节点数 / status 渠道状态 / request_id 渠道追踪号;同步失败时仅含 success:false 与 message(不影响本接口正常返回,此时 traces 为平台已落库轨迹) |
total | Integer | 轨迹条数 |
traces | Array | 轨迹节点,按时间正序 |
traces[].trace_time | String | 节点时间 Y-m-d H:i:s |
traces[].location | String | 节点位置(网点/中转场) |
traces[].description | String | 轨迹描述 |
traces[].status | String | 节点状态 |
请求示例
{ "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": "运输中" }
]
}
}
计费查询
POST/openapi/v2/express/bill/query复制
返回订单计费三层快照:预估费用(下单报价)、实际费用(渠道定案)、差价(补收/退还),以及实重/计费重与商户三层明细,用于对账与差价确认。
| 参数名 | 类型 | 必填 | 说明 |
order_no | String | 3 选 1 | 平台订单号 |
merchant_order_no | String | 3 选 1 | 商家订单号 |
waybill_no | String | 3 选 1 | 运单号 |
响应参数
| 字段 | 类型 | 说明 |
order_no / waybill_no / status | String | 订单号 / 运单号 / 订单状态 |
billed | Boolean | 是否已出账(实际总费用 > 0) |
estimated | Object | 预估:freight_fee 运费 / insurance_fee 保价费 / other_fee 其他费 / total_fee 合计 |
actual | Object | 实际:字段同上(unbilled 时 total_fee 为 null) |
difference.amount | Decimal | 差价金额(正数补收 / 负数退还) |
difference.status | String | 差价状态:none 无差价 / supplement 待补差 / 其他业务态 |
weight.actual_weight / weight.charge_weight | Decimal | 实际重量 / 计费重量(kg) |
merchant | Object | 商户层明细:prepaid_fee 预付 / actual_fee 实际 / difference 差价 / freight_fee / insurance_fee / other_fee |
user | Object | 用户层明细(结构同 merchant,脱敏输出) |
🔒
差价闭环:difference.status=supplement 时平台推送 fee.supplement,商户补款后平台推送 fee.paid,再调用「支付确认发货」放行(月结渠道)。
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 }
}
}
回调推送
平台在应用配置的 Webhook 地址上以 POST application/json 推送业务事件,出站请求同样携带签名头,接收方可用相同规则验签。
推送机制
| 项目 | 说明 |
| 请求方式 | 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 时,事件直接标记死信(不推送) |
| 幂等 | payload 含 event_id(UUID),同一下发事件重复推送请按 event_id 去重 |
| 日志状态 | queued 排队 / success 成功 / failed 待重试 / dead 死信 |
推送报文结构
| 字段 | 类型 | 说明 |
event_id | String | 事件 ID(UUID,幂等键,同时作为 X-Request-Id) |
event | String | 事件名(见下表) |
timestamp | Integer | 推送时间(Unix 秒) |
order_no | String | 平台订单号 |
waybill_no | String | 运单号(未生成时为空串) |
status | String | 推送时的订单状态(平台状态字典) |
data | Object | 事件业务数据(字段随事件类型不同,以后台推送日志中的实际报文为准) |
事件类型
| event | 触发时机 |
order.status_changed | 订单状态变更(下单成功、支付确认放行、取件、运输、签收等) |
track.updated | 物流轨迹更新 |
bill.updated | 计费定案(实际费用出账) |
price.diff | 产生差价(超重补收 / 超轻退还) |
fee.supplement | 产生补差单(待商户补款) |
fee.paid | 补差已支付完成 |
order.cancel_requested | 商户/平台发起取消申请 |
order.cancelled | 订单取消完成 |
order.status_changed 推送示例
{
"event_id": "5f2c9a1e-77d0-4a9c-8f31-9b2e5c7a0112",
"event": "order.status_changed",
"timestamp": 1757825600,
"order_no": "YT2609140000123456",
"waybill_no": "SF1234567890123",
"status": "submitted",
"data": {
"order_no": "YT2609140000123456",
"waybill_no": "SF1234567890123",
"status": "submitted",
"status_text": "取件中",
"timestamp": 1757825600
}
}
接收方应答(HTTP 2xx 即成功)
// 推荐返回
{ "success": true }
// 注意:平台仅校验 HTTP 状态码(2xx),非 2xx 或超时会触发重试直至死信
附录
附录 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)
| status | status_text | 说明 |
pending | 待支付 | 订单已创建,等待支付/确认 |
quoted | 已报价 | 已完成报价 |
paid | 已支付 | 已完成支付 |
submitted | 取件中 | 已提交渠道,等待上门取件 |
accepted | 已取件 | 渠道已揽收 |
transit | 运输中 | 在途 / 转运 |
delivered / signed | 已完成 | 已派送 / 已签收 |
cancelled / refunding / refunded | 已取消 | 已取消(含退款中 / 已退款) |
ℹ️
请以 status 做业务判断(status_text 仅用于展示,中文文案可能调整)。
附录 4 · 业务维度字典
| 字段 | 取值 |
biz_type | express 快递 / freight 快运 / cold_chain 冷链 机动车托运(汽车/电动车/摩托车)走运车域 /openapi/v2/car/*;宠物托运走运宠域 /openapi/v2/pet/*,均不通过快递域承载 |
settlement_mode | online 线上月结 / offline 现付·到付 |
shipping_scenario | standard 标准 / merchant_fixed 商家固定 / dewu_fixed 平台专线 / international 国际 |
payment_type | MONTH 月结(label monthly)/ PRESENT 现付(label cash)/ REACH 到付(label collect) |
difference_status | none 无差价 / supplement 待补差(以实际返回为准) |
附录 5 · 计费与精度口径
| 项目 | 口径 |
| 金额精度 | 元,保留 两位小数(freight / insurance_fee / other_fee / total_fee) |
| 重量精度 | 千克(kg);weight 为实重、volume_weight 为抛重、charge_weight 为计费重 |
| 计费重量进位 | 由渠道按公斤段规则进位确定,以「计费查询」返回的 charge_weight 为准 |
| 三层快照 | estimated(下单报价)/ actual(渠道定案)/ difference(差价),见「计费查询」 |
| 保价费 | 由渠道按 insurance_rate / 保额区间计取,返回 insurance_fee(已含在总费用) |
| 平台加价 | 平台对成本价统一加价后输出为商户成本价,报价字段即商户可下单价格 |
注意事项(必读)
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_id | Integer | 否 | 按一级类目过滤(别名 cate_id) |
cate_id | Integer | 否 | category_id 的兼容别名 |
| 响应字段 | 类型 | 说明 |
categories[] | Array | category_id / category_name / category_code / icon / sort / types[] |
types[] | Array | type_id / type_name / category_id / base_price / fixed_yoke_fee(木架费,商户免木架时为 0)/ fixed_delivery_fee(送货费)/ description / sort |
total | Integer | 类目总数 |
查价
POST/openapi/v2/car/price/query复制
按类目 + 城市路线返回报价与折扣明细,返回 quote_id(有效期 300 秒)供下单锁价;折扣仅作用于基础运费,木架费与送货费不打折。
| 参数名 | 类型 | 必填 | 说明 |
cate_id / category_id | Integer | 是 | 一级类目 ID(二者其一) |
typeid / type_id | Integer | 是 | 车型/货物类型 ID(二者其一) |
packing_method | Integer | 否 | 是否木架包装:1 是 / 0 否(别名 wood_frame_flag) |
delivery_type | Integer | 否 | 1 送货上门(默认)/ 2 网点自提 |
from_name / from_phone | String | 是 | 寄件人姓名 / 电话 |
from_province / from_city | String | 是 | 寄件省 / 市(城市名自动标准化) |
from_district / from_address | String | 否 | 寄件区县 / 详细地址 |
to_name / to_phone | String | 是 | 收件人姓名 / 电话 |
to_province / to_city | String | 是 | 收件省 / 市 |
to_district / to_address | String | 否 | 收件区县 / 详细地址 |
has_other_items | Integer | 否 | 是否随车物品:1 是 / 0 否 |
other_items_desc | String | 否 | 随车物品说明 |
appointment_time | String | 否 | 预约时间 |
| 响应字段 | 类型 | 说明 |
quote_id / expire_time / query_time | String | 报价单号(Q+YmdHis+8 位 hex)/ 失效时间 / 查询时间 |
category | Object | category_id / category_name / type_id / type_name |
route | Object | 寄收省市区 + transit_time(预计运输时长) |
price | Object | base_price 折后价 / original_price 牌价 / discount_rate / discount_text / discount_amount / wood_frame_fee / delivery_fee / total_price / original_total |
price_detail | Object | base_price_source / discount_source / discount_note / merchant_level_id / channel_type_id |
options | Object | 可选项回显: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_no | String | 否 | 商家订单号(≤64,幂等键;重复提交返回原单 + idempotent:true) |
quote_id | String | 否 | 查价返回的报价单号(锁价);失效/占用返回 2003 |
| 查价全部入参 | — | — | cate_id/typeid/packing_method/delivery_type/from_*/to_*/has_other_items/other_items_desc/appointment_time |
from_address / to_address | String | 是 | 详细地址(下单必填) |
weight | Decimal | 否 | 车辆重量(kg,可选) |
item_count | Integer | 否 | 车辆数量,默认 1 |
item_remark / remark | String | 否 | 车辆备注 / 订单备注(≤500) |
| 响应字段 | 类型 | 说明 |
order_no / merchant_order_no | String | 平台订单号 / 商家订单号 |
order_status / payment_status | String | 下单后为 waiting_pay / unpaid |
paid_amount / need_pay_amount | Decimal | 已付(0.00)/ 应付金额 |
is_test | Boolean | 是否测试单(应用开启 debug_mode 且在有效期内) |
price | Object | base_price / original_price / discount_rate / packing_fee / delivery_fee / total_price |
category | Object | 类目与车型回显 |
appointment_time / created_at | String | 预约时间 / 创建时间 |
💡
下单成功即推送 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_no | String | 2 选 1 | 平台订单号 / 商家订单号 |
pay_amount | Decimal | 否 | 支付金额,默认全额;与应付差额 >0.01 返回 1004 |
| 响应字段 | 类型 | 说明 |
order_no / transport_no | String | 订单号 / 运单号(YTWL 前缀) |
order_status / payment_status / payment_method | String | paid / paid / balance |
paid_amount / payment_time / balance_after | Decimal / 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_no | String | 否 | 任一存在 → 单笔查询 |
order_status | String | 否 | 状态过滤(兼容旧码归一:picking→picking_up、picked→picked_up、transporting→in_transit、pending→waiting_pay) |
start_date / end_date | String | 否 | 创建日期范围 Y-m-d(含首尾日) |
page / page_size | Integer | 否 | 页码(默认 1)/ 每页(默认 20,最大 100) |
| 响应字段 | 类型 | 说明 |
| 单笔:直接返回订单对象(字段见下) |
列表:{ list[], total, page, page_size, total_pages } |
order_no / merchant_order_no / transport_no | String | 订单号 / 商家单号 / 运单号 |
order_status / order_status_text | String | 状态码 / 中文(见 状态字典) |
payment_status / payment_status_text / payment_type / payment_time | String | unpaid/partial/paid 及支付方式与时间 |
sender / receiver | Object | {name,phone,province,city,district,address} |
item | Object | category_code / category_name / count / weight / remark |
fee | Object | base_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}(其他费用明细) |
courier | Object | agent_name / agent_phone(已脱敏) |
logistics.current_progress | String/Number | 当前物流进度 |
times | Object | created_at / updated_at / payment_at / appointment_time |
cancel_apply_status | String | 取消审批中时返回 pending_approval |
取消订单
POST/openapi/v2/car/order/cancel复制
| 参数名 | 类型 | 必填 | 说明 |
order_no / merchant_order_no | String | 2 选 1 | 平台订单号 / 商家订单号 |
cancel_reason | String | 否 | 取消原因(≤200) |
empty_run_fee | Decimal | 否 | 空跑费(已支付场景可扣,不得超过已支付金额,否则 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_no | String | 3 选 1 | 平台订单号 |
transport_no | String | 3 选 1 | 运单号 |
merchant_order_no | String | 3 选 1 | 商家订单号 |
| 响应字段 | 类型 | 说明 |
order_no / transport_no / order_status / status_text | String | 订单标识与状态 |
current_progress | Decimal | 当前进度百分比(0-100) |
sender_city / receiver_city | String | 起讫城市 |
estimated_arrival_time / actual_arrival_time | String | 预计到达 / 实际到达(未到为 null) |
track_list[] | Array | {time,status,desc,city,progress}(正序) |
track_count | Integer | 轨迹条数 |
费用推送(双模式)
POST/openapi/v2/car/fee/push复制
只传 order_no → 查询其他费用明细与待付;同时传 fee_items → 推送费用并返回幂等批次号 batch_no。
| 参数名 | 类型 | 必填 | 说明 |
order_no | String | 是 | 平台订单号 |
fee_items[] | Array | 否 | 费用项:fee_type / fee_name / fee_amount(>0)/ fee_remark |
apply_remark / operator_name | String | 否 | 申请备注 / 操作人(默认「系统」) |
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_amount | Decimal | 其他费用合计 / 订单实付总额 / 待付 / 已付 |
fee_count / fee_summary / fee_list[] | Integer / Object / Array | 条数 / 按类型汇总 / 明细列表 |
| 推送模式 |
batch_no | String | 幂等批次号(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_no | String | 2 选 1 | 平台订单号 / 商家订单号 |
pay_amount | Decimal | 是 | 支付金额(>0,不得超过待付金额) |
pay_method | String | 是 | 固定 balance(B3 仅余额) |
out_trade_no / paid_at | String | 否 | 外部交易号 / 支付时间 |
| 响应字段 | 类型 | 说明 |
order_no / pay_amount / paid_at | — | 订单号 / 本次支付 / 支付时间 |
paid_amount / remaining_amount | Decimal | 累计已付 / 剩余待付 |
payment_status | String | paid 或 partial |
balance_after / message | Decimal / 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_balance | Decimal | 余额 / 可用 / 冻结(当前为 0) |
deposit_amount | Decimal | 保证金(当前为 0) |
total_recharge / total_consume / total_refund | Decimal | 累计充值 / 消费 / 退款 |
balance_warning / is_warning | Decimal / Boolean | 预警阈值(1000.00)/ 是否低于阈值 |
last_recharge_time / last_consume_time | String | 最近充值 / 消费时间 |
状态字典(运车 / 运宠通用)
汽车托运与宠物托运共用同一状态字典,订单查询返回的 order_status / order_status_text 均以此为准。
| order_status | order_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_status | payment_status_text | 说明 |
unpaid | 未支付 | 尚未支付 |
partial | 部分已付 | 部分支付(费用支付支持) |
paid | 已支付 | 已结清 |
ℹ️
旧同义码(picking / picked / transporting / pending)仅用于读取历史数据时的展示归一化,平台不再新产;订单查询的 order_status 过滤参数兼容这些旧码。
错误码
| code | message(示例) | 触发条件 |
1004 | 寄件人电话格式不正确 / 收件人电话格式不正确 | 手机号不符合 ^1[3-9]\d{9}$ |
1004 | 支付金额不匹配,需支付: X,传入: Y | order/pay 金额与应付差额 >0.01 |
1004 | 空跑费不能超过已支付金额,已支付: X,空跑费: Y | order/cancel 空跑费超限 |
1004 | fee_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_id | Integer | 否 | 按一级类目过滤(别名 cate_id) |
cate_id | Integer | 否 | category_id 的兼容别名 |
species_id | Integer | 否 | 按一级品类过滤(返回该品类下的品种) |
| 响应字段 | 类型 | 说明 |
categories[] | Array | category_id / category_name / icon / intro / sort / types[] |
categories[].types[] | Array | type_id / type_name / weight_min / weight_max(重量档区间)/ weight_limit / base_price / fixed_delivery_fee(送货费)/ fixed_packaging_fee / intro / sort |
species[] | Array | species_id / species_name / icon / sort / breeds[] |
species[].breeds[] | Array | breed_id / breed_name / species_id / sort |
weight_ranges | Array | 可下单公斤段(如 1-3 / 3-10 / 10+) |
delivery_options | Array | {value,name,description}:1 送货上门 / 2 网点自提 |
cage_options | Array | {value,name,warning}:1 有笼子·航空箱 / 0 没有笼子 |
total_categories | Integer | 返回的一级类目数 |
ℹ️
类目与品种的职责区分:categories(一级 / 二级类目)是计价与下单的必填依据;species(品类 / 品种)仅用于信息展示与下单校验(不参与查价)。字典类数据平台侧有 1 小时缓存,变更后最长 1 小时生效。
查价
POST/openapi/v2/pet/price/query复制
按类目 + 品类 + 重量档 + 城市路线返回宠物托运报价(含折扣、送货费、笼子费)。本接口不返回 quote_id、不做锁价,下单时平台按同一计价服务实时重算。
| 参数名 | 类型 | 必填 | 说明 |
category_id / cate_id | Integer | 是 | 一级类目 ID(二者其一) |
type_id / typeid | Integer | 是 | 二级类目 ID(二者其一) |
species_id | Integer | 是 | 一级品类 ID(下单时校验) |
breed_id / breed_name | Integer / String | 否 | 二级品种 ID / 自定义品种名称(下单时二者至少传一个) |
weight | Decimal | 是 | 宠物重量(kg,>0),须落在该二级类目的重量档区间内 |
cage_provided | Integer | 否 | 是否自备笼子:1 有笼子 / 0 没有笼子(默认 0,为 0 时计笼子费) |
delivery_type | Integer | 否 | 1 送货上门(默认,计送货费)/ 2 网点自提(免送货费) |
from_name / from_phone | String | 是 | 寄件人姓名 / 电话 |
from_province / from_city | String | 是 | 寄件省 / 市(城市名自动标准化) |
from_district | String | 否 | 寄件区/县 |
to_name / to_phone | String | 是 | 收件人姓名 / 电话 |
to_province / to_city | String | 是 | 收件省 / 市 |
to_district | String | 否 | 收件区/县 |
| 响应字段 | 类型 | 说明 |
category | Object | category_id / category_name / type_id / type_name |
route | Object | 寄收省市区 + transit_time(预计运输时长) |
weight_info | Object | weight 本次重量 / weight_range 命中的公斤段 |
price | Object | original_price 基础运费牌价 / discount_price 折后基础运费 / discount_rate / discount_text / discount_amount / delivery_fee 送货费 / cage_fee 笼子费 / total_price 合计 / total_original 未折合计 |
price_detail | Object | 计价来源说明:base_price_source / delivery_fee_source / cage_fee_source / discount_source / discount_note |
options | Object | 可选项回显:delivery_type[] / cage_provided[]({value,name,fee|warning}) |
cage_warning | String | 未自备笼子时的提醒文案(自备时为空串) |
query_time | String | 查询时间 |
计价口径
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_no | String | 否 | 商家订单号(≤64,幂等键;重复提交返回原单 + idempotent:true) |
quote_id | String | 否 | 平台收下但不锁价,下单金额以实时重算为准 |
category_id / cate_id | Integer | 是 | 一级类目 ID(二者其一) |
type_id / typeid | Integer | 是 | 二级类目 ID(二者其一) |
species_id | Integer | 是 | 一级品类 ID |
breed_id / breed_name | Integer / String | 2 选 1 | 二级品种 ID / 自定义品种名称(至少传一个;breed_id 查不到且有 breed_name 时按自定义品种放行) |
weight | Decimal | 是 | 宠物重量(kg,>0),须落在二级类目重量档区间内 |
cage_provided | Integer | 否 | 1 有笼子 / 0 没有笼子(默认 0) |
delivery_type | Integer | 否 | 1 送货上门(默认)/ 2 网点自提 |
from_name / from_phone | String | 是 | 寄件人姓名 / 电话(手机号需符合 ^1[3-9]\d{9}$) |
from_province / from_city / from_address | String | 是 | 寄件省 / 市 / 详细地址 |
from_district | String | 否 | 寄件区/县 |
to_name / to_phone | String | 是 | 收件人姓名 / 电话 |
to_province / to_city / to_address | String | 是 | 收件省 / 市 / 详细地址 |
to_district | String | 否 | 收件区/县 |
appointment_time | String | 否 | 预约时间 |
remark | String | 否 | 订单备注(≤500) |
| 响应字段 | 类型 | 说明 |
order_no / waybill_no / merchant_order_no | String | 平台订单号(YP 前缀)/ 运单号(YPWB 前缀)/ 商家订单号 |
order_status / payment_status | String | 下单后固定 waiting_pay / unpaid |
paid_amount / need_pay_amount | Decimal | 已付(0.00)/ 应付金额 |
pet_info | Object | species_id / species_name / breed_id / breed_name / weight / weight_range / cage_provided / cage_warning |
price | Object | cost_price 折后基础运费 / original_price 牌价 / discount_rate / cage_fee / delivery_fee / total_fee |
category | Object | 类目与二级类目回显 |
delivery | Object | delivery_type / delivery_name(送货上门 / 网点自提) |
created_at | String | 创建时间 |
💡
下单成功即推送 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/pay | order_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/cancel | order_no / merchant_order_no、cancel_reason、empty_run_fee | 取消订单 |
POST /openapi/v2/pet/track/query | order_no / transport_no / merchant_order_no(3 选 1) | 轨迹查询 |
POST /openapi/v2/pet/fee/push | order_no 必填;fee_items[] / apply_remark / operator_name | 费用推送 |
POST /openapi/v2/pet/fee/pay | order_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。