开发者/快速开始
通用约定
适用于全部 7 个接口的规则。
#请求
- 接口地址:正式环境
https://b2b.cardv.net/api/v1,沙盒https://sandbox.cardv.net/api/v1。 - 路径末尾不要加斜杠:用
/api/v1/orders,不要用/api/v1/orders/。 - 请求体用 UTF-8 编码的 JSON,并设置
Content-Type: application/json。 - 金额用字符串传递,例如
"9.2500",避免浮点误差。 - 请设置能识别你系统的
User-Agent,例如AcmeShop-CardV/1.4。
#金额与时间
- 金额是保留 4 位小数的字符串,例如
"merchant_price": "9.2500"。 - 请用十进制(Decimal)类型读取金额,不要用浮点数。
- 你以钱包币种付款(即
GET/account返回的default_currency,目前为 USD)。 face_currency是卡面币种,可能和钱包币种不同。- 计算成本一律使用
merchant_price。price_label这类字段只用于展示。 - 所有时间都是 UTC,ISO 8601 格式,例如
2026-09-29T08:15:30.123456Z。 - 请用标准的 ISO 8601 解析器,秒的小数位数可能不固定。
- 签名用的
X-Timestamp是 Unix 时间(秒)。
#编号
| 编号 | 示例 | 说明 |
|---|---|---|
| 商户号(Merchant ID) | M00000001 | 永久不变。 |
| SKU 编号 | S000456 | 报价和下单时使用。 |
| 商品编号 | P000123 | SKU 所属的商品。 |
| CardV 订单号 | O-00001234 | 查询订单时使用。 |
| 商户订单号 | SHOP-10001 | 即 external_order_id,1–120 个字符,不能重复。 |
- 编号请按文本保存,不要解析其中的数字,长度以后可能增加。
- 订单还有一个数字
id,请不要使用,统一用order_id。 - 商户订单号建议只用
A–Z a–z 0–9 - _ .这些字符。
#分页
只有 GET/skus 需要分页,通过 limit 和 offset 控制:
GET /api/v1/skus?limit=100&offset=200{"count": 1234, "limit": 100, "results": ["..."], "filter_options": {}}limit默认 100,最大 500,超过 500 按 500 处理。count是符合条件的总数。持续翻页,直到offset达到count。limit或offset为负数或不是数字时,返回 HTTP 400。- 筛选值不存在时返回空列表,不会报错。
#频率限制
默认每分钟 60 次请求,按整个商户账户计算,所有 API Key 和后台用户共用这个额度。你的账户等级可能有不同的额度。
每分钟从整点秒
:00开始计算,被拒绝的请求也计入次数。超过限制时返回 HTTP 429,并带上
Retry-After请求头(需要等待的秒数):{"detail": "Merchant API rate limit exceeded. Expected available in 23 seconds."}避免超限的方法:缓存商品列表;用 Webhook 代替频繁轮询;每次遇到 429 后适当延长等待时间。
#错误
先看 HTTP 状态码,再看 JSON 响应体。响应体里的字段名告诉你出了什么问题,不要依赖错误信息的具体文字。
认证、权限、不存在和频率超限类错误使用 detail 字段:
{"detail": "Order not found."}下单和报价类错误会指明具体字段:
{"balance": "Insufficient available balance."}订单行格式错误时,按 items 中的顺序逐行给出错误:
{"items": [{}, {"quantity": ["Ensure this value is greater than or equal to 1."]}]}| 错误字段 | 出现在 | 怎么处理 |
|---|---|---|
detail | 任意接口 | 参考下方的状态码说明。 |
items | POST/orders | 修正订单行;如果是价格变了,请重新报价。 |
balance | POST/orders | 在商户后台加款。 |
risk | POST/orders | 超过了订单限额,请联系 CardV。 |
external_order_id | POST/orders | 商户订单号缺失、过长,或已被另一笔订单使用。 |
wallet | POST/orders | 钱包未启用,请联系 CardV。 |
quantity、amount | 报价 | 超出范围或不是数字。 |
limit、offset | GET/skus | 不是有效的数字。 |
少数错误不是 JSON 格式:
- HTTP 403 且内容是纯文本(例如
error code: 1010),来自 CardV 的网络防护层,说明请求根本没有到达 CardV。请把你的服务器 IP 和User-Agent发给 CardV。 - 路径不存在(404)或代理层错误(5xx)时,可能返回 HTML。
记录错误日志时,切勿记录 API Key、签名或卡密。
#HTTP 状态码
| 状态码 | 含义 | 是否重试 |
|---|---|---|
| 200 | 成功。对 POST/orders 来说,表示订单之前已存在。 | 不需要 |
| 201 | 创建了新订单。 | 不需要 |
| 400 | 请求被拒绝,没有扣款。 | 修正后再试 |
| 403 | 凭证、签名、IP 有问题,或该接口只能在后台使用。 | 修正后再试 |
| 404 | 不存在,或对你的账户不开放。 | 否 |
| 405 | 这个路径不支持该请求方法。 | 否 |
| 429 | 请求过于频繁。 | 等待 Retry-After 后再试 |
| 5xx 或超时 | 服务器或网络问题,订单可能已经创建。 | 是,见下文 |
对 POST/orders 重试时,只能用相同的内容和相同的商户订单号。详见重试流程。
#响应内容
brand_logo_url和image_url是 CardV 托管图片的完整地址,没有时为""。这些图片可公开访问,也可以缓存。- 订单里的
invoice_url和delivery_file_url是/orders/O-00001234/invoice这样的路径,暂时没有内容时为""。它们只能在商户后台打开,用 API Key 访问会返回 HTTP 403。发票和卡密 CSV 请到商户后台下载。
#兼容性
- 遇到不认识的字段请直接忽略。CardV 新增字段时不会升级 API 版本。
- 以后可能出现新的状态值。遇到不认识的状态,一律按"尚未完成"处理。
- 不要依赖 JSON 字段的顺序或错误信息的措辞。
接入遇到问题?请发送邮件至 [email protected],并附上 Merchant ID 与订单号或请求 ID。