Symax VMS 商城开放 API v1

面向 ERP、自建系统与第三方服务的订单、商品、库存、支付及线索集成接口

概览

所有开放接口使用 /api/v1/*。旧 open_* 路由不再提供兼容。

接口按 API Key 的权限范围和频道范围授权。频道级 Key 只能访问所属频道数据;全局 Key 应只授予受信任的内部系统。

基础地址

https://shop.example.com 替换成商城绑定域名。例如:https://shop.example.com/api/v1/goods

响应格式

{
  "code": 0,
  "goods": { "id": 1001, "status": 0 }
}

code = 0 表示成功;失败时 code = 1,并返回 msg。认证、权限、参数和资源错误同时使用相应 HTTP 状态码。

认证签名

每个请求必须带以下 HTTP Header:

Header说明
X-Shop-Key后台创建的 API Key。
X-Shop-TimestampUnix 秒级时间戳,服务器允许前后 300 秒。
X-Shop-Nonce每次请求唯一的随机字符串。重复 nonce 会被拒绝。
X-Shop-Signature使用 Secret 计算的 HMAC-SHA256 小写十六进制结果。
Content-Type带 JSON Body 的请求使用 application/json

待签名字符串必须严格使用以下五段内容和换行符:

UPPERCASE_METHOD + "\n" +
PATH_WITH_RAW_QUERY + "\n" +
TIMESTAMP + "\n" +
NONCE + "\n" +
RAW_REQUEST_BODY
查询参数属于签名内容。签名 /api/v1/orders?updated_since=... 时,实际请求的参数顺序和编码必须完全一致。GET 请求的 Body 为空字符串。

PHP 签名示例

$method = 'GET';
$path = '/api/v1/orders?updated_since=1780000000&limit=20';
$timestamp = (string) time();
$nonce = bin2hex(random_bytes(16));
$body = '';
$secret = '在后台保存的 Secret';

$string = strtoupper($method) . "\n" . $path . "\n" . $timestamp . "\n" . $nonce . "\n" . $body;
$signature = hash_hmac('sha256', $string, $secret);

$headers = [
    'X-Shop-Key: ' . $apiKey,
    'X-Shop-Timestamp: ' . $timestamp,
    'X-Shop-Nonce: ' . $nonce,
    'X-Shop-Signature: ' . $signature,
];

权限范围

Scope能力
orders.read读取订单及订单详情。
orders.ship回传实物订单物流并标记发货。
payments.read读取支付流水。
goods.read读取商品列表及详情。
goods.write创建或更新商品。新商品默认保存为草稿。
goods.publish / goods.unpublish独立执行商品上架、下架。
categories.read读取频道和分类。
inventory.read / inventory.write读取或更新商品、SKU 库存。
leads.read / leads.write读取或更新客户线索状态、负责人和备注。

接口目录

方法路径Scope用途
GET/api/v1/categoriescategories.read读取当前可访问频道及分类。
GET/api/v1/goodsgoods.read商品列表,支持 pagelimitstatuschannel_idupdated_since
GET/api/v1/goods/{id_or_goods_no}goods.read读取商品详情。
POST / PUT/api/v1/goods/api/v1/goods/{id}goods.write创建或更新商品。以 goods_no 作为外部稳定编码;新建默认草稿。
POST/api/v1/goods/{id}/publishgoods.publish上架商品。
POST/api/v1/goods/{id}/unpublishgoods.unpublish下架商品。
GET/api/v1/inventory?goods_id={id}inventory.read读取商品和 SKU 库存。
PUT / PATCH/api/v1/inventoryinventory.write更新普通商品库存,或指定 sku_key 更新 SKU 库存。
GET/api/v1/ordersorders.read订单列表,支持 pay_statusorder_statusupdated_since
GET/api/v1/orders/{order_no}orders.read读取订单、明细与收货地址。
POST/api/v1/orders/{order_no}/shiporders.ship回传物流单号。只允许已付款的实物订单。
GET/api/v1/paymentspayments.read读取支付流水。
GET/api/v1/leadsleads.read读取线索,支持 statusupdated_since
GET/api/v1/leads/{id}leads.read读取单条线索详情。
PUT / PATCH/api/v1/leads/{id}leads.write更新线索状态、负责人和处理备注。

调用示例

创建商品草稿

POST /api/v1/goods
{
  "goods_no": "ERP-10001",
  "channel_id": 3,
  "cate_id": 12,
  "name": "示例商品",
  "currency": "USD",
  "price": 19.90,
  "market_price": 29.90,
  "stock": 100,
  "thumb": "/webdata/shop/images/example.jpg",
  "images": ["/webdata/shop/images/example.jpg"],
  "sku": { "specs": [], "rows": [], "single": { "sn": "ERP-10001" } },
  "goods_type": 1,
  "shipping_template": "default"
}

创建后返回的 status0。完成资料校验后,再以独立权限调用上架接口。

上架商品

POST /api/v1/goods/1001/publish
{}

更新 SKU 库存

PUT /api/v1/inventory
{
  "goods_id": 1001,
  "sku_key": "Red|M",
  "stock": 36
}

回传物流

POST /api/v1/orders/ORD202608090001/ship
{
  "track_company": "DHL",
  "track_no": "JD014600006281234567"
}

远程图片导入

商品接口不会同步下载外部图片。先创建导入任务,等待任务完成后再把返回的媒体 ID 写入商品;这样商品不会因下载超时而写入半成品。

1. 创建导入任务

POST /api/v1/media
{
  "url": "https://cdn.example.com/products/10001/main.jpg",
  "channel_id": 3
}

需要 media.write 权限。一次最多提交 20 个 URL,也可以使用 urls 数组批量提交。

2. 查询任务

GET /api/v1/media/mi_xxxxxxxxxxxxxxxxxxxxxxxx

任务状态为 completed 时,响应中的 media_idlocal_url 才可使用。pendingprocessingretrying 时应继续轮询;failed 时检查 error_code 后修正 URL。

3. 引用本地媒体

PATCH /api/v1/goods/1001
{
  "thumb_media_id": "med_...",
  "image_media_ids": ["med_...", "med_..."]
}

媒体必须处于完成状态且属于同一频道。系统会将媒体 ID 转为本地地址后保存到商品,不会在商品中保留远程 URL。

导入任务只允许 HTTP/HTTPS 公网图片。内网、回环和保留地址会被拒绝;重定向、文件大小、真实 MIME 类型和图片解码均会校验。

Webhook

在商城后台为全局或频道配置 Webhook 地址和订阅事件。投递为 JSON POST,Header 包含 X-Shop-EventX-Shop-Event-IdX-Shop-TimestampX-Shop-Signature

签名字符串为 timestamp + "\n" + raw_body,使用 Webhook Secret 计算 HMAC-SHA256。接收方应使用 event_id 去重。

类别事件
订单order.createdorder.paidorder.cancelledorder.shippedorder.refund_requested
商品和库存goods.createdgoods.updatedgoods.publishedgoods.unpublishedstock.changedstock.low
线索lead.createdlead.updated
其他payment.abnormaldigital.delivered 及运营预警事件。

排错说明

HTTP 状态常见原因处理方式
401缺少 Header、签名不一致、时间戳超时或 nonce 重复。确认原始 Body、路径与 query、时间戳和 nonce 均未被代理改写。
403Key 已停用或 Scope 不足。在后台检查 Key 状态和权限范围。
404资源不存在,或不属于当前频道 Key 的范围。确认资源 ID、商品频道和 Key 范围。
409商品编码冲突、订单状态冲突或不能发货。先读取最新资源状态,再决定是否重试。
422字段缺失、分类不匹配、SKU 不存在或状态不合法。根据 msg 修正请求字段。
503nonce Redis 或线索数据表不可用。稍后重试,并检查商城基础服务状态。