tgpay cryptoAPI
crypto-payapiinvoicesrefunds

Referencia de la API: facturas y reembolsos

7 min de lecturaActualizado el 9 oct 2026

Los métodos de facturas: createInvoice, getInvoices, deleteInvoice, refundInvoice. Las convenciones (autenticación, estructura de respuesta, 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. Usa este campo en lugar de 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 admitidos para el pago — 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 se puede realizar al momento del pago, el pago se completa en el activo original
expires_inintegernosegundos hasta que la factura expira, hasta 2678400 (31 días); omitido o 0 = duración predeterminada. Consulta expiration_date en el resultado
rate_lock_secondsintegernoextensión, solo en modo fiat: congelar los tipos de conversión al crearla durante esta ventana (mira más abajo)

La descripción, el contenido posterior al pago y el botón pueden permanecer ocultos mientras se revisa el contenido o si no se ha aprobado. El monto de la factura se puede pagar igualmente.

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, registrados 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, registrado una vez reembolsada por completo.
  • Fijación del tipo (extensión): rate_lock_until y rate_lock_rates — los tipos registrados para cada 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, 400 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 de cambio actualizado para un activo aceptado — reintenta).

Cómo se pagan las facturas

El usuario paga con el saldo de su billetera en la Mini App, al instante y sin comisión de red, siempre que tenga fondos suficientes y confirme el pago. También puede aportar fondos desde una billetera externa: cuando esta opción está disponible, la app muestra una dirección de depósito y una fecha límite de pago. El depósito se abona a la billetera del propio usuario. El pago automático requiere un depósito a esa dirección, saldo disponible suficiente, ausencia de restricciones para los pagos salientes y que tanto la solicitud de pago como la factura sigan vigentes. Un depósito que llegue tarde permanece en la billetera del usuario; no demuestra que la factura esté pagada. En ambos casos recibes lo mismo: una factura normal con estado paid y un evento invoice_paid si configuraste una URL de webhook. No hay parámetros ni campos adicionales que debas gestionar.

En una factura fiat, el monto en cripto se calcula al pagar y se redondea hacia arriba a la unidad mínima del activo elegido. Después se descuenta la comisión para comerciantes de ese monto en cripto. Si no hay un tipo fijado vigente ni un tipo de cambio actualizado, el pago falla en lugar de completarse con un tipo de cambio desactualizado.

Fijar el tipo en una factura fiat

Pasa rate_lock_seconds para fijar el tipo de cambio del momento de cada activo aceptado al crearla. Mientras el tipo fijado siga vigente, quien paga ve exactamente los montos fijados y el pago se convierte al tipo fijado: tú asumes el riesgo de tipo de cambio durante ese plazo. El servidor ajusta la duración solicitada al intervalo admitido. Consulta rate_lock_until en el resultado para conocer la fecha límite real.

Cuando vence el plazo de fijación, la factura sigue siendo pagable si aún no ha expirado, al tipo de cambio del momento del pago. Para hacer coincidir ambos plazos, usa un expires_in dentro del intervalo admitido para la fijación y compara expiration_date con rate_lock_until en la respuesta.

getInvoices

GET /pay/api/getInvoices — ámbito read. Filtros: asset, fiat, invoice_ids (separados por comas), status (active / paid / expired — expired 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. Esta extensión de la API de Crypto Bot devuelve toda la cripto pagada o parte de ella desde el saldo de tu app a quien pagó. También funciona con pagos anónimos sin revelar la identidad del usuario. En una factura fiat, usa paid_asset y paid_amount: el reembolso no realiza una nueva conversión fiat.

ParámetroTipoObligatorioSignificado
invoice_idintegersíla factura pagada
amountstringnoel monto en cripto que se reembolsará, en el activo del pago original (paid_asset para facturas fiat). Si se omite, se devuelve todo el monto pendiente de reembolso. Los reembolsos parciales se acumulan hasta el monto en cripto originalmente pagado
spend_idstringnoclave de idempotencia — usa una, para que, si repites una solicitud tras un tiempo de espera agotado, se devuelva el resultado anterior en vez de reembolsar dos veces

El resultado es el objeto de factura actualizado con los acumulados refunded_amount / refunded_minor; refunded_at se registra una vez que la factura está reembolsada por completo. El estado sigue siendo paid. La comisión de la plataforma no se devuelve. Tu app necesita saldo suficiente en el activo del pago original, aunque swap_to haya convertido el ingreso a otro activo. Cada reembolso genera 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.