开发者/快速开始

通用约定

适用于全部 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报价和下单时使用。
商品编号P000123SKU 所属的商品。
CardV 订单号O-00001234查询订单时使用。
商户订单号SHOP-10001即 external_order_id,1–120 个字符,不能重复。
  • 编号请按文本保存,不要解析其中的数字,长度以后可能增加。
  • 订单还有一个数字 id,请不要使用,统一用 order_id。
  • 商户订单号建议只用 A–Z a–z 0–9 - _ . 这些字符。

#分页

只有 GET/skus 需要分页,通过 limit 和 offset 控制:

HTTP
GET /api/v1/skus?limit=100&offset=200
JSON
{"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 请求头(需要等待的秒数):

    JSON
    {"detail": "Merchant API rate limit exceeded. Expected available in 23 seconds."}
  • 避免超限的方法:缓存商品列表;用 Webhook 代替频繁轮询;每次遇到 429 后适当延长等待时间。

#错误

先看 HTTP 状态码,再看 JSON 响应体。响应体里的字段名告诉你出了什么问题,不要依赖错误信息的具体文字。

认证、权限、不存在和频率超限类错误使用 detail 字段:

JSON
{"detail": "Order not found."}

下单和报价类错误会指明具体字段:

JSON
{"balance": "Insufficient available balance."}

订单行格式错误时,按 items 中的顺序逐行给出错误:

JSON
{"items": [{}, {"quantity": ["Ensure this value is greater than or equal to 1."]}]}
错误字段出现在怎么处理
detail任意接口参考下方的状态码说明。
itemsPOST/orders修正订单行;如果是价格变了,请重新报价。
balancePOST/orders在商户后台加款。
riskPOST/orders超过了订单限额,请联系 CardV。
external_order_idPOST/orders商户订单号缺失、过长,或已被另一笔订单使用。
walletPOST/orders钱包未启用,请联系 CardV。
quantity、amount报价超出范围或不是数字。
limit、offsetGET/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。