商户 API 参考
所有方法共用的约定,外加那几个只读的目录类方法。逐个方法的页面: 账单和退款、转账和红包、 订阅、webhook。
这套 API 兼容 Crypto Bot:现成的 Crypto Bot 集成只要改 base URL 和令牌就能用。超出那份契约 的部分,下面都标了扩展。
整套 API 还有一份机器可读的 OpenAPI 3.1 规格——每一个方法、对象、错误名和 webhook 都在里面 ——跟这些页面一起发布:crypto-pay-openapi.yaml · crypto-pay-openapi.json。可以直接喂给代码生成器、API 客户端 或您的 AI 工具。
Base URL 和鉴权
所有方法都在 https://crypto.tgpaybot.com/pay/api/<methodName>。
每个请求都要用 TgCryptoPay-API-Token 请求头里的令牌鉴权(Crypto-Pay-API-Token
作为兼容别名也接受;两个都发的话,以规范的那个为准)。令牌缺失、无效、已吊销——或属于
一个已删除的应用——都返回 401 unauthorized。
令牌的形式是 <app_id>:<secret>,在创建或更换时显示一次;服务器只存它的散列值。见
开发者上手。
令牌和权限范围
两种凭据的鉴权方式完全一样:
- 主令牌——对每一个方法都有完整权限,也是唯一给 webhook 签名的钥匙。
- 受限令牌(扩展)——每个应用最多同时有 10 个,在更多 → 商户 API的受限令牌下面 创建,每一个都有一个标签和一部分权限范围。吊销其中一个是即时的,也不影响其他的;更换主 令牌同样不影响它们。
| 权限范围 | 它开放的方法 |
|---|---|
| (任意有效令牌) | getMe、getCurrencies、getExchangeRates |
read | getBalance、getStats、getInvoices、getChecks、getTransfers、getSubscriptionPlans、getSubscriptions |
invoices | createInvoice、deleteInvoice |
refunds | refundInvoice |
payouts | transfer、transferBatch |
checks | createCheck、deleteCheck |
subscriptions | createSubscriptionPlan、archiveSubscriptionPlan、cancelSubscription |
权限范围是叠加的、互相独立的——invoices 并不顺带给 read,所以一台只负责开账单的服务器,
可以拿一个什么都读不了的令牌。调一个令牌覆盖不到的方法会返回 403 scope_required。
getMe 会报出当前令牌的 scopes(主令牌是 null)和 token_name,所以您随时能查清楚手里
拿的是什么。
请求和响应
- 读取类方法是
GET,参数走 query string。涉及资金的方法只收POST——参数可以是 JSON body、form-urlencoded 或 query 参数(冲突时以 body 为准);multipart/form-data会被拒。 - 每个响应都是同一套 JSON 外层结构:成功是
{"ok": true, "result": …},出错是{"ok": false, "error": {"code": <HTTP status>, "name": "<error_name>"}}。 请按error.name分支——它才是稳定的、机器可读的那个字符串。 - 有一个边角情况:GET 方法上某个 query 值类型不对(比如
offset=abc)会返回 HTTP 422, body 是外层结构之外的{"detail": …}。请把 query 值的类型写对。
金额
- 加密货币金额是整币单位的小数字符串(
"10.5")——绝不是 JSON 数字。响应里还带着amount_minor(扩展):以字符串表示的最小单位整数值,因为 wei 量级的整数会超出 JavaScriptNumber的表示范围。 - 各币种的
decimals从getCurrencies取——请拿它来驱动您的金额运算,别写死。 - 法币金额最多 2 位小数。
- 汇率是定点小数字符串,绝不是数字。
分页
列表类方法(getInvoices、getChecks、getTransfers、getSubscriptions)接受 offset
(默认 0)和 count(默认 100,最大 1000;getSubscriptions 最大 500),返回
{"items": […]},按时间倒序。ID 过滤参数(invoice_ids、check_ids、transfer_ids)
是逗号分隔的整数列表。所有时间戳都是 ISO 8601 字符串。
幂等:spend_id
涉及资金的方法接受一个由调用方生成的 spend_id 键(1–64 个字符):transfer 和
transferBatch 的每一项都必须给,createCheck 和 refundInvoice 可给可不给
(扩展——建议一并传上)。用同一个键、同样的参数重试,返回的是原来那次的结果,钱不会动第二次,
所以超时的请求永远可以安全重试。同一个键配不同的参数会返回 409 idempotency_conflict;
原来那次还在执行时重试会返回 409 idempotency_in_progress。
频率限制
按应用算,该应用的所有令牌共用;超了返回 429 rate_limited:
| 方法 | 限制 |
|---|---|
createInvoice、createCheck | 每分钟 60 次 |
refundInvoice、transfer | 每分钟 30 次 |
transferBatch | 每分钟 10 次 |
读取类方法不限流。平台维护期间,写入类方法返回 503 maintenance,读取照常。
目录和账户类方法
getMe
GET /pay/api/getMe——无参数。返回这个应用的身份信息:app_id、name、
payment_processing_bot_username、webhook_url、webhook_events(该应用订阅了的扩展
webhook 类型),以及上面说过的令牌自省字段 scopes / token_name。
getBalance
GET /pay/api/getBalance——无参数。每个支持的币种返回一行,余额为零也返回:
currency_code、available(可花的余额)、onhold(锁在您未领红包里的资金),以及
amount_minor。
getCurrencies
GET /pay/api/getCurrencies——无参数。API 支持什么,以这份清单为准:加密货币行
(is_blockchain: true)和账单可以用来标价的法币(is_fiat: true)。每一行都带 code、
name、decimals 和 is_stablecoin 标记。
getExchangeRates
GET /pay/api/getExchangeRates——无参数。加密货币兑法币的报价:source、target、
rate(一个定点小数字符串),以及 is_valid——false 意味着整张表都是从过期缓存里给的,
那些汇率只能当参考。
getStats
GET /pay/api/getStats——可选的 start_at / end_at(ISO 8601;默认窗口是最近 24 小时)。
返回 volume(窗口内已付账单的美元金额)、conversion(已付/已开,百分比)、
unique_users_count、created_invoice_count、paid_invoice_count,以及实际生效的窗口
边界。日期解析不了会返回 400 invalid_date。
每个方法都可能返回的错误
| HTTP | error.name | 什么时候 |
|---|---|---|
| 401 | unauthorized | 令牌缺失、无效或已吊销 |
| 403 | scope_required | 令牌没有这个方法要的权限范围 |
| 400 | invalid_request | 参数解析不了或不合法(POST) |
| 429 | rate_limited | 超过频率限制 |
| 503 | maintenance | 平台维护中(写入类方法) |
| 500 | internal_error | 服务器意外出错 |
各方法特有的错误列在各自的页面上。
这篇文章帮上忙了吗?
谢谢反馈。