513 lines
23 KiB
Markdown
513 lines
23 KiB
Markdown
# 配送对接接口规范(模拟三通一达后台 / Mock 承运方 Server)
|
||
|
||
本文档用于定义“模拟承运方后台服务(Mock Server)”的接口与行为,供平台在未接入真实承运方前完成联调与测试。
|
||
|
||
本文定位:
|
||
- 规定 Mock Server 与平台后端之间的交互(Webhook 推送 + 控制面 API)。
|
||
- 规定平台侧建议的统一事件模型(用于入库、时间线展示、监控告警)。
|
||
|
||
关联文档:
|
||
- `配送模块需求文档.md`:目标/范围/验收与必须的故障注入
|
||
- `状态映射表.md`:状态码映射建议(Mock event_code -> 平台 status_code)
|
||
- `前端字段清单.md`:安卓/Web 时间线展示字段契约
|
||
|
||
包含两类接口:
|
||
1) Mock Server -> 平台:Webhook 事件推送(模拟承运方回调)
|
||
2) 平台/测试工具 -> Mock Server:控制面 API(创建运单、追加事件、运行场景、触发推送、查询轨迹)
|
||
|
||
## 统一约定
|
||
- 时间格式:ISO 8601(示例:"2026-02-05T10:30:00+08:00")
|
||
- 所有接口请求/响应均为 JSON,Content-Type: application/json
|
||
- 写操作建议携带 `request_id` 用于幂等与排查
|
||
- 所有第三方回调应保存 `raw_payload` 用于审计
|
||
|
||
补充说明(安卓端 & Web 端使用场景):
|
||
- 本文主要规范 Mock Server 与平台后端的交互;安卓/Web 客户端不应直接调用 Mock Server。
|
||
- Web 端联调时如需浏览器直连平台接口,应由平台网关配置 CORS(仅测试环境白名单),避免将 Mock Server 暴露给公网。
|
||
|
||
## 一、目标与约束
|
||
- 目标:用可控数据模拟关键配送节点与异常场景,覆盖验签、幂等、乱序/重复、延迟等测试。
|
||
- 约束:本规范服务于测试/预发布环境,不用于生产承运方直连。
|
||
|
||
## 二、核心数据模型(建议统一存储字段)
|
||
- `carrier`:承运方标识(例如:YUNDA、YTO、KDN)
|
||
- `tracking_no`:运单号
|
||
- `event_id`:第三方事件唯一ID(用于去重)
|
||
- `event_time`:事件时间(ISO8601)
|
||
- `event_code`:第三方原始事件码(尽量不改写,用于审计与一致性对齐)
|
||
- `event_text`:第三方原始事件文案(前端时间线默认展示)
|
||
- `status_code`:平台统一状态(PENDING, IN_TRANSIT, ARRIVED_HUB, OUT_FOR_DELIVERY, DELIVERED, EXCEPTION)
|
||
- `node_name`:节点名称(中转站/网点/城市)
|
||
- `location`:节点位置描述(城市/网点地址,注意隐私)
|
||
- `description`:事件详细描述
|
||
- `evidence_urls`:证据照片/签名链接数组
|
||
- `estimated_arrival`:ETA(若承运方提供,可选)
|
||
- `raw_payload`:原始第三方 JSON(审计)
|
||
- `last_synced_at`:本地同步时间
|
||
|
||
## 三、接入模式
|
||
- 平台接收 Mock Server 的 Webhook 推送(推荐)。
|
||
- 平台亦可主动调用 Mock Server 查询轨迹(模拟轮询补偿)。
|
||
|
||
## 四、接口定义(示例)
|
||
|
||
1) Mock Server -> 平台:事件推送(Webhook)
|
||
- URL: POST /webhook/express/status
|
||
- 描述: 承运方/聚合方主动推送运单事件(单条或批量事件)。平台应校验签名并返回 HTTP 200 表示成功接收。
|
||
- HTTP 头部(建议):
|
||
- `Content-Type: application/json`
|
||
- `X-Client-Id`: 承运方或聚合方ID
|
||
- `X-Timestamp`: 推送时间戳(防重放)
|
||
- `X-Signature`: HMAC-SHA256(body + X-Timestamp) 使用双方共享 secret
|
||
- 回调示例(单事件):
|
||
{
|
||
"tracking_no":"YD123456789",
|
||
"carrier":"YUNDA",
|
||
"event_id":"e_20260205_0001",
|
||
"event_code":"ARRIVED_HUB",
|
||
"event_text":"到达北京分拨中心",
|
||
"event_time":"2026-02-05T14:32:00+08:00",
|
||
"node_name":"北京分拨中心",
|
||
"location":"北京市朝阳区XXX",
|
||
"evidence_urls":[],
|
||
"raw_payload":{/* 原始承运方 JSON */}
|
||
}
|
||
|
||
处理要求:
|
||
- 平台校验 `X-Signature` 和 `X-Timestamp`;若验签失败或时间差过大返回 4xx。若成功返回 HTTP 200。接收后异步完成映射与入库。
|
||
- 幂等:基于 `event_id` 或 `tracking_no+event_code+event_time` 去重。
|
||
|
||
2) 平台 -> Mock Server:轨迹主动拉取(模拟轮询)
|
||
- URL: GET /mock/v1/track?tracking_no={tracking_no}&carrier={carrier}
|
||
- 描述: 平台主动查询单运单轨迹,返回事件数组。
|
||
- 响应示例:
|
||
{
|
||
"tracking_no":"YD123456789",
|
||
"carrier":"YUNDA",
|
||
"events":[
|
||
{"event_id":"e1","event_code":"PICKED","event_text":"已揽收","event_time":"2026-02-04T18:00:00+08:00","node_name":"门店揽收网点","location":"北京市顺义"},
|
||
{"event_id":"e2","event_code":"ARRIVED_HUB","event_text":"到达北京分拨中心","event_time":"2026-02-05T14:32:00+08:00","node_name":"北京分拨中心","location":"北京市朝阳区"}
|
||
]
|
||
}
|
||
|
||
3) 平台:异常上报 API(用户/客服触发,平台侧,不属于 Mock Server)
|
||
- URL: POST /api/v1/delivery/express/report-exception
|
||
- 说明: 该接口为平台自身能力,Mock Server 不强制实现。
|
||
- 请求示例:
|
||
{
|
||
"tracking_no":"YD123456789",
|
||
"reported_by":"user",
|
||
"report_type":"damaged",
|
||
"description":"包裹外包装破损,有压痕",
|
||
"evidence_urls":["https://.../img1.jpg"]
|
||
}
|
||
- 平台可选地回传给真实承运方(若未来接入)并记录回传结果。
|
||
|
||
4) 平台/测试工具 -> Mock Server:控制面 API(建议实现)
|
||
|
||
4.1 配置回调目标
|
||
- URL: POST /mock/v1/config
|
||
- 描述: 设置 Mock Server 推送到平台的 Webhook 目标地址与验签参数。
|
||
- 请求示例:
|
||
{
|
||
"target_webhook_url":"https://api.yourplatform.com/webhook/express/status",
|
||
"client_id":"carrier_mock_yunda",
|
||
"secret":"shared_secret",
|
||
"default_carrier":"YUNDA"
|
||
}
|
||
|
||
4.2 创建运单
|
||
- URL: POST /mock/v1/waybills
|
||
- 描述: 创建一个 mock 运单,可由调用方指定或由服务生成。
|
||
- 请求示例:
|
||
{
|
||
"carrier":"YUNDA",
|
||
"tracking_no":"YD123456789",
|
||
"order_no":"202602050001"
|
||
}
|
||
- 响应示例:
|
||
{
|
||
"carrier":"YUNDA",
|
||
"tracking_no":"YD123456789",
|
||
"created_at":"2026-02-05T14:00:00+08:00"
|
||
}
|
||
|
||
4.3 追加事件(不推送,仅入库)
|
||
- URL: POST /mock/v1/waybills/{tracking_no}/events
|
||
- 请求示例:
|
||
{
|
||
"event_id":"e_20260205_0002",
|
||
"event_code":"ARRIVED_HUB",
|
||
"event_text":"到达北京分拨中心",
|
||
"event_time":"2026-02-05T14:32:00+08:00",
|
||
"node_name":"北京分拨中心",
|
||
"location":"北京市朝阳区",
|
||
"evidence_urls":[]
|
||
}
|
||
|
||
4.4 运行预置场景(生成一组事件并可选立即推送)
|
||
- URL: POST /mock/v1/waybills/{tracking_no}/run-scenario
|
||
- 请求示例:
|
||
{
|
||
"scenario":"standard_delivered",
|
||
"push":true,
|
||
"inject":{
|
||
"delay_ms":300,
|
||
"duplicate":0,
|
||
"out_of_order":false,
|
||
"bad_signature":false,
|
||
"timestamp_skew_seconds":0
|
||
}
|
||
}
|
||
|
||
4.5 触发推送(把该运单事件推到平台)
|
||
- URL: POST /mock/v1/waybills/{tracking_no}/push
|
||
- 请求示例:
|
||
{
|
||
"mode":"all",
|
||
"inject":{
|
||
"delay_ms":0,
|
||
"duplicate":1,
|
||
"out_of_order":true
|
||
}
|
||
}
|
||
|
||
4.6 查询运单轨迹(Mock Server 自身查询接口)
|
||
- URL: GET /mock/v1/waybills/{tracking_no}/track
|
||
- 响应示例:
|
||
{
|
||
"carrier":"YUNDA",
|
||
"tracking_no":"YD123456789",
|
||
"events":[
|
||
{"event_id":"e1","event_code":"PICKED","event_text":"已揽收","event_time":"2026-02-04T18:00:00+08:00"}
|
||
]
|
||
}
|
||
|
||
4.7 健康检查
|
||
- URL: GET /mock/v1/health
|
||
- 响应示例:
|
||
{"status":"ok"}
|
||
|
||
## 五、字段映射与状态对照(示例)
|
||
- 平台统一状态 `OUT_FOR_DELIVERY` 映射关系示例:
|
||
- 韵达:承运方 `派送中` -> 平台 `OUT_FOR_DELIVERY`
|
||
- 聚合:原始 `deliver` -> 平台 `OUT_FOR_DELIVERY`
|
||
|
||
状态一致性策略(尽量保持平台与第三方一致):
|
||
- 一致性定义:平台保存的 `event_code/event_text` 与 `raw_payload` 应与第三方可查询到的轨迹语义一致;平台对外展示的 `status_code` 必须由映射表确定性生成(同一承运方同一 `event_code` 在同一版本映射下得到同一 `status_code`)。
|
||
- 字段保真:`event_code/event_text` 仅做透传与脱敏展示,不建议“为了统一文案”而改写原文;统一展示口径使用 `status_code` 的标签/颜色/筛选实现。
|
||
- 映射表治理:映射表变更需要版本化(例如 `mapping_version`)并走发布流程;避免在生产环境频繁调整导致历史轨迹“同码不同态”。如必须调整,建议补充回放/回填策略以保证历史一致。
|
||
- 回查纠偏(可选增强):平台定期或按需对“关键单/争议单”触发第三方轨迹回查;若发现缺失事件则补采入库;若发现语义冲突,优先保留原始事件并追加“平台侧纠偏事件/备注”,避免静默覆盖造成审计对不上。
|
||
|
||
## 六、验签与安全
|
||
- 建议使用 HMAC-SHA256 签名,签名字段为 `body + X-Timestamp`,服务端使用共享 `secret` 校验。
|
||
- 防重放:校验 `X-Timestamp` 与当前时间差(例如 < 5 分钟),并保存最近 N 个 `X-Signature` 或 `event_id` 用于去重。
|
||
|
||
## 七、幂等与重试策略
|
||
- webhook:承运方可能重试多次,平台必须基于 `event_id` 或 (`tracking_no`+`event_code`+`event_time`) 去重。
|
||
- 主动调用承运方接口失败时采用指数退避重试;关键操作(打单)建议入队异步重试并人工告警。
|
||
|
||
入库层(幂等去重、乱序处理)建议:
|
||
- 幂等目标:同一条事件无论推送/重试多少次,最终数据库只保留一条(或同一条被安全更新),避免重复入库造成时间线膨胀。
|
||
- 幂等键优先级:
|
||
- 优先使用第三方提供的 `event_id`。
|
||
- 若缺少 `event_id`,使用兜底组合键:`tracking_no + event_code + event_time`(必要时可补充 `node_name/location` 以降低碰撞)。
|
||
- 数据库约束:建议在事件表上建立唯一约束(例如 `carrier + tracking_no + event_id` 或 `tracking_no + dedupe_key`),写入采用 Upsert/Insert-Ignore,应用层无需“先查再写”来保证并发安全。
|
||
- 乱序处理:允许事件乱序写入(以免晚到的历史节点被丢弃);查询展示时按 `event_time` 排序生成时间线。
|
||
- 状态不回退(平台侧可选规则):当先收到终态(如 `DELIVERED`)后又收到更早时间的在途事件时,不应将订单状态从终态回退;可采用“以最新 `event_time` 事件计算 current_status”或“按状态流转等级仅允许前进”的策略。
|
||
|
||
## 八、展示与 UI 要求(与前端对接点)
|
||
- 时间线按 `event_time` 展示,标注 `carrier` 来源与 `last_synced_at`。
|
||
- 节点可展开查看 `description`、`node_name`、`location`、`evidence_urls`(签收照片/回单)。若无证据则隐藏预览。
|
||
- 提供“查看第三方原文”链接,展示 `raw_payload`(仅客服/运维可见)。
|
||
|
||
平台对客户端返回建议(安卓/Web):
|
||
- 客户端请求应面向平台统一接口(例如:`GET /api/v1/delivery/express/track?order_no=...`),由平台返回统一的 `status_history`。
|
||
- 响应中建议包含:`carrier`、`tracking_no`、`status`、`status_history`、`last_synced_at`,以及可选的 `eta`。
|
||
- `raw_payload` 不建议下发给普通用户端;仅在 Web 客服/运维界面按权限下发并记录审计。
|
||
|
||
## 九、监控与告警
|
||
- 指标:webhook 接收成功率、平均同步时延、同步失败率、超过阈值未更新的运单数。
|
||
- 告警:承运方 5xx 增加、webhook 验签失败率异常、单运单长时间无更新。
|
||
|
||
## 十、示例 cURL(Webhook 验证场景模拟)
|
||
```
|
||
curl -X POST https://api.yourplatform.com/webhook/express/status \
|
||
-H "Content-Type: application/json" \
|
||
-H "X-Client-Id: carrier_yunda" \
|
||
-H "X-Timestamp: 2026-02-05T14:32:00+08:00" \
|
||
-H "X-Signature: <hmac-signature>" \
|
||
-d '{"tracking_no":"YD123456789","event_id":"e_20260205_0001","event_code":"ARRIVED_HUB","event_time":"2026-02-05T14:32:00+08:00","event_text":"到达北京分拨中心"}'
|
||
```
|
||
|
||
## 十一、日志与保留策略
|
||
- 建议保留 `raw_payload` 与入库审计日志至少 30 天以便纠纷处理,审计记录包括接收时间、IP、头部信息与处理结果。
|
||
|
||
## 十二、兼容与扩展建议
|
||
- 建议实现承运商 Adapter 层:承运方差异在 Adapter 层转换为统一模型,便于后续扩展新承运方或替换聚合方。
|
||
- 若需签收照片或更高粒度信息,应优先与承运方签订企业级合同或直连,并在 UI 端明确注明凭证来源。
|
||
|
||
### 十二点一、平台后端适配架构(推荐实现方式)
|
||
|
||
目标:当不同第三方(直连承运方/聚合平台)API 结构、鉴权方式、事件码不同的时候,平台侧**不修改核心业务与数据库结构**即可接入。
|
||
|
||
核心原则:
|
||
- **统一领域模型入库**:第三方差异在入库前完成映射;数据库保存统一事件字段 + `raw_payload`。
|
||
- **Adapter 可插拔**:每家第三方实现一个 Adapter(验签/解析/查询/映射),核心服务只处理统一模型。
|
||
- **接入入口两条线**:Webhook(推送)与 Poller(轮询补偿)最终都走同一条 `EventIngestService`。
|
||
|
||
模块划分(建议):
|
||
- `WebhookController`:接收回调、路由到对应 Adapter、快速返回 200(业务异步处理)。
|
||
- `CarrierAdapter`(每家一个):验签、解析、字段映射、状态映射、(可选)轨迹查询。
|
||
- `AdapterRegistry/Router`:按 `carrier` 或 `X-Client-Id` 选择 Adapter(支持灰度与多配置)。
|
||
- `EventIngestService`:幂等去重、乱序处理策略、统一入库、写审计日志。
|
||
- `TrackQueryService`:给安卓/Web 提供统一查询接口(只读),不透出第三方差异。
|
||
- `PollerJob`:定时对“长时间无更新”的运单做轮询补偿(可按承运方频率配置)。
|
||
|
||
幂等与乱序建议(平台侧):
|
||
- 幂等键优先级:`event_id`(优先) > `tracking_no + event_code + event_time`(兜底)。
|
||
- 入库:允许乱序写入;查询展示时按 `event_time` 排序。
|
||
- 兼容缺字段:缺少 `event_id` 时必须使用兜底组合键;缺少 `location/node_name` 时 UI 降级仅展示 `event_text`。
|
||
|
||
### 架构图(Mermaid)
|
||
```mermaid
|
||
flowchart LR
|
||
subgraph Clients[客户端]
|
||
A[安卓 App] -->|GET 物流时间线| PAPI[平台 API]
|
||
W[Web/H5/PC] -->|GET 物流时间线| PAPI
|
||
end
|
||
|
||
subgraph Platform[平台后端]
|
||
PAPI --> TQS[TrackQueryService\n统一查询]
|
||
TQS --> DB[(Logistics DB\nWaybill + TrackingEvent)]
|
||
|
||
WH[WebhookController\n接收回调] --> REG[AdapterRegistry/Router\n按carrier或X-Client-Id路由]
|
||
REG --> AD1[YUNDA Adapter]
|
||
REG --> AD2[YTO Adapter]
|
||
REG --> AD3[Aggregator Adapter\n(快递鸟/快递100)]
|
||
|
||
AD1 --> ING[EventIngestService\n幂等/映射/入库]
|
||
AD2 --> ING
|
||
AD3 --> ING
|
||
ING --> DB
|
||
|
||
PJ[PollerJob\n轮询补偿] --> REG
|
||
PJ -->|queryTrack| AD1
|
||
PJ -->|queryTrack| AD2
|
||
PJ -->|queryTrack| AD3
|
||
end
|
||
|
||
subgraph ThirdParty[第三方/Mock]
|
||
MS[Mock Server 或真实承运方/聚合] -->|Webhook 推送| WH
|
||
end
|
||
```
|
||
|
||
### 回调时序图(Webhook 推送 -> 入库 -> 客户端展示)
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant TP as Mock/第三方
|
||
participant WH as WebhookController
|
||
participant REG as AdapterRegistry
|
||
participant AD as CarrierAdapter
|
||
participant ING as EventIngestService
|
||
participant DB as LogisticsDB
|
||
participant API as 平台查询API
|
||
participant APP as 安卓/Web
|
||
|
||
TP->>WH: POST /webhook/express/status (headers + body)
|
||
WH->>REG: resolveAdapter(carrier/X-Client-Id)
|
||
REG->>AD: getAdapter()
|
||
WH->>AD: verify + parseWebhook(rawBody)
|
||
AD-->>WH: NormalizedEvent[]
|
||
WH-->>TP: 200 OK (快速返回)
|
||
WH->>ING: ingest(NormalizedEvent[])
|
||
ING->>DB: upsert events (幂等去重)
|
||
|
||
APP->>API: GET /api/v1/delivery/express/track?order_no=...
|
||
API->>DB: query events (order_no/tracking_no)
|
||
DB-->>API: events ordered by event_time
|
||
API-->>APP: timeLine(status_history + last_synced_at)
|
||
```
|
||
|
||
备注:Mermaid 图在不支持的 Markdown 渲染器中会降级为代码块,不影响内容阅读。
|
||
|
||
## 十三、附录:不同第三方 API 形态示例(用于理解差异)
|
||
|
||
说明:以下为“常见形态示例”,用于帮助团队理解不同第三方接口在鉴权、字段与能力上的差异。
|
||
- 不保证与任一承运方/聚合平台的官方文档 100% 一致;对接时必须以官方文档、沙箱与实际回文为准。
|
||
- 推荐做法:在平台侧实现 Adapter/Mapper,把第三方差异映射为本文定义的统一事件模型再入库。
|
||
|
||
### 13.1 聚合平台常见形态(如快递100/快递鸟类)
|
||
|
||
典型能力:
|
||
- 轨迹查询 API:传入 `company_code + tracking_no`(有些场景需要收件人手机号后四位)
|
||
- 订阅/推送:先订阅,后续以 Webhook 回调推送事件
|
||
- 鉴权:常见 `appKey + sign`(MD5/HMAC)或 Token
|
||
|
||
示例:轨迹查询(示例)
|
||
```http
|
||
POST https://api.aggregator.example.com/v1/track/query
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"company_code": "yunda",
|
||
"tracking_no": "430123456789",
|
||
"phone_last4": "8000",
|
||
"nonce": "n_123",
|
||
"timestamp": 1738735200,
|
||
"sign": "md5_or_hmac_signature"
|
||
}
|
||
```
|
||
|
||
示例响应(示例)
|
||
```json
|
||
{
|
||
"success": true,
|
||
"tracking_no": "430123456789",
|
||
"company_code": "yunda",
|
||
"state": "in_transit",
|
||
"events": [
|
||
{ "time": "2026-02-05T10:12:00+08:00", "context": "已揽收", "location": "深圳市" },
|
||
{ "time": "2026-02-05T22:01:00+08:00", "context": "到达广州分拨中心", "location": "广州市" }
|
||
]
|
||
}
|
||
```
|
||
|
||
差异点:
|
||
- `state` / `status` 枚举不统一;事件字段可能是 `context/desc`、`time/timestamp`。
|
||
- 不同快递公司可能要求手机号参与查询或订阅验证。
|
||
|
||
### 13.2 承运方直连常见形态(企业接口)
|
||
|
||
典型能力:
|
||
- 轨迹查询、签收回单(POD)查询可能拆成多个接口
|
||
- 鉴权更严格:HMAC、证书、IP 白名单或 OAuth2
|
||
|
||
示例:轨迹查询(示例)
|
||
```http
|
||
POST https://open.carrier.example.com/v2/route/query
|
||
Content-Type: application/json
|
||
X-Client-Id: your_client_id
|
||
X-Timestamp: 2026-02-05T10:30:00+08:00
|
||
X-Signature: hmac_sha256(body + timestamp)
|
||
|
||
{
|
||
"tracking_no": "SF1234567890",
|
||
"include_pod": true
|
||
}
|
||
```
|
||
|
||
示例响应(示例)
|
||
```json
|
||
{
|
||
"tracking_no": "SF1234567890",
|
||
"routes": [
|
||
{ "code": "PICKED", "desc": "已揽收", "time": "2026-02-05T09:10:00+08:00", "station": "深圳XX营业点" },
|
||
{ "code": "ARRIVED_HUB", "desc": "到达分拨中心", "time": "2026-02-05T21:45:00+08:00", "station": "广州分拨中心" }
|
||
],
|
||
"pod": { "signed": false, "photo_url": null }
|
||
}
|
||
```
|
||
|
||
差异点:
|
||
- 字段更细(网点编码、操作员等),但不统一;POD 能力通常受权限/合同影响。
|
||
|
||
### 13.3 Webhook 推送常见形态(订阅后回调)
|
||
|
||
典型能力:
|
||
- 订阅后由第三方主动推送轨迹事件到平台
|
||
- 具备重试机制,因此平台必须做幂等去重、乱序处理
|
||
|
||
示例:回调事件(示例,字段名因第三方而异)
|
||
```json
|
||
{
|
||
"tracking_no": "430123456789",
|
||
"carrier": "YUNDA",
|
||
"event_id": "evt_0001",
|
||
"event_time": "2026-02-05T22:01:00+08:00",
|
||
"event_text": "到达广州分拨中心",
|
||
"location": "广州市",
|
||
"extra": { "pod_photo": null }
|
||
}
|
||
```
|
||
|
||
接入建议:
|
||
- 无论第三方字段如何变化,平台入库前统一映射到本文“核心数据模型”,并保留 `raw_payload`。
|
||
- 平台用 `event_id`(优先)或组合键(`tracking_no+event_code+event_time`)实现幂等。
|
||
|
||
### 13.4 圆通(YTO)物流轨迹查询接口(官方文档摘要)
|
||
|
||
文档入口:
|
||
- https://open.yto.net.cn/interfaceDocument/menu251/submenu258
|
||
|
||
定位:该文档描述“根据圆通运单号查询物流轨迹”的接口形态,典型属于“平台主动查询(轮询)”模式。
|
||
|
||
关键交互要点(按官方文档整理,具体以控制台配置与最新文档为准):
|
||
- 传输:HTTPS,POST。
|
||
- 报文结构:请求体包含 `timestamp`、`param`、`format`、`sign`。
|
||
- `param`:以 JSON/XML 字符串承载业务参数;轨迹查询场景下包含圆通运单号字段(示例为 `NUMBER`,一次查询一个单号)。
|
||
|
||
签名规则(按文档描述抽象):
|
||
- 参与签名的明文:`param + method + v`(其中 `method` 与 `v` 来自控制台为该接口生成的配置)。
|
||
- 将上述明文与客户密钥(`secret`)拼接后做 MD5,再对 MD5 的字节结果进行 Base64 编码,得到 `sign`。
|
||
- 伪公式:`sign = base64(md5((param + method + v) + secret))`
|
||
|
||
响应字段(按文档列举的 JSON 返回字段抽象):
|
||
- 运单号:`waybill_No`
|
||
- 走件时间:`upload_Time`(yyyy-MM-dd HH:mm:ss)
|
||
- 物流状态码:`infoContent`(示例枚举包括 GOT/ARRIVAL/DEPARTURE/SENT_SCAN/SIGNED 等)
|
||
- 物流信息文案:`processInfo`
|
||
- 城市/区县:`city`、`district`(可选)
|
||
- 重量:`weight`(可选)
|
||
|
||
平台侧映射建议(把第三方差异收敛到统一模型):
|
||
- 时间:`upload_Time` -> 平台 `event_time`
|
||
- 文案:`processInfo` -> 平台 `event_text`(可另存 `description`)
|
||
- 状态:`infoContent` -> 平台 `event_code`(保留原码),再映射到平台统一 `status_code`(见 `状态映射表.md`)
|
||
|
||
`infoContent` 到平台统一 `status_code` 的建议映射(示例):
|
||
- GOT(已揽收)-> IN_TRANSIT
|
||
- ARRIVAL(已收入/到达)-> ARRIVED_HUB
|
||
- DEPARTURE(已发出/离开节点)-> IN_TRANSIT
|
||
- SENT_SCAN(派件)-> OUT_FOR_DELIVERY
|
||
- INBOUND(自提柜入柜)-> IN_TRANSIT(或按业务定义为 OUT_FOR_DELIVERY)
|
||
- SIGNED(签收成功)-> DELIVERED
|
||
- FAILED(签收失败)-> EXCEPTION
|
||
- TMS_RETURN(退回)-> RETURNED
|
||
|
||
落库建议:
|
||
- 将圆通原始返回(整个数组或单条对象)保存到 `raw_payload`,便于客服/运维对照圆通官网。
|
||
- 幂等去重:若第三方无稳定 `event_id`,可用组合键 `tracking_no + infoContent + upload_Time` 生成 `dedupe_key`。
|
||
|
||
### 13.5 韵达(YUNDA)开放平台(官方文档入口与调研清单)
|
||
|
||
文档入口:
|
||
- https://open.yundaex.com/api/apiDoc
|
||
|
||
说明:韵达开放平台文档页面存在较多交互式内容(需登录/控制台配置后才能看到每个接口的 `method/v/测试地址` 等关键信息)。因此本节先固化“对接时必须确认的要点清单”,避免对接过程中遗漏。
|
||
|
||
从官方文档导航可见的能力分类(用于判断覆盖范围):
|
||
- API 鉴权说明
|
||
- 电子面单、散件下单
|
||
- 物流轨迹
|
||
- 售后服务、国际件、基础服务等
|
||
|
||
韵达轨迹对接需要在控制台确认/落盘的信息(建议形成《承运方接入配置表》):
|
||
- 鉴权方式:签名算法(HMAC/MD5 等)、参与签名字段、编码/排序规则、是否包含时间戳与 nonce。
|
||
- 接口要素:轨迹查询接口 URL、`method`、`v`(如平台/第三方采用“method+version+param”体系)。
|
||
- 订阅/回调能力:是否支持轨迹订阅与回调推送、回调重试策略、回调验签字段。
|
||
- 返回字段:事件时间字段、事件码/状态字段、事件文案字段、地点字段(城市/网点)与可选 POD 能力。
|
||
|
||
平台侧落地方式保持不变:
|
||
- 无论韵达返回结构如何,统一通过 Adapter 映射为平台 `TrackingEvent` 领域模型入库,并保留 `raw_payload`。
|
||
|
||
附:Mock 控制面通用错误码(示例)
|
||
- 40001: invalid_parameter
|
||
- 40002: missing_required_field
|
||
- 40901: duplicate_request
|
||
- 50001: internal_error
|
||
|
||
可选增强(非本期必需):
|
||
- 生成 OpenAPI 文档(控制面 API + Webhook 示例)
|
||
- 补齐“字段必填矩阵/容错矩阵”(配合 `drop_fields` 故障注入)
|