开放 API(实例注册 / 心跳 / 授权)

面向商城或服务端的 HTTP JSON 接口。所有路径均相对于站点根,例如 /api/v1/...

一、凭证与签名(注册类接口)

下列请求头必填(除 Content-Type):

规范串(UTF-8,换行符 \n):

METHOD + "\n" + CANONICAL_PATH + "\n" + TIMESTAMP + "\n" + SHA256(原始请求体)

CANONICAL_PATH 为 pathinfo 小写、去两端斜杠、若以 .html 结尾则去掉该后缀。密钥为凭证 Secret。X-Signature 为十六进制小写 HMAC 结果。

二、实例令牌(心跳 / 授权接口)

注册成功后响应中的 instance_token 仅返回一次,请安全保存。

三、接口列表

方法 路径 说明
POST/api/v1/instances/register产品签名。Body JSON:host(必填)、versionversion_codesite_nameextra。不支持泛域名 host。
POST/api/v1/instances/heartbeat实例令牌。Body:reported_ipversion 等。
POST/api/v1/license/verify实例令牌,校验授权。
GET/api/v1/license/summary实例令牌,授权摘要。

四、响应与错误码

成功与失败均为 JSON,字段:code(业务码)、messagerequest_iddata。HTTP 状态码与业务码可能不同,请以 JSON 为准。

产品签名相关

  • 200 — 成功
  • 40001 — 缺少 X-App-Id(HTTP 401)
  • 40002 — 无效 App Id(401)
  • 40003 — 凭证已过期(401)
  • 40004 — 签名无效(401)
  • 40005 — 重复或无效 Nonce(429)
  • 42901 — 单凭证 instances/register 过于频繁(429);分钟窗口由中枢 license.api_register_max_per_minute 控制,为 0 时关闭该限流
  • 40006 — 凭证已停用(403)
  • 40010 — host 必填(422)
  • 40011 — 开放接口不支持泛域名(422)
  • 50001 — 注册失败(500)

实例令牌相关

  • 40101 — 缺少 X-Instance-Id(401)
  • 40102 — 缺少 Authorization Bearer(401)
  • 40103 — 实例无效或已停用(403)
  • 40104 — 实例令牌无效(403)
  • 50002 — 心跳失败(500)

五、CRMEB updatewebinfo 与实例 host

中枢会读取 POST 中的 ipversionversion_codewebnamehttpshost;安装完成页 step5 常见的 uid 会写入心跳 extra 与审计 payload,便于在「接入流水 / 实例详情 / 审计」检索。接入源 IP(反代后见 TRUSTED_PROXY_IPS)与 POST 里的 ip(业务侧「上报 IP」)含义不同,排障时勿混读。完整决策与落库说明见 /docs/runbook-crmeb

与 CRMEB updatewebinfo 一致的 host 归一化

授权台用与开放 API 注册、预建实例相同的规则解析「站点标识」resolved_site_host

  1. 取 POST 字段 https(非空则优先);否则取 host
  2. 转小写、去掉 http://https:// 前缀,去掉尾部 /,再取第一个 / 之前的段(即不含路径)。
  3. 不自动去掉 www.:若商城上报 www.a.com,实例 host 须为 www.a.com 或能匹配的泛域名(如 *.a.com)。
  4. 纯 IP 站点(如 192.168.1.10)须用同一 IP 字符串预建/注册,不能与仅域名实例混用。

重要:平台默认在「系统设置」中开启 updatewebinfo 自动开通:未匹配到现有实例时会按指定产品自动创建实例并写入心跳(返回的 hint 会说明需在后台重置实例 Token 后配置到商城)。若关闭自动开通,则须先「预建实例」或 POST /api/v1/instances/register,且 host 与上式结果一致后,matched_instance_id 才会非空。未匹配或自动开通失败时可在「审计」中查看 crmeb.updatewebinfo_unmatched / crmeb.updatewebinfo_auto_provision;审计列表中的「接入 IP」列为中枢看到的对端地址,POST 字段 ip 在摘要里记为 body_ip

uid:若商城在表单中附带 uid,中枢会写入心跳 extra.uid 与 CRMEB 相关审计,可在「实例列表 / 审计」按 uid 筛选(依赖 MySQL JSON 函数)。

六、CRMEB shop Open API(/api/open/*

与上文「产品签名 /api/v1/*不是同一套协议。对应 CRMEB 中 UpgradeOpenApiService(原指向 shop.crmeb.net):成功时 JSON 顶层为 status === 200msgdata。可选请求头:X-APP-IDSystem-VersionAuth-Host(与 CRMEB 常见头对齐;中枢不强制校验除白名单外的头)。

方法 路径 说明
GET/api/open/version_listQuery:pagelimit。data 为版本行列表(与 get_version_list 数据源一致)。
GET/api/open/version_infoQuery:id。data 为单条详情。
GET/api/open/new_version_countQuery:id(客户端当前包 id)。data:{"count":n}
GET/api/open/get_version_authdata:{"auth":0|1},与系统设置 / 配置中 isauth 桩一致(非 shop 商业购权)。
POST/api/open/upgrade_logBody:JSON 或表单;落审计 crmeb.open.upgrade_log(摘要字段,防超大 payload)。

部署:环境变量 CRMEB_OPEN_API_ENABLED=false 时上述路径返回 HTTP 503 + JSON;CRMEB_OPEN_API_APP_IDS 非空时仅允许所列 X-APP-ID(逗号分隔)。亦可于「系统设置」覆盖开关与 AppId 白名单。新版跨版本升级云(原 upgrade.crmeb.net)见 Runbook 第六节:路径前缀 /crmeb-upgrade/api/...,与本节 /api/open 不同。

升级包 zip 与探测

商城会从 /public/uploads/upgrade/*.zip 拉包。虚构文件名探测得到 404 仅表示静态路径可达;真实升级200Content-Type 为 zip 且大小合理。无登记包时接口可能返回兼容桩数据,与「已登记升级包」条数一致即可。

安全建议

建议在网关或 WAF 对 POST /api/v1/instances/register 做 IP 白名单或 QPS 限流;管理后台使用强密码并限制管理入口暴露面。

HTTPS 全站 · 最小必要采集