Files
docs/入库测量与计费/第三方入仓测量接口联调说明-2026-08-04.md

6.1 KiB
Raw Permalink Blame History

第三方入仓测量接口联调说明

版本: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 服务发现。