# 外部系统 API 对接说明 > 完整对接指南(含美美与共示例、前端职责、自测方法)见 **[第三方对接指南](./第三方对接指南.md)**。 Base URL:`https://<你的域名>`(示例:`https://if.dev.51track.vip`) ## 响应格式 ```json { "code": 0, "message": "ok", "data": { } } ``` `code !== 0` 时为业务错误;询价业务失败时 HTTP 可能仍为 200,`data.status === "failed"`。 --- ## 方式 A:宿主两步接口(推荐) **接口路径不变**,鉴权由服务器 `.env` 控制: | 模式 | `HOST_PUBLIC_API_ENABLED` | 请求头 | |------|---------------------------|--------| | 公开(联调/内网) | `true` | 只需 `Content-Type: application/json` | | **鉴权(对接第三方)** | `false` | 见下方 Token 头 | | 步骤 | 方法 | 路径 | 说明 | |------|------|------|------| | 1 | POST | `/api/host/quote/candidates` | 地址 + 货物 → 联想候选 + `host_session_id` | | 2 | POST | `/api/host/quote/submit` | 确认候选 → **同步返回最终报价**(服务端内部轮询) | **公开模式** 无需 `Authorization` / `X-Customer-Id`。只需: ```http Content-Type: application/json ``` **鉴权模式** 须携带(Token 由我方在 `HOST_SERVICE_TOKENS` 中配置后发放): ```http Authorization: Bearer X-Customer-Id: Content-Type: application/json ``` 服务端 `.env` 示例(为美美与共单独发 Token): ```env HOST_PUBLIC_API_ENABLED=false HOST_SERVICE_TOKENS={"meimei-2026":{"customerId":"CUST_001","permissions":["pricing:markup:write"]}} CUSTOMER_REGISTRY=CUST_001 ``` ### 1. 联想地址 **请求体:** 见 [`host-candidates-req.example.json`](./host-candidates-req.example.json) **成功响应 `data` 字段:** | 字段 | 说明 | |------|------| | `host_session_id` | UUID,第二步必传;30 分钟有效 | | `pickup_candidates` | 提货候选列表 | | `delivery_candidates` | 派送候选列表 | | `requires_selection` | 是否需用户从多条候选中选择 | 候选对象字段:`option_id`、`display_label`、`formatted_address`、`street`、`city`、`state`、`zip`、`selectable`、`unavailable_reason` ### 2. 确认并取报价 ```json { "host_session_id": "第一步返回的 UUID", "pickup_candidate": { "option_id": "...", "display_label": "...", "formatted_address": "...", "street": "...", "city": "...", "state": "CA", "zip": "90001" }, "delivery_candidate": { "option_id": "...", "display_label": "...", "formatted_address": "...", "street": "...", "city": "...", "state": "TX", "zip": "75201" } } ``` `pickup_candidate` / `delivery_candidate` 须为第一步返回列表中的完整对象(`option_id` 须匹配)。 **成功响应 `data`:** 与 `GET /api/quotes/{id}` 相同,主要字段: | 字段 | 说明 | |------|------| | `status` | `done` 成功;`failed` 失败 | | `quotes[]` | 多档报价 | | `quotes[].final_total` | **对客户展示价**(USD,含加价) | | `quotes[].carrier` | 承运商 | | `quotes[].transit_days` | 时效 | | `error_message` | `status=failed` 时的原因 | **注意:** - 第二步 HTTP 连接可能保持 **10–420 秒**,Nginx 须设 `proxy_read_timeout 420s;` - 宿主**无需**再调 `GET /api/quotes/{id}` 轮询 ### 货物字段(第一步 `cargo`) | 字段 | 类型 | 说明 | |------|------|------| | `weight.value` | number | 单托重量 | | `weight.unit` | `lb` \| `kg` | 重量单位 | | `dimensions.length/width/height` | number | 单托尺寸 | | `dimensions.unit` | `in` \| `cm` | 尺寸单位 | | `pallet_count` | number | 托盘数 1–25 | | `cargo_type` | string | 见下方枚举 | **货物类型:** `general_freight` · `machinery` · `furniture` · `electronics` · `building_materials` · `auto_parts` · `food_nonperishable` · `apparel` · `other` ### 方式 A 错误码 | code | HTTP | 说明 | |------|------|------| | `VALIDATION_FAILED` | 400 | 参数无效;若 message 为「请求体格式无效」多为 JSON 格式错误 | | `UNAUTHORIZED` | 401 | 鉴权模式下缺少或无效的 `Authorization` | | `SESSION_EXPIRED` | 404 | `host_session_id` 过期或无效 | | `ADDRESS_SESSION_MISMATCH` | 400 | 候选不在本次联想结果中 | | `ADDRESS_NOT_SELECTABLE` | 400 | 选了不可用的候选 | | `QUOTE_TIMEOUT` | 504 | 服务端轮询超时 | | `RATE_LIMITED` | 429 | 限流 | --- ## 方式 B:Token 三步接口(旧流程,需客户端轮询) **前置条件:** 在请求头携带 Token(与方式 A 鉴权模式相同)。 ```http Authorization: Bearer X-Customer-Id: Content-Type: application/json ``` Token 在 `.env` 的 `HOST_SERVICE_TOKENS` 中配置。 | 步骤 | 方法 | 路径 | |------|------|------| | 1 | POST | `/api/addresses/mothership-candidates` | | 2 | POST | `/api/quotes` | | 3 | GET | `/api/quotes/{quote_id}`(每 2 秒轮询,最长约 7 分钟) | 第二步 body 须含 `customer_id`、`request_id`(UUID v4)、经 MotherShip 确认的 `pickup_address` / `delivery_address` 及货物字段。详情见 [第三方对接指南 §6](./第三方对接指南.md#6-方式btoken-三步接口)。 --- ## 快速自测(方式 A) **Windows PowerShell(推荐用 JSON 文件,避免引号转义问题):** ```powershell curl.exe -s -X POST "https://if.dev.51track.vip/api/host/quote/candidates" ` -H "Content-Type: application/json" ` --data-binary "@deploy/host-candidates-req.example.json" ``` 返回 `"code":0` 且含 `host_session_id` 即成功。 **Linux / macOS:** ```bash curl -s -X POST "https://if.dev.51track.vip/api/host/quote/candidates" \ -H "Content-Type: application/json" \ --data-binary "@deploy/host-candidates-req.example.json" ``` --- *文档版本:2026-06-30*