美润 WMS 开放接口

给卖家自己的系统、ERP 厂商、外包开发对接用。版本 v1,更新于 2026-09-23。 English

概述

地址https://wms.meirun.com/api/v1/...
格式请求和响应都是 JSON(UTF-8),POST 要带 Content-Type: application/json
时间ISO 8601,UTC,例如 2026-09-23T16:44:03.235Z
单位尺寸英寸(in),重量磅(lb)。字段名里带着单位:weightLb、lengthIn
数据范围一把密钥只能看到、只能操作发给它的那个卖家的数据;请求里带别的卖家也没用

认证与密钥

密钥由卖家在 OMS 生成:设置 → API 密钥 → 新建。密钥只在生成那一刻显示一次,丢了就作废重发。

AI 助手一键连接。Claude、ChatGPT 等支持 MCP 的 AI 助手,添加连接器时填 https://oms.meirun.com/mcp,卖家在弹出的 OMS 页面选只读或读写、按「允许」即可,不用复制密钥。连接后它和其它密钥一样列在「设置 → API 密钥」里,名字是「助手名 (AI)」,在那里撤销。

每个请求带在请求头里,两种写法都行:

X-Api-Key: wk_xxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxx
Authorization: Bearer wk_xxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxx
权限能做什么
只读所有 GET 接口
读写再加上所有 POST:建订单、取消、建商品、建入库单、设置 Webhook
只用来同步状态的系统,请发只读密钥。只读密钥调写接口会直接返回 403,不会悄悄成功。

测试模式

任何写接口加请求头 X-Test: 1:整个请求照常执行,所有校验都跑,返回和真的一样(多一个 "test": true),然后全部撤销,一条数据都不留。用来联调,不需要另开测试环境。

curl -X POST https://wms.meirun.com/api/v1/orders \
  -H "X-Api-Key: $KEY" -H "X-Test: 1" -H "Content-Type: application/json" \
  -d '{"ref":"TEST-1","lines":[{"sku":"LAMP-A","qty":1}]}'

分页

列表接口都支持 page(从 1 开始)和 pageSize(最大 200)。返回里带 total、page、pageSize。

错误

出错时 HTTP 状态码不是 2xx,响应是 {"error": "一句说明"},有的还带 reason(机器可读)。

状态码意思
400请求内容不对,error 里说哪里不对
401没带密钥,或密钥不对、已作废(统一这一句,不区分)
403只读密钥调了写接口;或要操作别的卖家
404没有这条记录(别的卖家的也返回 404)
409当前状态不允许,例如订单已发货、已买面单
422批量导入里有行不对,一行都没导入,problems 逐行说明

GET/api/v1/whoami

验证密钥,不改任何东西。对接写的第一个调用。

{ "warehouse": "meirun", "scope": "write",
  "seller": { "code": "1001", "name": "Hongyu Houseware" }, "key": "wk_15540e4e" }

GET/api/v1/warehouses

这家海外仓的各个仓(楼)。建入库单时用 code。

{ "warehouses": [ { "code": "WAL", "name": "Walnut", "city": "Walnut", "state": "CA", "country": "US" } ] }

商品

GET/api/v1/products

参数:q(搜 SKU/品名)、status(draft / pending / active / rejected / archived)、分页。

POST/api/v1/products

新建商品,默认直接提交给仓库审核(状态 pending);"submit": false 只存草稿。仓库审核通过后才能入库上架。

{
  "sku": "LAMP-A",               // 必填,2-50 个字符
  "name": "Brass Table Lamp",    // 必填
  "barcodes": ["0123456789012"],
  "declaredSpec": { "lengthIn": 12, "widthIn": 9, "heightIn": 4, "weightLb": 2.1 },
  "declare": { "en": "Table lamp", "cn": "台灯", "value": 15, "currency": "USD",
               "customsAttr": "general", "hsCode": "9405" }
}

GET/api/v1/stock

按 SKU 查库存。参数:sku(可逗号分隔多个,不填是全部)、分页。

{ "total": 1, "page": 1, "pageSize": 200, "stock": [ {
  "sku": "LAMP-A", "name": "Brass Table Lamp",
  "available": 38,      // 可售 = 在架 - 已被订单占用。推给平台的就是这个数
  "onShelves": 40, "locked": 2, "inTransit": 100, "awaitingPutaway": 0, "damaged": 1,
  "warehouses": ["WAL"]
} ] }

POST/api/v1/orders

建一张出库订单。有货的整单从货架发,没货的走工厂直邮,系统自己判断。

{
  "ref": "3153-3369-0518-3280",   // 你的订单号,唯一;不填系统生成
  "erpNo": "ERP-889012",          // 可选,你系统里的编号
  "shipTo": { "name": "Jane Doe", "company": "", "line1": "12 Main St", "line2": "",
              "city": "Flagstaff", "state": "AZ", "postCode": "86004", "country": "US", "phone": "9285550100" },
  "lines": [ { "sku": "LAMP-A", "qty": 2 } ]
}

返回 201,parcel 是建好的订单。

POST/api/v1/orders/import

一次导入一批,内容是 CSV 文本。全有或全无:有一行不对就一行都不导入,并逐行说明。"dryRun": true 只检查不导入。

认的列名(不分大小写):订单号 order/ref/order-id,sku,qty/quantity,收件人 name,地址 address1、address2、city、state、zip、country、phone。Amazon 未发货订单报表可以原样传。同一订单号多行 = 一单多个 SKU。

{ "text": "order,sku,qty,name,address1,city,state,zip,country\n1001,LAMP-A,2,Jane Doe,12 Main St,Flagstaff,AZ,86004,US", "dryRun": false }

GET/api/v1/orders

参数:q(搜单号)、status、updatedSince(只要这个时间之后变化过的)、分页。用轮询同步的话,每次带上你已经拿到的最新 updatedAt。

{ "total": 3, "page": 1, "pageSize": 200, "orders": [ {
  "ref": "3153-3369-0518-3280", "status": "shipped", "holdReason": null,
  "platform": "shopify", "platformOrderNo": "#3280", "erpNo": "ERP-889012",
  "shipTo": { ... }, "lines": [ { "sku": "LAMP-A", "qty": 2 } ],
  "weightLb": 4.2, "lengthIn": 12, "widthIn": 9, "heightIn": 4,
  "tracking": "794854001240", "carrier": "FEDEX",
  "shippedAt": "2026-09-22T21:10:00.000Z", "cancelledAt": null,
  "createdAt": "...", "updatedAt": "..."
} ] }

POST/api/v1/orders/cancel

取消订单。只在还没发生不可逆的事时能取消:已买面单、工厂已做出箱子、已发货的会被拒,并说明原因——这时请联系仓库。

{ "ref": "3153-3369-0518-3280" }
结果返回
取消成功200 {"ok": true, "already": false}
本来就已取消200 {"ok": true, "already": true}
已发货409 reason: "shipped"
已买面单409 reason: "labelled"
工厂已做出箱子409 reason: "boxed"
没有这单404 reason: "missing"

POST/api/v1/orders/intercept

截单。和 OMS 里的「截单」按钮是同一件事:还没发生不可逆的事就当场取消;已经买了面单、已经拣货或工厂已做出箱子的,先挂起等仓库确认,挂起期间不会发货。仓库同意后面单作废、运费退回、货放回货架;不同意的话订单回到原来的状态,原因写在这一单的留言里。

结果之后看订单自己的状态(GET /api/v1/orders 或 Webhook):cancelled 是取消了,exception 是还在等仓库。

{ "ref": "3153-3369-0518-3280" }
结果返回
当场取消200 {"ok": true, "state": "cancelled"}
等仓库确认200 {"ok": true, "state": "pending"}
本来就已取消200 {"ok": true, "state": "already"}
已发货409 reason: "shipped"
没有这单404 reason: "missing"

/api/v1/orders/cancel 保持原样(已买面单的直接 409),已经按它写好的对接不受影响。

入库单

GET/api/v1/inbound

参数:status、q、分页。

POST/api/v1/inbound

告诉仓库有货要来。商品要先在系统里(见上面「商品」)。

{
  "warehouseCode": "WAL",          // 只有一个仓时可以不填
  "tracking": "1Z999AA10123456784",
  "eta": "2026-10-05",
  "cartons": 12,
  "note": "",
  "lines": [ { "sku": "LAMP-A", "qty": 120 } ]
}

GET/api/v1/consignments

跨境直邮的箱子:工厂量尺、交给货代、到仓、出库各个时间点。一单多箱时箱号是 订单号-1、订单号-2。参数 q。

GET/api/v1/tracking

已发货订单在承运商那里的进度。参数:q、stage、stalled=1(只要卡住的)。

Webhook:订单一变就通知你

不想轮询的话,给密钥设一个接收地址(必须 https)。之后每分钟把这一分钟里变化过的订单 POST 过去,一次最多 100 单。

POST/api/v1/webhook

{ "url": "https://erp.example.com/meirun/hook" }
→ { "ok": true, "url": "...", "secret": "whsec_..." }   // secret 只显示这一次

{"url": ""} 关掉。GET/api/v1/webhook 看当前地址、最后一次送达时间和最后一次失败原因。

我们发过去的

POST https://erp.example.com/meirun/hook
Content-Type: application/json
X-WMS-Timestamp: 1758645843
X-WMS-Signature: sha256=5f1c...

{ "event": "orders.updated", "orders": [ { ...和 GET /api/v1/orders 里的一样... } ] }

验证签名

用 secret 对 时间戳 + "." + 原始请求体 做 HMAC-SHA256,和 X-WMS-Signature 比较。不一致就不是我们发的。

// Node.js
const crypto = require("crypto");
const expected = "sha256=" + crypto.createHmac("sha256", SECRET)
  .update(req.headers["x-wms-timestamp"] + "." + rawBody).digest("hex");
if (expected !== req.headers["x-wms-signature"]) return res.status(401).end();

# Python
import hmac, hashlib
expected = "sha256=" + hmac.new(SECRET.encode(), (ts + "." + raw_body).encode(), hashlib.sha256).hexdigest()
至少送达一次,不保证只一次。 你返回 2xx 才算送达;超时或出错,下一分钟会把同样的订单再发一遍。请按 ref + updatedAt 去重。

订单状态

status意思
awaitingTracking待获取运单号
toMove待移货
toPrint已有运单号,待打单
toPick待拣货
toPack待包装
toShip待发货
shipped已发货
cancelled已取消
exception挂起,等人处理。holdReason:platformCancelled(平台取消了,但面单已买)/ platformAddress(平台改了地址,但面单已买)

有问题联系美润:在 OMS 里给仓库发工单,或联系你的对接人。