0. 接口兼容
本卡网框架兼容独角兽卡网(Dujiao-Next)Provider 协议,可按照独角兽卡网协议完成接口认证、商品同步、库存同步、采购下单、订单查询和发货回调等对接。
同时,本卡网框架提供完备的自定义上下游同步协议,支持同步商品分类、商品信息、SKU、价格、库存、Logo、商品详情、详情图片、发货格式等字段。
未来将继续兼容更多卡网同步协议和 Provider 实现,具体以对应版本的 API 文档为准。
如需部署本卡网或进行上下游接口对接,可联系客服获取部署与技术支持。
1. 接入概览
Nexora Provider API 让本站可以作为上游货源站。下游系统配置 API URL、API Key、API Secret 后,可以同步分类、商品、SKU、库存、价格、图片、发货格式,并在用户付款后向本站创建采购订单。
基础地址示例:
https://your-domain.example.com
API 前缀:
/api/v1/upstream
备用前缀:
/v1/upstream金额字段统一使用字符串并保留两位小数,例如 "12.30"。当前币种为 CNY,采购余额复用 API Key 绑定用户的积分余额。
2. 认证与签名
所有 Provider API 请求都必须携带认证头:
Dujiao-Next-Api-Key: <api_key>
Dujiao-Next-Timestamp: <unix_timestamp_seconds>
Dujiao-Next-Signature: <signature>
Content-Type: application/json签名算法:
body_md5 = md5(raw_request_body)
sign_string = METHOD + "\n" + PATH + "\n" + TIMESTAMP + "\n" + body_md5
signature = hex_lowercase(hmac_sha256(api_secret, sign_string))签名注意事项:
METHOD使用大写,例如 GET、POST。PATH只包含路径,不包含域名和查询字符串。- GET 请求或空请求体按空字节计算 MD5。
- 时间戳允许窗口为 60 秒,请保证服务器时间准确。
- 请求体最大 1MB,超过会返回 413。
import crypto from "node:crypto"
function sign({ method, path, timestamp, body = "", secret }) {
const bodyMd5 = crypto.createHash("md5").update(body).digest("hex")
const signString = `${method.toUpperCase()}\n${path}\n${timestamp}\n${bodyMd5}`
return crypto.createHmac("sha256", secret).update(signString).digest("hex")
}3. 接口列表
| 方法 | 路径 | 说明 |
|---|---|---|
| GET/POST | /api/v1/upstream/ping | 连接测试、账户信息、余额 |
| GET | /api/v1/upstream/categories | 分类列表 |
| GET | /api/v1/upstream/products | 商品列表 |
| GET | /api/v1/upstream/products/{id} | 商品详情 |
| POST | /api/v1/upstream/orders | 创建采购订单 |
| GET | /api/v1/upstream/orders/{id} | 查询采购订单 |
| POST | /api/v1/upstream/orders/{id}/cancel | 取消采购订单,当前版本不支持 |
4. 商品同步接口
连接测试
GET /api/v1/upstream/ping
{
"ok": true,
"site_name": "Nexora|耐索拉",
"provider_type": "ORION_KEY",
"protocol_version": "1.0",
"instance_id": "nexora",
"user_id": "00000000-0000-0000-0000-000000000000",
"balance": "100.00",
"currency": "CNY",
"member_level": {}
}分类列表
GET /api/v1/upstream/categories
{
"ok": true,
"categories": [
{
"id": 1001,
"parent_id": 0,
"slug": "category-1001",
"name": { "zh-CN": "社交账号", "en": "社交账号" },
"sort_order": 0
}
]
}商品列表
GET /api/v1/upstream/products?page=1&page_size=50&include_inactive=false
{
"ok": true,
"items": [
{
"id": 2001,
"slug": "product-2001",
"title": { "zh-CN": "示例商品", "en": "示例商品" },
"description": { "zh-CN": "商品简介", "en": "商品简介" },
"content": { "zh-CN": "商品详情 Markdown 或 HTML", "en": "商品详情 Markdown 或 HTML" },
"price_amount": "10.00",
"original_price": "10.00",
"fulfillment_type": "auto",
"is_active": true,
"category_id": 1001,
"delivery_format": "account_password",
"delivery_delimiter": "----",
"logo_url": "https://your-domain.example.com/api/uploads/logo.png",
"images": ["https://your-domain.example.com/api/uploads/logo.png"],
"has_sku": true,
"skus": [
{
"id": 3001,
"sku_code": "1-month",
"spec_values": { "name": "1个月" },
"price_amount": "10.00",
"stock_status": "available",
"stock_quantity": 100,
"is_active": true
}
]
}
],
"total": 1,
"page": 1,
"page_size": 50,
"includes_inactive": false
}下游映射商品时应使用 product.id 和 sku.id,不要依赖商品名。商品详情接口 GET /api/v1/upstream/products/{id} 返回结构与列表中的单个商品一致。
5. 采购订单接口
创建采购订单会立即按绑定用户积分余额扣款,并进入发货流程。
POST /api/v1/upstream/orders
Content-Type: application/json
{
"downstream_order_no": "D202608210001",
"sku_id": 3001,
"quantity": 1,
"callback_url": "https://downstream.example.com/provider/callback",
"trace_id": "trace-abc-001",
"manual_form_data": {}
}| 字段 | 必填 | 说明 |
|---|---|---|
| downstream_order_no | 是 | 下游订单号,同一个 API Key 下必须唯一,最长 128 |
| sku_id | 是 | Provider SKU ID |
| quantity | 是 | 购买数量,范围 1 到 1000000 |
| callback_url | 否 | 订单状态回调 URL,会进行 SSRF 防护 |
| trace_id | 否 | 下游链路追踪 ID,最长 128 |
| manual_form_data | 否 | 预留字段,会参与幂等摘要 |
唯一键是 credential_id + downstream_order_no。相同下游订单号重复请求时,如果 SKU、数量、回调 URL、trace_id、manual_form_data 完全一致,则返回原订单;如果参数不同,返回 409,不重复扣款、不重复发货。
{
"ok": true,
"order_id": 9001,
"order_no": "2026082112345678",
"downstream_order_no": "D202608210001",
"status": "delivered",
"amount": "10.00",
"currency": "CNY",
"trace_id": "trace-abc-001",
"items": [
{
"product_id": 2001,
"sku_id": 3001,
"title": { "zh-CN": "示例商品", "en": "示例商品" },
"quantity": 1,
"unit_price": "10.00",
"total_price": "10.00"
}
],
"fulfillment": {
"type": "card_key",
"status": "delivered",
"payload": "account@example.com----password",
"delivery_data": ["account@example.com----password"]
}
}订单状态包括 processing、delivered、failed。查询订单使用 GET /api/v1/upstream/orders/{id},只能查询当前 API Key 创建的订单。
6. 回调通知
创建订单时传入 callback_url 后,订单状态变化会向该地址发送 POST 回调。回调请求头使用同一套 Dujiao-Next 签名头,签名 path 使用回调 URL 的 path。
{
"event": "order.updated",
"ok": true,
"order_id": 9001,
"order_no": "2026082112345678",
"downstream_order_no": "D202608210001",
"status": "delivered",
"amount": "10.00",
"currency": "CNY",
"timestamp": 1787300000,
"fulfillment": {
"type": "card_key",
"status": "delivered",
"payload": "account@example.com----password",
"delivery_data": ["account@example.com----password"]
}
}回调 URL 只允许 http/https,拒绝本机、内网、链路本地、云元数据地址,以及解析到受限地址的域名。
7. 错误码
| HTTP | error_code | 说明 |
|---|---|---|
| 400 | bad_request | 请求参数错误 |
| 401 | unauthorized | API Key、时间戳或签名错误 |
| 409 | idempotency_conflict | 同一下游订单号重复提交但参数不一致 |
| 400/404 | product_unavailable | 商品不可售 |
| 400 | sku_unavailable | SKU 不存在或不可售 |
| 400 | insufficient_stock | 库存不足 |
| 400 | insufficient_balance | 余额不足 |
| 413 | request_too_large | 请求体超过 1MB |
| 429 | rate_limited | Provider API 触发限流 |
| 500 | internal_error | 服务端内部错误 |
8. 下游同步建议
- 映射键使用
source_type=ORION_KEY、external_product_id=product.id、external_sku_id=sku.id。 - 上游价格上涨且高于本地售价时,应自动抬价到不亏损;上游价格下降时,不自动降低本地售价。
- 库存按
stock_quantity同步,最终能否发货以采购接口结果为准。 - 如果下游启用同步上下架,按上游
is_active复用本地上架/下架行为。 - 图片建议首次导入或管理员恢复默认图时下载到下游本地存储,普通定时同步不要重复下载未变化图片。
- 保存
delivery_format和delivery_delimiter,用于下游解析和展示卡密。
母站管理员关闭图片暴露后,Provider API 的 logo_url 返回空字符串,images 返回空数组,content 中的 Markdown 图片和 HTML img 会被移除。该开关不影响母站自己的前台展示。
9. 上线前检查清单
- API Key 已启用,Secret 未泄露
- 下游服务器时间误差小于 60 秒
- 创建订单必须传 downstream_order_no
- 同一下游订单号重试参数必须一致
- processing 状态不要换新订单号反复采购
- 回调地址必须是安全公网 URL
- 下游验证回调签名后再处理发货
- 下游售价不得低于上游成本
- 日志不打印 Secret、完整签名头和卡密明文
- 请求体控制在 1MB 内
当前实现边界:不支持订单取消;不提供独立 API 客户余额体系;不提供 IP 白名单;不使用 nonce;金额币种为 CNY;商品详情内容按管理员填写内容透传,可能是 Markdown,也可能包含 HTML。
