批量采购 API 完整接口文档

机器可读契约(英文描述)以 openapi.json 为准,agent 可从 llms.txt 开始。

AIBulk 开发者 / 批量采购 API

Base URL:https://aibulk.uk/api。本文档里的接口路径(/products、/orders …)相对于 https://aibulk.uk/api/wholesale/v1,例如 GET https://aibulk.uk/api/wholesale/v1/products;OpenAPI 里的路径(/wholesale/v1/...)相对于 https://aibulk.uk/api。https://api.aibulk.uk 是等价别名(如 https://api.aibulk.uk/wholesale/v1/products),长期可用。机器可读契约以 https://aibulk.uk/api/openapi.json 为准,给 agent 的接入指南是 https://aibulk.uk/api/llms.txt,每次契约变更都按日期记在变更日志。本文档的在线版本在 aibulk.uk/developers/api,概览与代码示例在 aibulk.uk/developers。

通用约定

所有接口需携带在用户中心生成的 API Key:

Authorization: Bearer awk_xxxxxxxx...
  • 金额是最多两位小数的十进制字符串(如 "22.00"),不要用浮点数。
  • 默认限流 300 次/分钟;响应返回 X-RateLimit-Limit 与 X-RateLimit-Reset(当前窗口结束的 Unix 秒),429 另带 Retry-After。X-RateLimit-Remaining 只在部分接口返回,请按 429 + Retry-After 退避,不要依赖它。
  • 每个响应带 X-Request-Id。错误体也会尽量返回 requestId,排障时请一并提供。
  • 错误按稳定的 error 码分支,不依赖中文 message。部分冲突还会返回 details,5xx 会标记 retryable: true。完整清单见下文「错误码一览」。
  • 通过 API 出的兑换码不设有效期。payment=intent 订单与充值单约 15 分钟未支付即过期。USDC 充值按 1:1 记入 USDT 余额。

兼容性约定

  • 变更只做加法:字段和接口不改名、不删除。响应随时可能新增字段,不认识的字段请忽略。
  • 枚举值会增加:status、stockMode、deliveryType、deliveryMode、availabilityStatus、fulfillmentStatus、错误码和 webhook 事件名都可能出现新值。不要按封闭枚举解析:遇到不认识的值按「不支持」处理(跳过该商品,或把该订单转人工),不要让整个响应解析失败——一个未知的 stockMode 不应拖垮整份商品目录。
  • 文档标为可空的字段可能为 null。尤其 deliveryType=direct_code 时 redeemUrl 为 null;余额支付的 direct_code 订单在交付完成前可能返回 paid 且 codes=[]。
  • 每次契约变更都按日期和契约版本(openapi.json 的 info.version)记在变更日志。

支付合规

  • 2026 年 8 月起,币安分批封禁与 17 家受制裁平台(含 HTX、BitPapa、EXMO、Rapira、Aifory Pro、ABCeX、WhiteBird、Shelbit、Aban Tether、A7 等)的交易,与其直接或间接发生资金往来的钱包可能被冻结或因合规审查被扣留资金,见币安官方公告。
  • 请仅使用与上述实体及其关联地址无资金往来的钱包完成充值与单笔支付;此类地址导致的冻结、扣审或损失由付款方自行承担。
  • 本平台不与受制裁实体发生任何形式的关联。

等级与定价

用户等级 Lv1–Lv5 按“累计消费 + 当前余额”自动升级,只升不降。网页、REST API 和 MCP 统一按商品对应等级价结算;GET /products 的 price 是当前调用者单价。

推荐下单流程

  1. GET /products 取得商品、当前单价和履约状态。下单请使用稳定的 id,不要用 slug。
  2. 大额下单前调用 GET /products/:id/availability?qty=N。
  3. POST /orders 时携带自己的唯一 externalOrderId;网络异常、超时或 5xx 重试必须复用原值和相同商品/数量。
  4. 如不能接受静默调价,把最新报价(GET /products 的 price 或 availability 的 unitPrice)作为 expectedUnitPrice 提交;价格变化返回 409 price_changed 和最新价格。
  5. payment=balance 即时扣款,平台兑换码通常同步返回;直接发卡商品可能先返回 paid,请查询原订单或等待 Webhook。payment=intent 返回结账地址,付款后使用同一查询流程。
  6. 按 deliveryType 交付:redemption 发送 code + redeemUrl;direct_code 发送实际礼品卡 code,redeemUrl=null,无需平台兑换。

0.01 USDT 真实下单测试

测试商品 API 下单测试商品(无实际权益),ID:prod_api_order_test。商城与商品列表不展示,请直接使用此 ID。

  • 正式环境真实扣款,所有等级均为 0.01 USDT/件;不是免费沙箱。
  • 仅支持 REST API、payment=balance、qty=1,需有至少 0.01 USDT 余额;不支持网页、MCP 或单笔在线支付购买。
  • 可验证余额扣款、发码、订单查询、externalOrderId 幂等和已配置的 order.delivered Webhook。沿用 API 限流。
  • 返回的是测试码,不含实际权益,不可转售为订阅权益。在兑换站提交返回 400 test_code_only;不用于测试实际订阅到账。
  • 测试码可以提交给 POST /redemptions(redeemInfo 任意,建议 {}):提交即在同一事务内完成(status=fulfilled,deliverable 为固定文案),并推送 redemption.fulfilled。用它可以花 0.01 USDT 跑通「下单 → 代客兑换 → 轮询 / Webhook」整条链;重复提交同一测试码返回 409 already_redeemed。
  • 相同订单重试须复用 externalOrderId 和相同参数,不重复扣款;换一个 ID 会创建新订单并再次扣款。
curl https://aibulk.uk/api/wholesale/v1/orders \
  -H "Authorization: Bearer $AIBULK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"externalOrderId":"integration-test-001","productId":"prod_api_order_test","qty":1,"payment":"balance","expectedUnitPrice":"0.01"}'

可先调用 GET /products/prod_api_order_test/availability?qty=1 检查是否可购。数量不为 1 返回 400 api_test_quantity;不支持的购买渠道或支付方式返回 400 api_test_balance_only。

延迟交付测试(礼品卡分支)

prod_api_order_test_delayed(API 延迟交付测试商品,无实际权益)用来测礼品卡分支:先 paid、codes=[],随后 order.delivered,再用 GET /orders/:id 取码。规则同上:商品列表不展示,所有等级真实扣款 0.01 USDT,仅 REST API payment=balance、qty=1。

  • POST /orders 返回 status=paid、codes=[]、deliveryType=direct_code、redeemUrl=null、fulfillmentStatus=processing。
  • 约 1–2 分钟后(下单后至少 60 秒)订单变为 delivered,带一张 TEST-XXXX-XXXX-XXXX 形式的测试码;配置了 Webhook 会收到 order.delivered(重试规则与真实订单相同)。
  • 测试码没有价值,不要交付给客户;它不是平台兑换码,兑换站与 POST /redemptions 都会拒绝。
  • 没有模拟 fulfillmentStatus=needs_attention / order.delivery_attention 的测试商品,请按文档里的事件结构处理这一分支。
curl https://aibulk.uk/api/wholesale/v1/orders \
  -H "Authorization: Bearer $AIBULK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"externalOrderId":"delayed-test-001","productId":"prod_api_order_test_delayed","qty":1,"payment":"balance","expectedUnitPrice":"0.01"}'

直接交付礼品卡 code

商品与订单的 deliveryType 区分交付方式:redemption 沿用平台兑换码 + 兑换网址;direct_code 直接交付礼品卡 code,redeemUrl 为 null,无需经过平台兑换站。

美区 App Store 礼品卡、Roblox 美元礼品卡与 Robux 兑换码属于 direct_code。余额付款或单笔支付完成后,订单可能暂时返回 status: "paid"、codes: [],表示正在取码。请用原订单 ID 查询或等待 order.delivered Webhook;全部数量交付后状态才变为 delivered,codes[] 为实际卡码。不要为等待取码创建新订单或更换幂等 ID。订单下载同样只包含实际卡码。美区 Apple 卡仅用于美国地区 Apple 账户。

分组 productGroupId 面额示例 faceCurrency region 官方兑换入口
apple-gift-card-us "25.00" USD US https://apps.apple.com/redeem
roblox-gift-card-us "25.00" USD US https://www.roblox.com/redeem
robux "800"(Robux 数量) ROBUX GLOBAL https://www.roblox.com/redeem

多面额礼品卡(Apple Gift Card / Roblox / Robux)

商品目录兼容原来的独立 SKU 列表,每行仍可通过 id 下单。新增字段用于把多个面额合并展示:

字段 示例 含义
productGroupId apple-gift-card-us 展示分组,不能作为下单 productId
denomination "25.00" / "800" 礼品卡实际面额,按 faceCurrency 计的十进制字符串
faceCurrency USD / ROBUX 面额单位,与支付币种区分
region US / GLOBAL 卡片地区
price "24.99" 当前账户实际购买单价
stockMode limited 库存有限;数量需要单独检查,stock 为 null

普通商品的四个分组/面额字段为 null。相同 productGroupId 的 SKU 可组成面额选择器;仅显示 inStock && available 的选项,按面额数值排序。购买时传选中行的 id,不要传页面 slug,也不要额外传 denomination 来代替选择 SKU。

limited 商品的 availability?qty=N 会读取最新可购情况并扣除本平台待处理订单;下单在扣款或创建支付链接前再次校验,并防止本平台并发请求重复占用余量。可购性查询本身不预留库存,付款前后仍可能缺货。409 insufficient_stock、stock_unavailable 或 fulfillment_unavailable 表示本次未扣款、未创建支付链接;减少数量或稍后重新检查。网络超时或结果不明时先按原 externalOrderId 查单。

示例:选择 $25 面额并使用余额购买一张。API_KEY 从自己的安全配置读取,externalOrderId 必须由业务系统持久化,超时重试沿用原值。

const base = "https://aibulk.uk/api/wholesale/v1";
const headers = { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json" };
async function api(path, init = {}) {
  const response = await fetch(base + path, { ...init, headers });
  const data = await response.json();
  if (!response.ok) throw Object.assign(new Error(data.message), { status: response.status, data });
  return data;
}
const { products } = await api("/products");
const selected = products.find(p => p.productGroupId === "apple-gift-card-us"
  && p.denomination === "25.00" && p.faceCurrency === "USD" && p.region === "US"
  && p.inStock && p.available);
if (!selected) throw new Error("This denomination is unavailable");
const quote = await api(`/products/${encodeURIComponent(selected.id)}/availability?qty=1`);
if (!quote.available) throw new Error("This quantity is unavailable");
const result = await api("/orders", {
  method: "POST",
  body: JSON.stringify({ externalOrderId, productId: selected.id, qty: 1,
    payment: "balance", expectedUnitPrice: quote.unitPrice })
});
// Persist result.orderId. Reuse it for GET /orders/:id and webhook reconciliation.
// payment=intent instead returns checkoutUrl; inspect the same order after payment.

直接发卡订单在创建响应、订单列表及订单详情中还提供:

fulfillmentStatus 客户端行为
awaiting_payment 等待完成付款
processing 每 10–30 秒查询原订单,或等待通知
needs_attention 显示人工处理中,降低轮询频率,凭原订单号联系客服;不要重复购买
delivered 将详情的 codes[] 交付给买家
expired 未支付过期;已发起付款但结果不明时先核对原单
refunded 订单已记录退款状态

fulfilledQuantity 是已取得的卡码数量;部分完成时仍不返回任何卡码,整单完成后一起交付。needs_attention 同时返回 errorCode: "delivery_needs_attention"、resolution: "manual_review"。这表示客服核对剩余交付及退款,不代表退款已经到账;已取得卡码或结果不明的订单不会自动整单退款。支付状态 paid 与履约状态分开判断。交付后按上表给买家对应的官方兑换入口。

异常通知为 order.delivery_attention,使用与 order.delivered 相同的签名、重试及 eventId 去重规则;每个订单首次进入人工处理时发送一次。通知可能乱序,到达后查询原订单确认最新状态。

{
  "eventId": "order:example-order:order.delivery_attention",
  "event": "order.delivery_attention",
  "timestamp": 1787500000,
  "orderId": "example-order",
  "externalOrderId": "your-order-123",
  "productId": "selected-sku-id",
  "qty": 2,
  "deliveryType": "direct_code",
  "fulfillmentStatus": "needs_attention",
  "fulfilledQuantity": 1,
  "errorCode": "delivery_needs_attention",
  "resolution": "manual_review",
  "codes": [],
  "redeemUrl": null
}

接口

GET /products — 商品与报价

返回商品、当前用户单价、库存模式及履约状态:

{
  "products": [{
    "id": "prod_chatgpt_plus",
    "name": "ChatGPT Plus (1个月)",
    "price": "21.56",
    "currency": "USDT",
    "stockMode": "on_demand",
    "availabilityStatus": "available",
    "deliveryMode": "automatic"
  }]
}

常用字段说明:

  • id:稳定商品 ID,用于下单和可购性检查。
  • slug:展示/SEO 标识,可能变化,不建议作为程序化下单依据。
  • price:当前 API Key 对应用户等级的单价。
  • stockMode=inventory:受平台自有库存数量约束;stock 最多缓存 60 秒且会展示封顶。
  • stockMode=on_demand:按兑换请求履约,stock=null。
  • stockMode=limited:库存有限、数量不公开,stock=null;按所选数量调用可购性检查,下单时再次校验。
  • deliveryMode=automatic 表示兑换后自动履约;manual / manual_fallback 表示可能需要人工处理。
  • availabilityStatus=degraded 表示自动路线不可用、将人工兜底,不代表即时自动交付。
  • redeemFields / redeemFieldsEn:兑换时终端用户必须提供的资料(与兑换站 check 返回一致;direct_code 礼品卡为 [])。代客兑换的下游请在采购前按此收集资料,key 即 redeemInfo 的键名。

GET /products/:id 返回同一结构的单个商品(不走列表缓存),未知或下架商品返回 404 not_found。例如 Claude Pro:

{
  "id": "prod_claude_pro",
  "price": "22.00",
  "deliveryType": "redemption",
  "redeemFields": [
    { "key": "account_id", "label": "Claude Organization ID", "type": "text", "required": true }
  ]
}

GET /products/:id/availability?qty=50 — 可购性与报价

{
  "productId": "prod_chatgpt_plus",
  "qty": 50,
  "available": true,
  "unitPrice": "21.56",
  "stockMode": "on_demand",
  "availabilityStatus": "available",
  "deliveryMode": "automatic",
  "checkedAt": 1787500000
}

该结果是本平台当前库存/路由配置的判定,不等于上游服务 SLA 保证。

GET /balance — 余额查询

{ "balance": "1250.00", "currency": "USDT" }

POST /topup — 幂等充值

新接入必须提供 externalTopupId,也可改放到 Idempotency-Key 请求头。超时重试必须复用同一个值:

{ "externalTopupId": "topup-20260824-001", "amount": "500.00", "currency": "USDT" }
{
  "orderId": "...",
  "externalTopupId": "topup-20260824-001",
  "amount": "500.00",
  "status": "pending",
  "checkoutUrl": "https://checkout.tariapay.com/...",
  "reused": false
}

同一个幂等键换金额或币种会返回 409 idempotency_conflict。充值单约 15 分钟未支付即过期;到账后余额以 GET /balance 为准,也可订阅 topup.credited。USDC 充值按 1:1 记入 USDT 余额。

每个账号每小时最多发起 20 次充值请求(幂等重放也计数,用户中心、REST API 与 MCP 共用额度),同时最多存在 5 笔未支付充值单,超出返回 429 too_many_pending_topups:先完成支付或等它们过期再建新单。

兼容窗口内,旧客户端只传 amount / currency 仍可建单,但响应会带 HTTP Warning: 299 和 idempotencyWarning;这种请求不具备安全重试能力。请尽快补上幂等键,未来主版本会改为强制要求。

POST /orders — 幂等批量下单

{
  "externalOrderId": "your-order-123",
  "productId": "prod_chatgpt_plus",
  "qty": 50,
  "payment": "balance",
  "expectedUnitPrice": "21.56"
}

余额模式即时返回:

{
  "orderId": "...",
  "externalOrderId": "your-order-123",
  "amount": "1078.00",
  "status": "delivered",
  "codes": ["AB4K-9XQ2-..."],
  "redeemUrl": "https://redeemhub.uk",
  "reused": false
}

单笔支付模式返回 checkoutUrl(兼容字段 paymentUrl 也可能出现),此时订单通常是 pending,不会返回 code:

{
  "orderId": "...",
  "externalOrderId": "your-order-123",
  "amount": "1078.00",
  "status": "pending",
  "checkoutUrl": "https://checkout.tariapay.com/...",
  "paymentUrl": "https://checkout.tariapay.com/...",
  "redeemUrl": "https://redeemhub.uk",
  "reused": false
}

checkoutUrl 只交给付款人,不要写进日志或公开。

用户完成支付并被 Tariapay 确认后,平台开始交付;直接发卡订单可能保持 paid,需要同时检查 fulfillmentStatus。集成方应查询 GET /orders/:id 或接收 order.delivered Webhook,确认全部卡码可用后再向下游发货。超过支付窗口仍未确认的订单会变成 expired;若要重新发起未支付订单,请使用新的 externalOrderId。

余额不足返回 402 insufficient_balance;库存、幂等冲突和价格变化使用 409 及对应错误码。

GET /orders / GET /orders/:id — 订单查询

列表支持 externalOrderId、limit=1..100、cursor,返回:

{ "orders": [], "nextCursor": null, "hasMore": false }

后续页只透传上一页的 nextCursor,不要解析游标;游标无效/过期会返回 400 invalid_cursor。列表行是摘要,不含 codes 与 paymentUrl;详情在 status=delivered 时带 codes。redemption 商品应同时交付 code 与 redeemUrl;direct_code 商品直接交付实际卡码,redeemUrl=null。

字段命名:POST /orders 返回 camelCase(orderId、externalOrderId)。契约 1.5.0 起,订单列表行和详情也带同名 camelCase 字段——orderId、externalOrderId、productId、orderNumber、unitPrice、productName、createdAt、paidAt(充值行另有 externalTopupId)——与原有 snake_case 字段(id、external_order_id、product_id、order_number、unit_price、product_name、created_at、paid_at、topup_external_id)并存、值相同;snake_case 为兼容老客户端保留。新集成请统一用 camelCase,下单与查询共用一套解析。

GET /orders/:id 示例(余额支付的平台兑换码订单):

{
  "orderId": "…",
  "externalOrderId": "your-order-123",
  "productId": "prod_claude_pro",
  "orderNumber": "…",
  "unitPrice": "22.00",
  "productName": "Claude Pro (1个月)",
  "createdAt": 1787500000,
  "paidAt": 1787500000,
  "id": "…",
  "external_order_id": "your-order-123",
  "channel": "wholesale_api",
  "product_id": "prod_claude_pro",
  "order_number": "…",
  "qty": 2,
  "unit_price": "22.00",
  "amount": "44.00",
  "currency": "USDT",
  "status": "delivered",
  "deliveryType": "redemption",
  "created_at": 1787500000,
  "paid_at": 1787500000,
  "product_name": "Claude Pro (1个月)",
  "redeemUrl": "https://redeemhub.uk",
  "paymentUrl": null,
  "codes": ["AB4K-9XQ2-XXXX-XXXX", "CD7M-2PQ8-XXXX-XXXX"]
}

直接发卡订单另带 fulfillmentStatus、fulfilledQuantity、errorCode、resolution(见上文)。paymentUrl 只在 pending 的单笔支付单上返回。

订单状态含义:

  • pending:待支付或等待支付确认;intent 模式此时无 code。
  • paid:支付已确认;直接发卡订单同时检查 fulfillmentStatus,needs_attention 表示需要人工处理。
  • delivered:已出 code,可交付下游。
  • expired:支付窗口超时且未确认;使用新的 externalOrderId 重新下单。
  • refunded:已退款/撤销。

PUT /webhook — 配置通知

仅接受公共 HTTPS 地址;空字符串清除。配置成功返回一次性 secret(重新配置即轮换)。平台先持久化事件,再立即投递;接收方须在 5 秒内返回 2xx,否则按 30 秒起、每次翻倍、封顶 6 小时的间隔重试,最多 10 次。平台不跟随重定向,3xx 按投递失败处理,请直接配置最终地址(含末尾斜杠等细节)。X-AIBulk-Timestamp 是事件创建时间,可据此拒绝过旧的重放。

投递体示例:

{
  "eventId": "evt_...",
  "event": "order.delivered",
  "timestamp": 1787500000,
  "orderId": "...",
  "externalOrderId": "your-order-123",
  "codes": ["..."],
  "redeemUrl": "https://redeemhub.uk"
}

请求头包括:

  • X-AIBulk-Signature: sha256=<HMAC-SHA256(secret, rawBody)>
  • X-AIBulk-Event-Id
  • X-AIBulk-Delivery-Id
  • X-AIBulk-Timestamp

接收方应按 eventId 幂等,并在处理成功后返回 2xx。

  • POST /webhook/test:产生并投递一条持久化测试事件。
  • GET /webhook/deliveries?limit=50&cursor=...:查询投递历史。
  • POST /webhook/deliveries/:id/retry:手工重试失败/取消的记录。

当前事件包括 order.delivered、order.delivery_attention、topup.credited、redemption.fulfilled、redemption.failed 和 webhook.test。

order.delivered 表示所有客户卡码已备齐。redemption 商品不表示终端用户已完成订阅兑换,兑换进度在 redeemUrl 所在兑换站查询,或由下游通过下文的兑换接口 / redemption.* 事件跟踪;direct_code 商品交付实际礼品卡码,无需平台兑换。

POST /redemptions — 服务端代客兑换

适用于自己采购兑换码、再替终端用户完成兑换的下游(例如买家付款后提交 Claude Organization ID,由下游系统直接兑换)。与兑换站的 submit 是同一套校验与状态机,区别只有:

  • 使用同一个 Bearer API Key 鉴权,按 Key 限流(提交 60 次/分钟,查询沿用 300 次/分钟),不按出口 IP。服务器型下游与其他租户共享出口 IP 也不会互相挤兑。
  • 只接受本 Key 所属用户自己订单出的码;其他码一律 404 invalid_code,不区分「不存在」和「不属于你」。direct_code 礼品卡订单无需兑换,其码不在此接口范围内。

请求体的 redeemInfo 键名来自商品的 redeemFields[].key:

{ "code": "AB4K-9XQ2-XXXX-XXXX", "redeemInfo": { "account_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" } }
{ "redemptionId": "6f3c…", "status": "pending", "code": "AB4K-9XQ2-XXXX-XXXX", "orderId": "…" }

履约是异步的:之后轮询 GET /redemptions/:redemptionId,或接收 redemption.fulfilled / redemption.failed。错误码与兑换站一致:

HTTP error 含义
400 missing_field redeemFields 中必填项为空
400 invalid_account_id Claude Organization ID 不是合法 UUID
400 invalid_session_json / invalid_telegram_username 对应商品的资料格式错误
400 account_plan_not_free ChatGPT Session 的实时套餐不是 Free:Go 与 prod_chatgpt_plus 只接当前为 Free 的账号;已有付费套餐的账号请改用 prod_chatgpt_plus_subscribed 的码(码未被占用)
400 test_code_only 测试商品的码不可兑换
404 invalid_code 码无效、已作废,或不是本账号订单出的码
409 already_redeemed 已在处理中或已完成,不能重复提交
409 retry_conflict 上一次失败的尝试仍占用供应商资源,稍后再查询进度/重试
410 code_expired 码已过期
503 session_validation_unavailable ChatGPT Session 预检暂不可用,可重试

GET /redemptions/:redemptionId、GET /redemptions?code=… — 兑换进度

{
  "redemptionId": "6f3c…",
  "code": "AB4K-9XQ2-XXXX-XXXX",
  "orderId": "…",
  "externalOrderId": "your-order-123",
  "productId": "prod_claude_pro",
  "status": "fulfilled",
  "retryable": false,
  "failureCode": null,
  "deliverable": "充值完成:ab***@example.com",
  "createdAt": 1787500000,
  "fulfilledAt": 1787500600
}
  • status:not_redeemed(该码尚未提交,redemptionId=null,仅 ?code= 查询会出现)→ pending → processing → fulfilled | failed。
  • failed 时 retryable=true,可用修正后的 redeemInfo 再次 POST /redemptions 同一个码;failureCode 为 fulfillment_failed(自动履约未完成)或 rejected_by_operator(人工判定失败)。
  • deliverable 仅在 fulfilled 时返回,是脱敏后的完成说明(如充值账号部分打码),不含卡密以外的原文。
  • 处理中时服务端每单最多 60 秒向上游刷新一次,更快的轮询没有收益;建议 30–60 秒一次,或以 Webhook 为主、轮询兜底。
  • 按 redemptionId 查询不属于本账号的兑换单返回 404 not_found。

redemption.fulfilled / redemption.failed 使用与 order.delivered 相同的签名、重试和 eventId 去重规则;每张兑换单每次进入终态发一次(失败后重提会开始新一轮尝试,再次进入终态时再发一次,eventId 不同)。只发给批发 API 订单出码的账号,零售网页单与礼品卡单不发。payload 不含交付内容和提交资料:

{
  "eventId": "redemption:6f3c…:0:redemption.failed",
  "event": "redemption.failed",
  "timestamp": 1787500000,
  "orderId": "…",
  "externalOrderId": "your-order-123",
  "productId": "prod_claude_pro",
  "redemptionId": "6f3c…",
  "code": "AB4K-9XQ2-XXXX-XXXX",
  "status": "failed",
  "failureCode": "fulfillment_failed",
  "retryable": true,
  "fulfilledAt": null
}

redemption.fulfilled 的 status 为 fulfilled、failureCode 为 null、retryable 为 false、fulfilledAt 为完成时间。事件可能乱序或晚于轮询结果到达,收到后以 GET /redemptions/:redemptionId 为准。

GET /transactions — 余额流水

支持 limit、cursor 和 type=topup|purchase|refund|adjust:

{
  "transactions": [{ "type": "purchase", "amount": "-1078.00", "balanceAfter": "172.00", "order_id": "..." }],
  "nextCursor": null,
  "hasMore": false
}

错误码一览

HTTP error 出现在 处理
401 unauthorized 所有接口 Key 缺失或无效;到用户中心重新生成
400 invalid_input 所有接口 参数不合法,看 message
400 invalid_cursor 列表接口 游标失效,从第一页重新开始
404 not_found 商品、订单、兑换单 ID 不存在或不属于本账号
402 insufficient_balance POST /orders 余额模式 充值或减少数量
409 out_of_stock / insufficient_stock / stock_unavailable / fulfillment_unavailable POST /orders 本次未扣款;减少数量或稍后再试
409 price_changed POST /orders 用 details.actualUnitPrice 重新确认后再下单
409 duplicate_order POST /orders 并发撞车,按 externalOrderId 查单
409 idempotency_conflict POST /orders、POST /topup 幂等键被用于不同参数,换新的业务 ID
400 api_test_quantity / api_test_balance_only 测试商品 测试商品只支持 REST、余额、qty=1
404 invalid_code /redemptions 码无效、已作废或不是本账号的
400 missing_field / invalid_account_id / invalid_session_json / invalid_telegram_username POST /redemptions 按 redeemFields 修正资料
400 account_plan_not_free POST /redemptions 换用当前为 Free 的账号,或改买 prod_chatgpt_plus_subscribed
409 already_redeemed / retry_conflict POST /redemptions 转入轮询;retry_conflict 稍后再提
410 code_expired POST /redemptions 码已过期(API 出的码不设有效期,一般不会出现)
409 webhook_not_configured POST /webhook/test 先配置 Webhook
429 rate_limited 所有接口 按 Retry-After 退避
429 too_many_pending_topups POST /topup 已有 5 笔未支付充值单;先支付或等约 15 分钟过期
429 too_many_pending_orders POST /orders(intent 模式) 已有 5 笔未支付订单;先支付或等约 15 分钟过期。余额支付的订单即时结算,不计入
502 / 504 payment_provider_error / payment_provider_timeout intent 下单、充值 未留下订单,用同一幂等键重试
503 session_validation_unavailable POST /redemptions ChatGPT Session 预检暂不可用,可重试
500 internal_error 所有接口 retryable: true,带 requestId 联系支持

重试建议

  • 创建订单超时/网络断开/5xx:用同一个 externalOrderId、同一个 productId、同一个 qty 重试,或用 GET /orders?externalOrderId=... 找回原单。
  • 返回 duplicate_order:通常是并发重试撞车,查询 GET /orders?externalOrderId=...。
  • 返回 idempotency_conflict:同一个幂等 ID 被用于不同商品/数量/金额;不要继续重试,换新的业务 ID。
  • 返回 price_changed:展示/确认最新 details.actualUnitPrice 后,用新的业务决策继续。
  • 返回 rate_limited:按 Retry-After 退避。
  • 代客兑换返回 retry_conflict:不要换码重买,30–60 秒后查询 GET /redemptions?code=…,待 status=failed 且 retryable=true 再重提。

兑换站交付说明

以下适用于 deliveryType=redemption 的平台兑换码,请把 code 与 redeemUrl 一起发给终端用户。direct_code 礼品卡直接交付实际卡码,不执行以下平台兑换步骤:

  1. 终端用户打开 redeemUrl。
  2. 输入/粘贴 code。
  3. 按页面要求提交该商品所需的兑换信息。
  4. 若是自动履约商品,兑换后可能需要数分钟处理;终端用户可在兑换站查询状态。

兑换站是中性品牌域名,适合转售场景。不要只交付 code 而遗漏 redeemUrl。

若下游自己收集资料并替终端用户兑换,改用上文的 POST /redemptions 与 GET /redemptions/:redemptionId,不要用兑换站的公开接口(那组接口按客户端 IP 限流,服务器出口 IP 与其他租户共享时很快会被限)。

MCP

https://aibulk.uk/api/mcp(别名 https://api.aibulk.uk/mcp)使用相同 Bearer Key。工具包括 list_products、check_availability、get_balance、create_topup、purchase_codes、get_order、list_orders、list_transactions。

Grok 兑换账号

Super Grok 和 Grok Heavy 兑换需提供完整 Session JSON,或其中 session.userId 的 UUID。登录 Grok 后打开 Grok Session 获取;不要使用 sessionId、xUserId 或邮箱作为充值账号。

使用兑换 API / MCP 时,先调用 check 并使用返回的 redeemFields。grok_user_id 字段可传入 UUID 字符串,或包含 status: "authenticated" 与 session.userId 的完整 JSON 字符串。页面会展示识别出的 userId,提交前请确认目标账号。

前后端校验输入格式,服务端只保留归一化后的 userId。格式错误会在占用兑换码前返回 400,修正后可重试。此检查不证明账号实时登录状态或充值资格;提交成功表示兑换申请已受理,不代表订阅已到账。

Changelog

契约版本即 openapi.json 的 info.version;日期为上线日期(UTC)。新增枚举值、字段变为可空这类「加法」也会列出——它们曾让严格解析的客户端出错,见兼容性约定。

2026-10-22(版本号未变)

  • intent 模式下单:每账户同时最多 5 笔未支付订单(新错误 429 too_many_pending_orders);付款或约 15 分钟过期后释放,余额支付不计入。

2026-10-19(版本号未变)

  • 变更:所有 ChatGPT 商品都只收 ChatGPT Session。prod_chatgpt_pro_20x(Pro 200)与 prod_chatgpt_pro_500(Pro 500)的兑换资料由 account_email 改为 session_json,与 prod_chatgpt_plus、prod_chatgpt_pro_5x 相同(登录后打开 https://chatgpt.com/api/auth/session 复制完整 JSON);两者仍为人工交付。只传 account_email 时 POST /redemptions 返回 400 missing_field,码不会被占用。请按 GET /products/:id 返回的 redeemFields 提交。

1.5.1 — 2026-10-12

  • 新增:商品 prod_chatgpt_plus_subscribed(ChatGPT Plus 已订阅账号),适用于已有 Plus、Go 等付费套餐的 Personal 账号,当前为 Free 的账号也可用;兑换资料与 prod_chatgpt_plus 相同(session_json)。
  • 变更:prod_chatgpt_plus 只接当前为 Free 的 Personal 账号。付费套餐账号兑换时 POST /redemptions 返回 400 account_plan_not_free,码不会被占用,可换账号重提。
  • 文档:兑换错误码补充 account_plan_not_free(Go 此前已会返回)。

1.5.0 — 2026-10-10

  • 修复:OpenAPI servers 改为 https://aibulk.uk/api(主)和 https://api.aibulk.uk(等价别名)。此前从 https://aibulk.uk/api/openapi.json 取到的 servers 是不带 /api 的售卖站主机,生成的客户端会在售卖站主机上请求 /wholesale/v1/... 并拿到 404 页面。用旧 spec 生成过客户端的,请把 base URL 改成上面任一地址。
  • 修复:API 的 llms.txt 曾指向售卖站主机上不带 /api 的 /openapi.json(404)和 /mcp(405);正确地址是 https://aibulk.uk/api/openapi.json 与 https://aibulk.uk/api/mcp。两份 llms.txt 现在都写明 REST Base URL 并链接本变更日志。
  • 新增:延迟交付测试商品 prod_api_order_test_delayed(0.01 USDT、REST 余额、每单 1 件):先 paid、codes=[],约 1–2 分钟后交付 TEST- 测试码并发 order.delivered,见延迟交付测试。
  • 新增:GET /orders 列表行与 GET /orders/:id 增加 camelCase 别名 orderId、externalOrderId、productId、orderNumber、unitPrice、productName、createdAt、paidAt,充值行另有 externalTopupId;snake_case 字段不变。
  • 文档:写明上面的兼容性约定(只做加法、枚举会增加、可空字段)与本变更日志。

2026-10-08(版本号未变)

  • 充值限制为每账户每小时 20 笔、同时最多 5 笔未支付(新错误 429 too_many_pending_topups)。

1.4.0 — 2026-10-06

  • 新增服务端代客兑换:POST /redemptions、GET /redemptions/:redemptionId、GET /redemptions?code=;webhook redemption.fulfilled / redemption.failed;GET /products/:id;商品字段 redeemFields / redeemFieldsEn 写入 spec。新增兑换错误码 invalid_account_id。
  • prod_api_order_test 的码可提交到 POST /redemptions,立即完成(无实际权益)。

1.3.1 — 2026-09-28

  • 已有变体字段出现新值:faceCurrency 可为 ROBUX,region 可为 GLOBAL(Roblox 与 Robux 直发码商品)。

2026-09-25(版本号未变)

  • Webhook 投递不再跟随重定向,3xx 记为一次失败;请登记最终地址。

1.3.0 — 2026-09-13

  • 新增直接交付礼品卡:deliveryType(redemption | direct_code)。direct_code 的 redeemUrl 为 null;余额订单可能先返回 status=paid、codes=[],全部卡到手后变为 status=delivered 并发 order.delivered。
  • stockMode 新增取值 limited(库存有限、不公开精确数量;按目标数量调 availability)。
  • 订单新字段 fulfillmentStatus、fulfilledQuantity、errorCode、resolution;新 webhook order.delivery_attention;变体字段 productGroupId、denomination、faceCurrency、region;新错误码 stock_unavailable、fulfillment_unavailable。
  • 这一版扩充了已有枚举、让 redeemUrl 可为空,但没有提前通知,严格解析的客户端因此出错。1.5.0 起兼容性约定写明在文档里。

1.2.1 — 2026-09-08

  • 新增 0.01 USDT 联调测试商品 prod_api_order_test(仅 REST 余额支付、每单 1 件);deliveryMode 新增 test_code_only;新错误 api_test_balance_only、api_test_quantity。

2026-09-01(版本号未变)

  • 商品新增 nameEn 与 redeemFieldsEn(英文标题与兑换字段标签)。

1.2.0 — 2026-08-31

  • 写明出站 webhook 目录(order.delivered、topup.credited、webhook.test)、签名与重试规则,每个操作声明 429;补全商品 schema(retailPrice、inStock、available)。

1.1.0 — 2026-08-25

  • 新增充值幂等 externalTopupId / Idempotency-Key、游标分页(limit、cursor、nextCursor、hasMore)、expectedUnitPrice 与 409 price_changed、availabilityStatus / deliveryMode、错误体 requestId / retryable,以及 webhook 投递记录与重试接口。

1.0.0 — 2026-08-14

  • 首个公开契约。