账单
一张账单对应一次购买:以法币或稳定币计价的价格、有效期,以及顾客选择后确定的支付币种和收款地址。
创建
请求头:Authorization(CP-HMAC)、Idempotency-Key、Content-Type: application/json。
{
"order_id": "ORDER-1001",
"price_amount": "49.99",
"price_currency": "USD",
"allowed_assets": ["USDT-TRON", "USDC-BASE", "BTC"],
"return_url": "https://shop.example/orders/ORDER-1001",
"expires_in_seconds": 1800,
"metadata": { "user_id": "42", "plan": "pro" }
}| 字段 | 必填 | 规则 |
|---|---|---|
order_id | 是 | 1–128 个字符,在商户范围内唯一(重复将返回 409 duplicate_order) |
price_amount | 是 | 大于 0 的十进制字符串,小数点后最多 18 位 |
price_currency | 是 | USD、EUR、USDT 或 USDC |
allowed_assets | 否 | 最多 30 个资产 id(GET /v1/assets)。留空表示所有可用资产。账单实际采用与可用资产的交集;交集为空则返回 422 invalid_allowed_assets |
return_url | 否 | https://…,用于「返回商店」按钮 |
expires_in_seconds | 否 | 300–86 400,默认 1800(30 分钟) |
metadata | 否 | 最多 20 个键,键名格式 [A-Za-z0-9_.-]{1,64},值最长 500 个字符;会在账单中原样返回 |
响应 201:
{
"id": "inv_x7k2…",
"order_id": "ORDER-1001",
"status": "created",
"price_amount": "49.99",
"price_currency": "USD",
"allowed_assets": ["USDT-TRON", "BTC"],
"checkout_url": "https://pay.coinetic.money/pay/inv_x7k2…#t=…",
"return_url": "https://shop.example/orders/ORDER-1001",
"expires_at": "2026-10-12T15:30:00Z",
"created_at": "2026-10-12T15:00:00Z",
"quote": null,
"paid_amount": "0", "outstanding_amount": "0", "overpaid_amount": "0",
"refunded_amount": "0", "refundable_amount": "0",
"payments": [],
"metadata": { "user_id": "42", "plan": "pro" },
"livemode": true
}price_amount以规范形式返回,去掉末尾的零:传入"3.00"会返回"3"。请按十进制数比较金额,不要用 float,也不要逐字节比较。checkout_url在#之后包含支付页面的令牌。请勿将其写入日志或公开。livemode: false表示沙盒账单。生产环境的商店应拒绝此类账单。
哪些资产会出现在账单中
资产可用的条件是:Coinetic 已启用该资产,您在该网络上有有效的收款钱包,并且您没有在后台(「设置」→「可支付资产」)中将其排除。每种资产都有最低金额(GET /v1/assets 中的 min_amount):如果账单金额折算成该资产后低于最低金额,该资产就不会出现在账单中。例如:BTC = 60 000 USD 时,一张 3 USD 的账单折合 5 000 聪,而最低金额为 10 000 聪,因此这张账单只会提供稳定币。
selectable_assets 字段列出 allowed_assets 中当前可以选择的资产;支付页面只展示这些资产。
幂等性
Idempotency-Key:8–128 个可打印 ASCII 字符,不含空格,且不能以d:开头。建议基于订单号生成,例如order-ORDER-1001。- 相同的键和相同的请求体,返回相同的响应(同一张账单)。
- 相同的键但请求体不同,返回
409 idempotency_conflict。 - 首次请求仍在处理中,返回
409 idempotency_in_progress,请一秒后重试。 - 因业务规则被拒绝的结果(例如
422)同样会被记住。
查询
顾客选择币种后,账单中会出现 quote:
{
"asset_id": "USDT-TRON", "network": "tron", "token_contract": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
"address": "TX…", "amount_due": "49990000", "decimals": 6, "display_amount": "49.99",
"payment_uri": "tron:…", "rate": "1", "rate_valid_until": null,
"network_warning": "请仅通过 TRON 网络(TRC-20)发送 USDT…"
}payments 为付款列表:tx_hash、amount(以最小单位计)、confirmations、required_confirmations、state(mempool、included、confirmed、reorged、replaced、failed、dropped)。
unmatched_payments 为转入账单地址但未计入的转账:来自其他 EVM 网络(wrong_network),或使用了不在白名单中的代币(token_not_whitelisted)。它们不会改变账单状态和 paid_amount。
列表
响应:{ "items": [...], "next_cursor": "…" | null },按从新到旧排序,limit 取值 1–200。
状态
| 状态 | 含义 | 商店应如何处理 |
|---|---|---|
created | 账单已创建,尚未选择币种 | 等待 |
awaiting_payment | 已选择币种并分配地址 | 等待 |
detected | 链上已看到付款(内存池) | 显示「已检测到付款」,不要发货 |
confirming | 已打包进区块,确认数尚未达到要求 | 显示进度,不要发货 |
paid | 已足额支付并确认 | 完成订单 |
overpaid | 支付金额超出应付金额 | 完成订单;多付部分可按需退款 |
underpaid | 已确认金额少于应付金额(扣除容差后) | 请顾客向同一地址补付 |
expired | 已过期,未收到付款 | 提供新账单(见下文) |
late_payment | 付款在过期后才到账 | 由您决定:完成订单或退款 |
manual_review | 付款正在接受 AML 审查 | 等待审查结果;不要发货 |
refunded、cancelled | 已关闭 | 不要发货 |
GET /v1/invoices/{id} 获取到 paid 或 overpaid 状态时才完成订单。过期后使用稳定币付款
以 USD 计价的账单用 USDT 或 USDC 支付不存在汇率风险,因此过期后(30 天内)的付款会被自动计入:已收到 invoice.expired 的账单会变为 paid,并发送带有 data.late: true 的 invoice.paid。因此,请不要因为 invoice.expired 就不可逆地关闭订单。对于波动性资产,此类付款会进入 late_payment 状态。
金额与汇率
- 价格以账单币种设定。顾客选择支付币种时,Coinetic 会锁定对应的加密货币金额。
- 与计价币种对应的稳定币(USD 账单使用 USDT):按 1:1 计算,金额在账单有效期内固定不变。
- 波动性资产(BTC、ETH 等):取 Kraken、Coinbase 和 Bitstamp 汇率的中位数,锁定 20 分钟。
amount_due以资产的最小单位表示(TRON 上的 USDT 为 6 位小数:"49990000"= 49.99)。display_amount是同一金额的常规写法。- 少付容差(默认 0.5%)用于覆盖钱包的舍入误差。
参考汇率:GET /v1/rates?base=BTC"e=USD。请不要据此向顾客展示“精确”的加密货币金额:只有账单给出的金额才具有约束力。