tgpay cryptoAPI
crypto-payapireferencetokens

Referencia de la API para comerciantes

10 min de lecturaActualizado el 22 oct 2026

Las convenciones que comparten todos los métodos, más los métodos de catálogo de solo lectura. Consulta los detalles de cada método en estas páginas: facturas y reembolsos, transferencias y cheques, suscripciones, webhooks.

La API sigue las convenciones de Crypto Bot para los métodos aquí documentados. Cambia la URL base y el token, y prueba en la red de prueba los métodos que use tu integración. Nuestras funciones adicionales se indican como extensión.

También hay una especificación OpenAPI 3.1 legible por máquina: crypto-pay-openapi.yaml · crypto-pay-openapi.json. Pásasela a generadores de código, clientes de API o tus herramientas de IA, pero consulta también las páginas de cada método: las extensiones más recientes pueden tardar en incorporarse a la especificación.

URL base y autenticación

Todos los métodos están disponibles en https://app.tgpaycrypto.com/pay/api/<methodName>. En la red de prueba la base es https://testnet.tgpaycrypto.com/pay/api: apps y tokens separados, fondos de prueba sin valor real.

Autentica cada petición con el token en la cabecera TgPayCrypto-API-Token (TgCryptoPay-API-Token, el nombre anterior al 2026-09-07, y Crypto-Pay-API-Token se aceptan como alias de compatibilidad; si se envían varias, gana la canónica). Un token ausente, inválido o revocado devuelve 401 unauthorized. Lo mismo ocurre con un token restringido vencido, el token de una app eliminada o uno cuyo titular esté bloqueado.

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 sin revocar por app, incluidos los vencidos. Abre Más → API para comerciantes, elige la app y entra en Acceso y tokens. Créalos 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. Un token también puede tener una fecha de vencimiento; después de esa fecha deja de servir para autenticarse.
ÁmbitoMétodos que desbloquea
(cualquier token válido)getMe, getCurrencies, getExchangeRates
readgetBalance, getStats, getInvoices, getChecks, getTransfers, getSubscriptionPlans, getSubscriptions
invoicescreateInvoice, deleteInvoice
refundsrefundInvoice
payoutstransfer, transferBatch
checkscreateCheck, deleteCheck
subscriptionscreateSubscriptionPlan, archiveSubscriptionPlan, cancelSubscription
webhooksupdateApp

Los ámbitos son aditivos e independientes: invoices no implica read, así que un servidor que solo crea facturas puede usar un token sin acceso a los saldos ni al historial de pagos. 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 puedes comprobar qué token estás usando y qué permite hacer.

Modo de pagos

Un ámbito dice qué métodos puede llamar un token; el modo de pagos de la app dice a quién puede pagar cualquiera de sus tokens, incluido el principal. Una app nueva le paga a cualquiera desde el primer minuto; el dueño puede restringirlo en Más → API para comerciantes: abre la app y entra en Configuración de pagos → Pagos a través de la API. Esto limita lo que se puede hacer si un token se filtra, igual que el límite diario. Volver a ampliarlo requiere su PIN o biometría; la API solo puede leerlo (getMe → payout_mode).

payout_modeQué pueden hacer transfer, transferBatch y createCheck
anypagarle a cualquier usuario, dejar un pago en espera para un @username desconocido, crear cheques al portador: el valor por defecto y el comportamiento de Crypto Bot
allowlistpagar solo a los usuarios de Telegram de la lista. Todos los destinatarios de un cheque, tanto el usuario designado como los de una lista, deben estar autorizados. Otros destinatarios, los @username desconocidos y los cheques al portador devuelven 403 recipient_not_allowed
offnada: toda llamada de pago devuelve 403 payouts_disabled; las facturas, las suscripciones, los reembolsos y los webhooks funcionan como siempre

Si se rechaza un pago, el dueño recibe un aviso en Telegram y puede cambiar el modo. El límite diario de pagos se aplica además del modo. Para qué pueden usarse los pagos lo establecen las condiciones de la API para comerciantes.

Peticiones y respuestas

  • Los métodos de lectura son GET con parámetros en la cadena de consulta. Los métodos que mueven dinero son solo POST: los parámetros van como cuerpo JSON, form-urlencoded o parámetros de consulta (ante conflicto gana el cuerpo); multipart/form-data se rechaza.
  • Las respuestas generadas por los métodos de la API usan esta estructura JSON: éxito {"ok": true, "result": …}, error {"ok": false, "error": {"code": <HTTP status>, "name": "<error_name>"}}. Usa error.name para decidir cómo gestionar el error: es un identificador estable.
  • Un parámetro de consulta con un tipo incorrecto en un método GET (por ejemplo, offset=abc) puede rechazarse antes de que se ejecute el método de la API. Comprueba el estado HTTP: no todas las respuestas de error tienen la estructura anterior. Envía los parámetros de consulta con los tipos esperados.

Montos

  • Los montos en cripto son cadenas decimales en unidades del activo ("10.5"), nunca números JSON. Las respuestas también llevan amount_minor (extensión): el valor entero en unidades mínimas como cadena, porque los enteros a escala de wei pueden superar la precisión exacta de un Number de JavaScript.
  • Los decimals por activo vienen de getCurrencies: usa ese valor para calcular los montos en vez de fijarlo 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 siempre son 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 devuelve el resultado original en vez de mover fondos dos veces, así que puedes reintentar una petición que superó el tiempo de espera. 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

Se aplican por app y se comparten entre todos sus tokens. Al superarlos se devuelve 429 rate_limited:

MétodoLímite
createInvoice, createCheck60 por minuto
refundInvoice30 por minuto
transfer30 por minuto
transferBatch10 por minuto
updateApp10 por minuto
createSubscriptionPlan20 por minuto

Pueden aplicarse otros límites a las peticiones. Si recibes 429 rate_limited, aumenta la espera antes de volver a intentarlo. Durante el mantenimiento de la plataforma, los métodos de escritura devuelven 503 maintenance y 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ó), los campos de introspección del token scopes / token_name descritos arriba y payout_mode (off / allowlist / any), daily_payout_max_usd_cents (0 = sin límite establecido por el titular) y daily_payout_spent_usd_cents (lo gastado durante las últimas 24 horas).

updateApp

POST /pay/api/updateApp — ámbito webhooks. Parámetros opcionales: name (de 1 a 64 caracteres), webhook_url (una URL HTTPS pública; una cadena vacía la elimina) y webhook_events (un array o una lista separada por comas con los nombres de los eventos adicionales admitidos). Una lista de eventos vacía deja únicamente invoice_paid. Devuelve los mismos campos de la app que getMe.

getBalance

GET /pay/api/getBalance — sin parámetros. Devuelve un array con una fila por activo admitido, incluso si el saldo es cero: currency_code, available (saldo disponible), onhold (fondos de cheques sin canjear y pagos pendientes a @username) 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. Estos tipos de cambio son orientativos. is_valid: true no garantiza que una cotización esté actualizada. Si no se pueden obtener tipos de cambio, el resultado puede ser un array vacío. Para comprobar un pago real, usa los montos y los tipos de cambio registrados en la factura.

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 durante ese período, estimado a los tipos de cambio actuales; los activos sin precio se contabilizan como cero), 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

HTTPerror.nameCuándo
401unauthorizedtoken ausente, inválido o revocado
403scope_requiredel token no tiene el ámbito del método
403payouts_disabledel modo de pagos de la app es off (solo en los métodos que envían pagos)
403recipient_not_allowedel destinatario no está en la lista de destinatarios de la app (solo en los métodos que envían pagos)
400invalid_requestparámetros inválidos o que no se pueden interpretar (POST)
403daily_cap_exceededse superaría el límite diario de pagos de la app
403verification_requiredlas operaciones salientes del titular están restringidas; afecta a transferencias, cheques y reembolsos
503merchant_payouts_pausedlos cargos al saldo de la app están temporalmente suspendidos
429rate_limitedse superó el límite de frecuencia
503maintenancemantenimiento de la plataforma (métodos de escritura)
500internal_errorerror inesperado del servidor

Los errores propios de cada método están listados en la página de ese método.

Errores sin el formato JSON

Una respuesta de error en texto sin formato o HTML no permite identificar por sí sola en qué capa se produjo. Revisa el estado HTTP, el cuerpo y los encabezados de la respuesta.

Si Cloudflare devuelve error code: 1010, ha rechazado al cliente por la firma del navegador antes de que la solicitud llegara a la API. Los permisos del token no son la causa de este error de Cloudflare. Un User-Agent ausente o no estándar puede activar la protección de red. Prueba a enviar un encabezado User-Agent que identifique a tu cliente, como MyShop/1.0, y repite la solicitud; esto no garantiza que se solucione. Si el error persiste, envía a soporte el estado HTTP, el cuerpo y los encabezados de la respuesta, tras eliminar los tokens y las cookies.