tgpay cryptoAPI
crypto-payapiinvoicesrefunds

Référence de l’API : factures et remboursements

7 min de lectureMis à jour le 9 oct. 2026

Les méthodes de facture : createInvoice, getInvoices, deleteInvoice, refundInvoice. Les conventions (authentification, enveloppe, montants, spend_id) sont sur la page Référence de l’API marchand ; le parcours guidé est Accepter des paiements avec des factures.

createInvoice

POST /pay/api/createInvoice — permission invoices, limite : 60 par minute.

ParamètreTypeRequisSignification
currency_typestringnoncrypto (défaut) ou fiat
assetstringmode cryptol’actif à facturer, par exemple USDT. Interdit en même temps que fiat
fiatstringmode fiatla monnaie fiduciaire dans laquelle le prix est libellé (les lignes is_fiat de getCurrencies)
accepted_assetsstring / arraynonmode fiat uniquement : les actifs avec lesquels le payeur peut payer — une chaîne séparée par des virgules ("USDT,GRAM") ou un tableau JSON. Omis = tous les actifs pris en charge
amountstringoui, sauf si open_amount est définichaîne décimale positive : unités de l’actif en mode crypto, unités fiduciaires (2 décimales au maximum) en mode fiat
open_amountbooleannonextension, mode crypto uniquement : pas de montant fixe — le payeur en saisit un au moment de payer (dons et pourboires). Ne peut pas être utilisé avec amount
descriptionstringnonjusqu’à 1024 caractères, affichée au payeur
hidden_messagestringnonjusqu’à 2048 caractères, révélé au payeur seulement après le paiement
payloadstringnonjusqu’à 4096 caractères de vos propres données, renvoyés dans la facture et le webhook
allow_commentsbooleannonlaisse le payeur joindre un commentaire (défaut true)
allow_anonymousbooleannonlaisse le payeur masquer son identité (défaut true)
paid_btn_namestringnonbouton après paiement : viewItem, openChannel, openBot ou callback
paid_btn_urlstringnonl’URL http(s) du bouton — requise quand paid_btn_name est défini
swap_tostringnontente de convertir automatiquement les paiements reçus dans cet actif. Si la conversion ne peut pas s’exécuter au moment du paiement, le paiement réussit quand même sans conversion
expires_inintegernonsecondes avant expiration de la facture, jusqu’à 2678400 (31 jours) ; omis ou 0 = durée de validité par défaut. Consultez expiration_date dans le résultat
rate_lock_secondsintegernonextension, mode fiat uniquement : fige les taux de conversion à la création pour cette fenêtre (voir plus bas)

La description, le contenu après paiement et le bouton peuvent être masqués aux payeurs pendant l’examen du contenu ou si celui-ci n’a pas été approuvé. Le montant de la facture reste payable.

Le résultat — et la charge utile du webhook invoice_paid — est l’objet facture. Ses champs clés :

  • Identité et état : invoice_id, hash (l’identifiant public dans pay_url), status (active / paid / expired), pay_url — le lien t.me que vous envoyez au payeur (bot_invoice_url, mini_app_invoice_url, web_app_invoice_url en sont des alias).
  • Montants : amount (la valeur nominale — unités fiduciaires sur une facture fiat, crypto sinon ; null tant qu’une facture à montant libre est impayée), amount_minor, et sur les factures fiat payées paid_asset / paid_amount / paid_fiat_rate — la crypto réellement facturée et le taux utilisé.
  • Frais : fee_asset / fee_amount, enregistrés lors du paiement — le chiffre qui fait foi pour votre comptabilité (fee et usd_rate sont des alias Crypto Bot obsolètes). Voir frais et limites.
  • Payeur : paid_by_user_id (null quand le payeur a choisi l’anonymat), paid_anonymously, comment.
  • Remboursements (extension) : refunded_amount / refunded_minor (cumulés) et refunded_at, enregistré une fois le remboursement complet.
  • Taux bloqué (extension) : rate_lock_until et rate_lock_rates — les taux enregistrés par actif, null si aucun blocage n’a été demandé.
  • Données de création : description, hidden_message, payload, paid_btn_name / paid_btn_url, expiration_date (expires_at en est un alias), les champs de conversion (swap_to, is_swapped, swapped_to, swapped_rate, swapped_output, …).

Erreurs : 400 invalid_currency (actif et fiat mélangés), 400 invalid_amount, 400 unknown_asset, 400 unsupported_fiat, 400 paid_btn_url_required, et pour les demandes de blocage de taux 400 rate_lock_fiat_only, 409 ratelock_disabled, 409 rate_unavailable (pas de taux récent pour un actif accepté — réessayez).

Comment les factures sont payées

Le payeur paie depuis le solde de son portefeuille dans la Mini App — instantanément, sans frais de réseau, sous réserve d’un solde suffisant et de la confirmation du paiement. Le payeur peut aussi alimenter la facture depuis un portefeuille externe : lorsque cette option est disponible, l’app affiche une adresse de dépôt et une échéance de paiement. Le dépôt crédite son propre portefeuille. Le paiement automatique nécessite un dépôt à cette adresse, un solde disponible suffisant, aucune restriction sur les paiements sortants et une demande de paiement ainsi qu’une facture encore valides. Un dépôt tardif reste sur le portefeuille du payeur ; il ne prouve pas que la facture a été payée. Dans les deux cas, vous recevez une facture au statut paid et un événement invoice_paid si une URL de webhook est configurée, sans paramètre ni champ supplémentaire à gérer.

Sur une facture fiat, le montant en crypto est calculé au moment du paiement et arrondi à l’unité minimale supérieure de l’actif choisi. Les frais marchands sont ensuite déduits de ce montant en crypto. Si aucun taux bloqué valide ni taux récent n’est disponible, le paiement échoue du côté du payeur plutôt que de se régler à un taux obsolète.

Bloquer le taux sur une facture fiat

Passez rate_lock_seconds pour enregistrer le taux courant de chaque actif accepté à la création. Tant que le blocage est actif, le payeur voit exactement les montants enregistrés, et le paiement utilise le taux enregistré — vous prenez le risque de change pendant la fenêtre. Le serveur ajuste la durée demandée à la plage prise en charge. Consultez rate_lock_until dans le résultat pour connaître l’échéance effective.

Quand le blocage expire, une facture non expirée reste payable au taux du moment du paiement. Pour faire coïncider les deux échéances, choisissez un expires_in dans la plage de blocage prise en charge, puis comparez expiration_date et rate_lock_until dans la réponse.

getInvoices

GET /pay/api/getInvoices — permission read. Filtres : asset, fiat, invoice_ids (séparés par des virgules), status (active / paid / expired — expired est une extension ; active exclut les factures dont l’échéance est déjà passée), plus offset / count. Renvoie {"items": [invoice, …]}, les plus récentes d’abord.

deleteInvoice

POST /pay/api/deleteInvoice — permission invoices. Un seul paramètre : invoice_id. Annule une facture impayée et renvoie true. Erreurs : 404 invoice_not_found, 409 invoice_already_paid — une facture payée ne peut pas être supprimée, les fonds ont déjà été transférés.

refundInvoice

POST /pay/api/refundInvoice — permission refunds, limite : 30 par minute. Cette extension par rapport à Crypto Bot rembourse tout ou partie du montant en crypto effectivement payé, depuis le solde de votre application vers le payeur. Elle fonctionne aussi pour les payeurs anonymes sans révéler leur identité. Pour une facture en monnaie fiduciaire, utilisez paid_asset et paid_amount ; le remboursement ne procède pas à une nouvelle conversion.

ParamètreTypeRequisSignification
invoice_idintegerouila facture payée
amountstringnonle montant en crypto à rembourser, dans l’actif payé à l’origine (paid_asset pour les factures en monnaie fiduciaire). Omis = tout le montant restant à rembourser. Les remboursements partiels se cumulent jusqu’au montant en crypto initialement payé
spend_idstringnonclé d’idempotence — utilisez-en une, pour qu’une nouvelle tentative après un délai de réponse dépassé renvoie le résultat précédent sans rembourser deux fois

Le résultat est l’objet facture mis à jour avec les cumuls refunded_amount / refunded_minor ; refunded_at est enregistré une fois la facture entièrement remboursée. Le statut reste paid. Les frais de plateforme ne sont pas remboursés. Votre application doit disposer d’un solde suffisant dans l’actif payé à l’origine, même si swap_to a converti le paiement dans un autre actif. Chaque remboursement déclenche le webhook facultatif refund_completed.

Erreurs : 404 invoice_not_found, 409 invoice_not_paid, 409 already_refunded (plus rien à rembourser), 409 amount_too_big (plus que le reliquat non remboursé), 409 insufficient_funds, 400 invalid_amount, et la paire spend_id 409 idempotency_conflict / 409 idempotency_in_progress.