tgpay cryptoAPI
crypto-payapiinvoicesrefunds

Referencia de la API: facturas y reembolsos

6 min de lecturaActualizado el 22 ago 2026

Los métodos de facturas: createInvoice, getInvoices, deleteInvoice, refundInvoice. Las convenciones (autenticación, envoltorio, montos, spend_id) están en la página de referencia de la API para comerciantes; el recorrido guiado es Aceptar pagos con facturas.

createInvoice

POST /pay/api/createInvoice — ámbito invoices, límite de 60 por minuto.

ParámetroTipoObligatorioSignificado
currency_typestringnocrypto (por defecto) o fiat
assetstringmodo criptoel activo a cobrar, por ejemplo USDT. No se permite junto con fiat
fiatstringmodo fiatla moneda fiat en la que está el precio (las filas is_fiat de getCurrencies)
accepted_assetsstring / arraynosolo en modo fiat: los activos con los que puede pagar quien paga — una cadena separada por comas ("USDT,GRAM") o un array JSON. Si se omite = todos los activos admitidos
amountstringsí, salvo que se use open_amountcadena decimal positiva: unidades del activo en modo cripto, unidades fiat (máx. 2 decimales) en modo fiat
open_amountbooleannoextensión, solo en modo cripto: sin monto fijo — quien paga ingresa uno al pagar (donaciones y propinas). Excluyente con amount
descriptionstringnohasta 1024 caracteres, se le muestra a quien paga
hidden_messagestringnohasta 2048 caracteres, se le revela a quien paga solo después del pago
payloadstringnohasta 4096 caracteres de datos propios, devueltos en la factura y en el webhook
allow_commentsbooleannopermitir que quien paga adjunte un comentario (por defecto true)
allow_anonymousbooleannopermitir que quien paga oculte su identidad (por defecto true)
paid_btn_namestringnobotón posterior al pago: viewItem, openChannel, openBot o callback
paid_btn_urlstringnola URL http(s) del botón — obligatoria cuando se usa paid_btn_name
swap_tostringnointercambiar automáticamente los pagos recibidos a este activo. Se hace lo posible: si el intercambio no puede correr al momento del pago, el pago igual funciona sin intercambiar
expires_inintegernosegundos hasta que la factura expira, hasta 2678400 (31 días); omitido o 0 = nunca
rate_lock_secondsintegernoextensión, solo en modo fiat: congelar los tipos de conversión al crearla durante esta ventana (mira más abajo)

El resultado —y el payload del webhook invoice_paid— es el objeto de factura. Sus campos clave:

  • Identidad y estado: invoice_id, hash (el id público dentro de pay_url), status (active / paid / expired), pay_url — el enlace de t.me que le envías a quien paga (bot_invoice_url, mini_app_invoice_url y web_app_invoice_url son alias de él).
  • Montos: amount (el valor nominal — unidades fiat en una factura fiat, cripto en el resto; null mientras una factura de monto abierto está sin pagar), amount_minor, y en las facturas fiat pagadas paid_asset / paid_amount / paid_fiat_rate: la cripto realmente cobrada y el tipo usado.
  • Comisión: fee_asset / fee_amount, sellados al pagar — la cifra de referencia para tus libros (fee y usd_rate son alias obsoletos de Crypto Bot). Mira comisiones y límites.
  • Quien paga: paid_by_user_id (null cuando eligió el anonimato), paid_anonymously, comment.
  • Reembolsos (extensión): refunded_amount / refunded_minor (acumulados) y refunded_at, sellado una vez reembolsada por completo.
  • Fijación del tipo (extensión): rate_lock_until y rate_lock_rates — los tipos sellados por activo, null cuando no se pidió ninguna fijación.
  • Tal como se creó: description, hidden_message, payload, paid_btn_name / paid_btn_url, expiration_date (expires_at es un alias), los campos de intercambio (swap_to, is_swapped, swapped_to, swapped_rate, swapped_output, …).

Errores: 400 invalid_currency (activo y fiat mezclados), 400 invalid_amount, 404 unknown_asset, 400 unsupported_fiat, 400 paid_btn_url_required, y para las peticiones con fijación de tipo 400 rate_lock_fiat_only, 409 ratelock_disabled, 409 rate_unavailable (no hay un tipo fresco para un activo aceptado — reintenta).

Cómo se pagan las facturas

Quien paga lo hace con el saldo de su billetera en la Mini App, al instante y sin comisión de red. También puede financiar la factura desde una billetera externa: la app le muestra una dirección de depósito, su transferencia llega a su propia billetera y la factura se liquida sola en cuanto aterriza. En cualquier caso tú ves lo mismo: una factura paid normal y un webhook invoice_paid; no hay parámetros ni campos extra que manejar.

En una factura fiat, el monto en cripto se calcula al momento del pago, redondeado a tu favor, así que nunca recibes menos que el valor nominal en fiat. Si no hay un tipo fresco disponible, el pago falla del lado de quien paga en vez de liquidarse a un tipo viejo.

Fijar el tipo en una factura fiat

Pasa rate_lock_seconds para sellar el tipo del momento de cada activo aceptado al crearla. Mientras la fijación está viva, quien paga ve exactamente los montos sellados y el pago se convierte al tipo sellado: tú asumes el riesgo de tipo de cambio durante la ventana. El servidor acota la ventana entre 60 segundos y el máximo de la plataforma (hoy 15 minutos).

Cuando la fijación caduca, la factura sigue siendo pagable y vuelve en silencio a la conversión del momento del pago. Si quieres que la factura muera con la cotización, pon expires_in con el mismo valor.

getInvoices

GET /pay/api/getInvoices — ámbito read. Filtros: asset, fiat, invoice_ids (separados por comas), status (active / paid / expiredexpired es una extensión; active excluye las facturas que ya pasaron su fecha límite), más offset / count. Devuelve {"items": [invoice, …]}, las más recientes primero.

deleteInvoice

POST /pay/api/deleteInvoice — ámbito invoices. Un parámetro: invoice_id. Cancela una factura sin pagar y devuelve true. Errores: 404 invoice_not_found, 409 invoice_already_paid — una factura pagada no se puede eliminar, el dinero ya se movió.

refundInvoice

POST /pay/api/refundInvoice — ámbito refunds, límite de 30 por minuto. Una extensión sobre Crypto Bot: devuelve el monto nominal de una factura pagada —o parte de él— desde el saldo de tu app a quien la pagó, incluidos quienes pagaron de forma anónima, sin revelar quiénes eran.

ParámetroTipoObligatorioSignificado
invoice_idintegerla factura pagada
amountstringnoel monto a reembolsar, en el activo de la factura. Omitido = todo el resto sin reembolsar. Los reembolsos parciales se acumulan hasta el monto nominal
spend_idstringnoclave de idempotencia — usa una, para que un reintento por tiempo agotado repita en vez de reembolsar dos veces

El resultado es el objeto de factura actualizado con los acumulados refunded_amount / refunded_minor; refunded_at se sella una vez que la factura está reembolsada por completo. El estado sigue siendo paid. La comisión de la plataforma no se devuelve. Cada reembolso dispara el webhook opcional refund_completed.

Errores: 404 invoice_not_found, 409 invoice_not_paid, 409 already_refunded (no queda nada por reembolsar), 409 amount_too_big (más que el resto sin reembolsar), 409 insufficient_funds, 400 invalid_amount, y el par de spend_id 409 idempotency_conflict / 409 idempotency_in_progress.