Référence de l’API : webhooks
Les webhooks transmettent les événements à votre serveur après qu’ils se sont produits. Définissez l’URL du webhook (facultatif) sur votre application dans Plus → API marchand ; la plateforme y envoie ensuite en POST un corps JSON signé pour chaque événement auquel vous êtes abonné.
L’enveloppe
{
"update_id": 123,
"update_type": "invoice_paid",
"request_date": "2026-08-11T12:00:00Z",
"payload": { … }
}
update_id reste stable d’un nouvel envoi à l’autre du même événement —
fondez votre déduplication dessus. request_date est enregistré à chaque
tentative de livraison. payload est l’objet complet correspondant au
type d’événement : l’objet facture pour les événements de facture, l’objet
chèque, transfert ou abonnement (les structures sont sur les pages de
référence correspondantes).
Les types d’événements
update_type | Se déclenche quand | Charge utile |
|---|---|---|
invoice_paid | une facture est payée — sans activation supplémentaire | objet facture |
invoice_expired | une facture dépasse son échéance sans être payée | objet facture |
check_activated | un chèque est récupéré, ou un destinataire récupère sa part | objet chèque ; une récupération dans une liste nominative contient aussi activated_slot |
check_expired | un chèque à liste nominative expire et les parts non récupérées reviennent à l’application | objet chèque avec recipients et leurs valeurs claimed_at |
transfer_completed | un transfert aboutit ou un paiement sur la blockchain est confirmé | objet transfert ou retrait |
transfer_returned | un transfert en attente non récupéré revient à l’application, ou un paiement sur la blockchain échoue et ses fonds réservés sont rendus | objet transfert ou retrait |
refund_completed | un remboursement est exécuté | objet facture avec les champs refunded_* |
subscription_activated | un utilisateur approuve une formule | objet abonnement |
subscription_charged | une période est facturée — charge.kind dit laquelle : initial, renewal ou resubscribe | objet abonnement + charge : {period_no, kind, asset, amount, fee, paid_at} |
subscription_cancelled | un abonnement est annulé par l’une des deux parties | objet abonnement |
subscription_expired | la période de grâce s’écoule sans paiement | objet abonnement |
Les paiements sur la blockchain créés dans l’app utilisent ces mêmes événements de transfert. Leur charge utile contient kind: "withdrawal", des champs comme network, address et txid, et le statut completed ou failed. Leur transfer_id appartient à une séquence d’identifiants distincte : vérifiez kind avant de l’utiliser. La référence OpenAPI téléchargeable décrit les deux variantes de charge utile.
Tout sauf invoice_paid est facultatif (une extension par rapport à
Crypto Bot — un consommateur strictement calqué sur Crypto Bot ne
rencontre jamais un update_type inconnu sans l’avoir demandé).
Activez-les par application sous Événements de webhook supplémentaires
dans la section Webhook de l’application ; les interrupteurs portent les identifiants du tableau ci-dessus. Enregistrez une URL de webhook pour recevoir les événements.
Vérifier la signature
Chaque livraison porte l’en-tête TgPayCrypto-API-Signature
(TgCryptoPay-API-Signature et Crypto-Pay-API-Signature sont des alias de
compatibilité avec la même valeur) : le HMAC-SHA256 hexadécimal du corps
brut de la requête, avec pour clé l’empreinte SHA-256 du
token d’API principal de votre application. C’est le schéma de Crypto
Bot, donc le code de vérification existant fonctionne sans modification :
import hashlib, hmac
secret = hashlib.sha256(API_TOKEN.encode()).digest()
expected = hmac.new(secret, raw_body, hashlib.sha256).hexdigest()
ok = hmac.compare_digest(expected, headers["TgPayCrypto-API-Signature"])
Vérifiez sur les octets bruts reçus — une résérialisation après analyse peut différer octet pour octet et faire échouer le contrôle. Seul le token principal signe ; les tokens restreints ne signent jamais. Renouveler le token principal change instantanément la clé de signature des webhooks : mettez donc le secret à jour sur votre serveur au même moment.
Livraison et nouvelles tentatives
- Une livraison est considérée comme réussie si une réponse 2xx est reçue avant la fin du délai d’attente. Répondez rapidement et traitez les tâches longues séparément.
- Un statut d’erreur, un délai de réponse dépassé ou un échec de connexion déclenche de nouvelles tentatives, de plus en plus espacées, jusqu’à la limite définie par la plateforme. La livraison n’est pas garantie ; utilisez
getInvoicespour rapprocher les paiements après une interruption. - Après la dernière tentative, la livraison est abandonnée. L’URL du webhook elle-même n’est jamais désactivée automatiquement — les erreurs de votre serveur ne désabonnent pas automatiquement votre application.
- Comme les envois peuvent être répétés, votre gestionnaire doit être idempotent :
dédupliquez sur
update_idavant d’agir.
⚠️ Vérifiez avant d’honorer la commande
N’importe qui peut envoyer un POST à votre URL de webhook. Tant que le
contrôle de signature n’est pas passé, traitez le corps comme une entrée
non fiable : n’expédiez pas de commande, ne créditez pas d’utilisateur, ne
marquez rien comme payé. L’ordre sûr est : vérifier la signature →
dédupliquer sur update_id → agir.
Cet article vous a-t-il été utile ?
Merci pour votre retour.