6.0 KiB
6.0 KiB
第三方入仓测量接口联调说明
版本:2026-08-04
网关基地址:http://127.0.0.1:9000(测试环境替换为实际网关域名)
一、接口用途
第三方测量设备每次回传一条箱规测量数据和一张对应图片。后端按入仓码匹配入库单,并校验指定货物明细属于该入库单关联订单,然后形成一条测量明细。
接口只保存测量结果,不执行客服审核、计费、托盘拆分、库位占用或完成入库。
二、提交接口
POST /openapi/v1/inbound-measurements
Content-Type: multipart/form-data
请求头:
X-App-Key: <第三方应用Key>
X-Timestamp: <Unix毫秒时间戳>
X-Nonce: <本次请求唯一随机串>
X-Signature: <HMAC-SHA256签名>
Idempotency-Key: <本次业务操作幂等键>
multipart 内容:
| part 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
data |
UTF-8 JSON 文本 | 是 | 一条箱规测量数据,服务端使用原文验签 |
image |
二进制文件 | 是 | 该条明细唯一对应图片;JPG、PNG、BMP,最大 5 MB |
data 示例:
{
"eventNo": "M202608040001",
"externalDetailNo": "BOX-20260804-0001",
"warehouseCode": "CN-YW-01",
"inboundCode": "ZBYHK2604100412",
"inboundDetailId": "190000000000000001",
"deviceCode": "DEVICE-01",
"measuredAt": "2026-08-04T10:30:00+08:00",
"boxSpecification": "40*30*47cm",
"packageCount": 50,
"lengthCm": 40.000,
"widthCm": 30.000,
"heightCm": 47.000,
"unitWeightKg": 20.000,
"remark": ""
}
字段说明:
| 字段 | 必填 | 规则 |
|---|---|---|
eventNo |
是 | 同一 AppKey 下唯一;1~128 位字母、数字、点、下划线、冒号或横线 |
externalDetailNo |
是 | 第三方物理测量明细唯一号;重复绑定会被拒绝 |
warehouseCode |
是 | 必须属于该 AppKey 预先绑定的仓库 |
inboundCode |
是 | 柏悦入仓码,后端据此匹配入库单 |
inboundDetailId |
是 | 柏悦提供的订单货物明细 ID;必须属于该入库单关联订单 |
deviceCode |
是 | 测量设备编码,最长 64 位 |
measuredAt |
是 | ISO 8601 时间且必须包含时区 |
boxSpecification |
是 | 箱规显示文本,最长 64 位 |
packageCount |
是 | 本箱规箱数,1~1,000,000 |
lengthCm |
是 | 单箱长度,单位厘米且大于 0 |
widthCm |
是 | 单箱宽度,单位厘米且大于 0 |
heightCm |
是 | 单箱高度,单位厘米且大于 0 |
unitWeightKg |
否 | 单箱重量,单位 KG且大于 0;重量 OCR 流程可另行确认 |
remark |
否 | 最长 500 字符 |
三、签名算法
先计算图片内容摘要:
imageSha256 = SHA256(image原始字节).lowerHex
构造签名 body,LF 是单个换行符 \n:
signatureBody = data原始UTF-8文本 + LF + imageSha256
bodySha256 = SHA256(signatureBody的UTF-8字节).lowerHex
构造六行 canonical string,末尾不追加换行:
POST
/openapi/v1/inbound-measurements
<X-Timestamp>
<X-Nonce>
<Idempotency-Key>
<bodySha256>
最终签名:
X-Signature = HMAC-SHA256(appSecret, canonicalString).lowerHex
data 中任何空格、换行或字段顺序变化都会改变签名。计算签名后必须发送完全相同的 data 原文和图片字节。
四、成功响应
{
"code": "200",
"message": "success",
"data": {
"eventNo": "M202608040001",
"inboundCode": "ZBYHK2604100412",
"inboundDetailId": "190000000000000001",
"measurementId": "190000000000000010",
"measurementItemId": "190000000000000020",
"imageFileId": "190000000000000030",
"accepted": true,
"status": "RECEIVED",
"receivedAt": "2026-08-04T02:30:00Z"
},
"requestId": "...",
"traceId": "...",
"timestamp": "2026-08-04T02:30:01Z"
}
所有 ID 都是字符串,调用方不得转换为 JavaScript Number。
五、事件查询
GET /openapi/v1/inbound-measurements/events/{eventNo}
GET 同样需要 X-App-Key、X-Timestamp、X-Nonce 和 X-Signature,不需要 Idempotency-Key。canonical string 中幂等键行为空字符串,body 摘要使用空字节 SHA-256。
六、幂等与重复规则
X-Nonce:短时间防重放,使用后不能再次使用。Idempotency-Key:一次 HTTP 写操作标识;网络重试必须复用原值。appKey + eventNo:第三方业务事件唯一标识。tenantId + inboundDetailId + externalDetailNo:测量明细绑定唯一约束。- 相同事件号或幂等键重试时,
data原文及图片内容必须与首次完全一致,否则返回冲突。
七、主要失败场景
| 业务码 | 场景 |
|---|---|
A0400 |
data 不是有效 JSON、图片为空或无法读取 |
A0401 |
AppKey、时间戳或签名无效 |
A0403 |
AppKey 未绑定请求仓库,或内部凭证无效 |
A0404 |
入仓码不存在,或货物明细不属于入库单关联订单 |
A0409 |
入库状态不允许测量、Nonce 重放、事件/幂等内容不一致、明细重复绑定 |
A0422 |
字段缺失、格式或数值范围不符合要求 |
S0503 |
Order 或 File 服务暂不可用 |
普通业务失败应以响应体 code 判断,不能只判断 HTTP 状态。
八、后台处理过程
验签和防重放
→ 按入仓码及绑定仓库查入库单
→ 调用 Order 校验货物明细归属
→ 检查第三方明细号是否已经绑定
→ 调用 File 保存并校验真实图片
→ 写入一条测量批次和一条测量明细
→ 返回测量、明细和图片ID
如果图片已保存但测量数据落库失败,Firstleg 会调用 File 执行补偿清理。
九、上线前置
部署新版 Firstleg 前,先执行:
firstleg/src/main/resources/db/phase2-third-party-single-measurement-migration.sql
或执行已内联该增量的二期统一脚本:
deploy/sql/2026-08-04-二期入库新增表字段-MySQL8一键执行.sql
同时确认 Firstleg、Order、File 使用一致的 INTERNAL_SERVICE_TOKEN,并配置 ORDER_SERVICE_URL、FILE_SERVICE_URL 或启用 Nacos 服务发现。