You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

168 lines
5.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 外部系统 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 <Service Token>
X-Customer-Id: <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 连接可能保持 **10420 秒**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 | 托盘数 125 |
| `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 | 限流 |
---
## 方式 BToken 三步接口(旧流程,需客户端轮询)
**前置条件:** 在请求头携带 Token与方式 A 鉴权模式相同)。
```http
Authorization: Bearer <Service Token>
X-Customer-Id: <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*