对外接口

分两类:设备侧接口需要 X-API-Key(在后台「接口密钥」页签发,按产品线限定); 用户侧接口不需要 Key,但按 IP 严格限流,且只返回脱敏信息。

错误约定:业务失败一律返回 HTTP 200 + {"ok":false,"error":"..."}, 只有协议层问题(缺 Key 401、限流 429、参数非法 400)才用 4xx。 客户端只需判断 ok 字段,不必解析状态码表。

设备侧接口(需 API Key)

GET /api/v1/ping

连通性探测,返回服务名与时间。不需要 Key。

GET /api/v1/products

列出在售商品与规格。只暴露「有没有货」,不暴露精确库存数。

POST /api/v1/verify

校验卡密,不改动任何数据。

# 请求
curl -X POST https://<域名>/api/v1/verify \
  -H "X-API-Key: ck_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"card":"YZ-XXXXX-XXXXX-XXXXX-XXXXX","deviceId":"machine-fingerprint","deviceName":"DESKTOP-01"}'

# 响应
{ "ok": true, "action": "known_device", "card": {
    "status": "active", "usable": true, "permanent": false,
    "remainingDays": 27, "maxDevices": 2, "usedDevices": 1,
    "expiresAt": "2026-10-21T08:55:42.000Z" } }

POST /api/v1/activate

激活并绑定设备。首次激活会从这一刻起算有效期(不是在库存里放着的这段时间)。 设备数超过规格上限时返回 device_limit/api/v1/heartbeat 与它等价,可用于定期续期并刷新最后在线时间。

POST /api/v1/batch-verify

一次最多校验 100 张,返回与请求等长的结果数组。大批量迁移或对账时用。

字段位置说明
cardbody卡密。也接受 code / licenseKey 两个别名
deviceIdbody设备指纹。verify 可省略;activate 必填
deviceNamebody设备名,用于后台人工核对
X-API-Keyheader也接受 Authorization: Bearer <key>

错误码

error含义建议处理
bad_format卡密格式不对提示用户检查输入
not_found卡密不存在提示卡密无效
not_issued卡密还在库存里,尚未发货联系客服
revoked已吊销(退款或人工)停止使用
expired已过有效期引导续费
deadline_passed超过最终期限停止使用
device_limit绑定设备数已满提示解绑或升级
missing_deviceactivate 没带 deviceId补上再试
product_not_allowed该 Key 无权校验这个产品线的卡换对应产品线的 Key

用户侧接口(无需 Key)

POST /api/public/query

按 IP 限流(默认 20 次/分钟)且校验同源,只返回末四位与状态,不返回完整卡密。 为了让「卡密是否存在」无法被探测,不存在与格式错误统一返回 not_found

curl -X POST https://<域名>/api/public/query \
  -H "Content-Type: application/json" \
  -d '{"card":"YZ-XXXXX-XXXXX-XXXXX-XXXXX"}'

GET /api/public/config

返回站点名称与副标题,供页面展示。

接入步骤

  1. 在后台「商品」里建一个商品,代号填成你的产品线(例如 nova)。
  2. 在「商品」里给它加规格:填时长、设备数、价格。
  3. 到「库存」里对这个规格批量生卡。
  4. 到「接口密钥」签发一把 Key,产品线填上一步的代号(留空表示不限)。
  5. 客户端调用 /api/v1/activate,带上 X-API-KeydeviceId

Key 明文只在签发时显示一次,库里只有哈希 —— 丢了只能在后台重新签发一把。