Referencia de la API para comerciantes
Las convenciones que comparten todos los métodos, más los métodos de catálogo de solo lectura. Las páginas método por método: facturas y reembolsos, transferencias y cheques, suscripciones, webhooks.
La API es compatible con Crypto Bot: una integración existente de Crypto Bot funciona con solo cambiar la URL base y el token. Todo lo que va más allá de ese contrato está marcado abajo como extensión.
Junto a estas páginas se publica una especificación OpenAPI 3.1 legible por máquina de toda la API —cada método, objeto, nombre de error y webhook—: crypto-pay-openapi.yaml · crypto-pay-openapi.json. Pásasela a generadores de código, clientes de API o tus herramientas de IA.
URL base y autenticación
Todos los métodos viven en
https://crypto.tgpaybot.com/pay/api/<methodName>.
Autentica cada petición con el token en la cabecera
TgCryptoPay-API-Token (Crypto-Pay-API-Token se acepta como alias de
compatibilidad; si se envían las dos, gana la canónica). Un token ausente,
inválido o revocado —o el token de una app eliminada— devuelve
401 unauthorized.
El token tiene la forma <app_id>:<secret> y se muestra una sola vez, al
crearlo o al renovarlo; el servidor guarda solo su hash. Mira
Empezar como desarrollador.
Tokens y ámbitos
Dos tipos de credenciales se autentican igual:
- El token principal: acceso completo a todos los métodos, y la única clave que firma los webhooks.
- Los tokens restringidos (extensión): hasta 10 vivos por app, creados en Más → API para comerciantes, en Tokens restringidos, cada uno con una etiqueta y un subconjunto de ámbitos. Revocar uno es instantáneo y no toca a los demás; renovar el token principal tampoco los toca.
| Ámbito | Métodos que desbloquea |
|---|---|
| (cualquier token válido) | 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 |
Los ámbitos son aditivos e independientes: invoices no implica read, así que
un servidor que solo crea facturas puede tener un token que no puede leer nada.
Llamar a un método que el token no cubre devuelve 403 scope_required.
getMe informa los scopes del token actual (null para el token principal) y
su token_name, así que siempre puedes comprobar qué tienes en la mano.
Peticiones y respuestas
- Los métodos de lectura son
GETcon parámetros en la cadena de consulta. Los métodos que mueven dinero son soloPOST: los parámetros van como cuerpo JSON, form-urlencoded o parámetros de consulta (ante conflicto gana el cuerpo);multipart/form-datase rechaza. - Toda respuesta es JSON con el mismo envoltorio:
éxito
{"ok": true, "result": …}, error{"ok": false, "error": {"code": <HTTP status>, "name": "<error_name>"}}. Ramifica segúnerror.name: es la cadena estable legible por máquina. - Un caso límite: un valor de consulta con tipo inválido en un método GET (por
ejemplo,
offset=abc) devuelve HTTP 422 con un cuerpo{"detail": …}fuera del envoltorio. Envía valores de consulta bien tipados.
Montos
- Los montos en cripto son cadenas decimales en unidades enteras de moneda
(
"10.5"), nunca números JSON. Las respuestas también llevanamount_minor(extensión): el valor entero en unidades mínimas como cadena, porque los enteros a escala de wei desbordan unNumberde JavaScript. - Los
decimalspor activo vienen degetCurrencies: guía tus cálculos de montos desde ahí en vez de fijarlos en el código. - Los montos en fiat tienen como máximo 2 decimales.
- Los tipos de cambio son cadenas de punto fijo, nunca números.
Paginación
Los métodos de listado (getInvoices, getChecks, getTransfers,
getSubscriptions) toman offset (por defecto 0) y count (por defecto 100,
máx. 1000; getSubscriptions máx. 500) y devuelven {"items": […]}, los más
recientes primero. Los filtros por ID (invoice_ids, check_ids,
transfer_ids) son listas de enteros separadas por comas. Las marcas de tiempo
son en todos lados cadenas ISO 8601.
Idempotencia: spend_id
Los métodos que mueven dinero toman una clave spend_id generada por quien
llama (de 1 a 64 caracteres): obligatoria en transfer y en cada elemento de
transferBatch, opcional en createCheck y refundInvoice (extensión — úsala
igual). Reintentar con la misma clave y los mismos parámetros repite el
resultado original en vez de mover fondos dos veces, así que una petición que se
agotó por tiempo siempre se puede reintentar. La misma clave con parámetros
distintos devuelve 409 idempotency_conflict; un reintento mientras la
original sigue ejecutándose devuelve 409 idempotency_in_progress.
Límites de frecuencia
Por app, compartidos entre todos sus tokens; superarlos devuelve
429 rate_limited:
| Método | Límite |
|---|---|
createInvoice, createCheck | 60 por minuto |
refundInvoice, transfer | 30 por minuto |
transferBatch | 10 por minuto |
Los métodos de lectura no tienen límite de frecuencia. Durante el mantenimiento
de la plataforma, los métodos de escritura devuelven 503 maintenance mientras
las lecturas siguen funcionando.
Métodos de catálogo y de cuenta
getMe
GET /pay/api/getMe — sin parámetros. Devuelve la identidad de la app:
app_id, name, payment_processing_bot_username, webhook_url,
webhook_events (los tipos de webhook extendidos que la app activó) y los
campos de introspección del token scopes / token_name descritos arriba.
getBalance
GET /pay/api/getBalance — sin parámetros. Devuelve un array con una fila por
activo admitido, incluso en cero: currency_code, available (saldo
gastable), onhold (fondos bloqueados en tus cheques pendientes) y
amount_minor.
getCurrencies
GET /pay/api/getCurrencies — sin parámetros. La lista de referencia de lo que
admite la API: filas de cripto (is_blockchain: true) y las monedas fiat en las
que se pueden cotizar las facturas (is_fiat: true). Cada fila lleva code,
name, decimals y la marca is_stablecoin.
getExchangeRates
GET /pay/api/getExchangeRates — sin parámetros. Cotizaciones de cripto a
fiat: source, target, rate (una cadena de punto fijo) e is_valid;
false significa que toda la tabla se sirve desde una caché vieja, así que
trata esos tipos como meramente indicativos.
getStats
GET /pay/api/getStats — start_at / end_at opcionales (ISO 8601; la
ventana por defecto son las últimas 24 horas). Devuelve volume (valor en
dólares de las facturas pagadas en la ventana), conversion (pagadas/creadas,
en porcentaje), unique_users_count, created_invoice_count,
paid_invoice_count y los límites efectivos de la ventana. Una fecha que no se
puede interpretar devuelve 400 invalid_date.
Errores que puede devolver cualquier método
| HTTP | error.name | Cuándo |
|---|---|---|
| 401 | unauthorized | token ausente, inválido o revocado |
| 403 | scope_required | el token no tiene el ámbito del método |
| 400 | invalid_request | parámetros inválidos o que no se pueden interpretar (POST) |
| 429 | rate_limited | se superó el límite de frecuencia |
| 503 | maintenance | mantenimiento de la plataforma (métodos de escritura) |
| 500 | internal_error | error inesperado del servidor |
Los errores propios de cada método están listados en la página de ese método.
¿Te sirvió este artículo?
Gracias por tu comentario.