开放接口文档 · ERP / 进销存对接

维修端与供应端已有 ERP / 进销存系统(金蝶、用友、管家婆等),通过本接口与系统自动同步订单、库存与对账数据

一、接入流程

① 主账号登录本端→② 设置 → 开放接口→③ 开通应用,保存 AppKey / AppSecret→④ ERP 按本文档签名调用→⑤(选填)配置 Webhook 接收事件

AppSecret 仅在开通 / 重置时完整显示一次,请妥善保存;泄露可随时在端内一键重置。应用可停用,停用后全部调用立即被拦截。

二、鉴权与签名

所有接口通过 HTTP 请求头鉴权,四个头缺一不可:

请求头说明
X-App-Key开通应用时分配的 AppKey(erp_ 开头)
X-Timestamp当前毫秒时间戳,与服务器误差须在 ±5 分钟内
X-Nonce8~64 位随机串,10 分钟内不可重复(防重放)
X-Sign签名,见下方算法

签名算法(HMAC-SHA256,十六进制小写)

bodyHash = SHA256_HEX(原始请求体字符串)        // GET 请求为空字符串 ""
signStr  = AppKey + "\n" + Timestamp + "\n" + Nonce + "\n" + bodyHash
X-Sign   = HMAC_SHA256_HEX(AppSecret, signStr)

限流:每应用每分钟 120 次。签名错误、时间戳过期、Nonce 重放均返回 code:-1 与中文错误说明。

Node.js 示例

const crypto = require('crypto');
const APP_KEY = 'erp_xxxxxxxx', APP_SECRET = 'sk_xxxx';
const BASE = 'http://162.14.118.157:3000';

async function callApi(method, path, body) {
  const raw = body ? JSON.stringify(body) : '';
  const ts = String(Date.now());
  const nonce = crypto.randomBytes(12).toString('hex');
  const bodyHash = crypto.createHash('sha256').update(raw).digest('hex');
  const sign = crypto.createHmac('sha256', APP_SECRET)
    .update([APP_KEY, ts, nonce, bodyHash].join('\n')).digest('hex');
  const res = await fetch(BASE + '/api/open/erp/v1' + path, {
    method, headers: { 'Content-Type': 'application/json',
      'X-App-Key': APP_KEY, 'X-Timestamp': ts, 'X-Nonce': nonce, 'X-Sign': sign },
    body: raw || undefined });
  const j = await res.json();
  if (j.code !== 0) throw new Error(j.msg);
  return j.data;
}

// 示例:厂家 ERP 拉取待接单采购单
const orders = await callApi('GET', '/orders?status=' + encodeURIComponent('已接单'));
console.log(orders);

Python 示例

import hashlib, hmac, json, time, requests, secrets

APP_KEY, APP_SECRET = 'erp_xxxxxxxx', 'sk_xxxx'
BASE = 'http://162.14.118.157:3000'

def call_api(method, path, body=None):
    raw = json.dumps(body, ensure_ascii=False) if body else ''
    ts = str(int(time.time() * 1000))
    nonce = secrets.token_hex(12)
    body_hash = hashlib.sha256(raw.encode()).hexdigest()
    sign = hmac.new(APP_SECRET.encode(),
        f'{APP_KEY}\n{ts}\n{nonce}\n{body_hash}'.encode(), hashlib.sha256).hexdigest()
    r = requests.request(method, BASE + '/api/open/erp/v1' + path, data=raw or None,
        headers={'Content-Type': 'application/json', 'X-App-Key': APP_KEY,
                 'X-Timestamp': ts, 'X-Nonce': nonce, 'X-Sign': sign})
    j = r.json()
    assert j['code'] == 0, j['msg']
    return j['data']

三、接口一览

方法路径(前缀 /api/open/erp/v1)说明适用端
GET/ping连通性测试,返回主体信息与可用接口清单两端
GET/orders?status=&since=采购单列表。status 按状态过滤(待接单/已接单/已发货/已完成);since 按创建时间增量拉取(如 2026-10-01)两端
GET/orders/{id}采购单详情(含物流轨迹节点)两端
POST/orders/{id}/ship回传发货:{express, expressNo, freight, auto};auto:true 走系统自动叫单厂家
GET/inventory库存查询:厂家返回商品库存(含仓位号);门店返回库存台账两端
POST/inventory/sync库存同步(绝对值覆盖):{items:[{partId 或 oe, qty, bin?}]},单次 ≤500 条,返回 updated 与 unmatched 明细两端
GET/settlements?month=YYYY-MM月度对账:厂家=已完成采购单合计;门店=清分流水合计与明细两端

数据隔离:每个应用仅能访问本主体(本店/本厂)的数据,越权访问返回「采购单不存在 / 未匹配到商品」。

四、Webhook 事件推送

在端内配置回调地址后,系统将以下事件实时 POST 推送到你的 ERP:

事件触发时机接收方
order.created门店创建采购单(含厂家一键补货代下单)厂家 ERP
order.shipped厂家发货(端内操作或 ERP 回传)门店 ERP
order.received门店签收采购单,自动入库存台账厂家 ERP

推送体:{ "event": "order.shipped", "t": "...", "data": {采购单对象} }

推送头与接口调用使用同一套签名规则(X-App-Key / X-Timestamp / X-Nonce / X-Sign + X-Event),你的 ERP 应按同一算法验签,防止伪造推送。验签后对系统返回 2xx 即视为送达;失败记录可在端内「开放接口 → Webhook 推送日志」查看。

五、错误码与排障

返回含义与处理
缺少鉴权头四个签名头缺一,检查请求头大小写与拼写
时间戳无效或已过期服务器允许 ±5 分钟误差,请校准 ERP 服务器时钟(NTP)
X-Nonce 已使用同一随机串 10 分钟内重复,请每次请求重新生成
签名校验失败核对拼接顺序(AppKey→Timestamp→Nonce→bodyHash)、换行为 \n、bodyHash 用原始请求体、HMAC 输出十六进制小写
触发限流每应用每分钟 120 次,批量同步请合并到 inventory/sync 单次 ≤500 条
应用已停用主账号在端内「设置 → 开放接口」重新启用

全部调用与推送均在端内留痕(接口、结果、耗时、失败原因),主账号可随时审计。

六、与预留接口的关系

系统另保留总台签发的简易 Key 接口(/api/open/v1/*:配件目录、采购单查询、代发起售后),面向保险公司、充电站、公共事业缴费等外部资源接入;本文档的 ERP 体系(/api/open/erp/v1/*)面向门店与厂家的内部系统对接,密钥由本端主账号自助管理。两者互不影响。

门户:道驰云修 · 汽车维修数字系统 · 技术支持请联系系统总台

道驰云修 · 汽车维修数字系统
运营主体:四川马道驰企业管理有限公司