tgpay cryptoAPI
crypto-payapiwebhookssignature

Référence de l’API : webhooks

3 min de lectureMis à jour le 11 août 2026

Les webhooks poussent les événements vers votre serveur à l’instant où ils se produisent. Définissez l’URL du webhook 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’une relivraison à l’autre du même événement — fondez votre déduplication dessus. request_date est apposé à 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, ou l’objet abonnement (les formes sont sur les pages de référence correspondantes).

Les types d’événements

update_typeSe déclenche quandCharge utile
invoice_paidune facture est payée — toujours livréobjet facture
invoice_expiredune facture dépasse son échéance sans être payéeobjet facture
check_activatedl’un de vos chèques est récupéréobjet chèque
refund_completedun remboursement est exécutéobjet facture avec les champs refunded_*
subscription_activatedun utilisateur approuve une formuleobjet abonnement
subscription_chargedune période est facturée — charge.kind dit laquelle : initial, renewal ou resubscribeobjet abonnement + charge : {period_no, kind, asset, amount, fee, paid_at}
subscription_cancelledun abonnement est annulé par l’une des deux partiesobjet abonnement
subscription_expiredla période de grâce s’écoule sans paiementobjet abonnement

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 sur l’écran API marchand — les commutateurs apparaissent une fois une URL de webhook définie, et ils portent les identifiants bruts du tableau ci-dessus.

Vérifier la signature

Chaque livraison porte l’en-tête TgCryptoPay-API-Signature (Crypto-Pay-API-Signature est un 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["TgCryptoPay-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 dans le même geste.

Livraison et réessais

  • Une livraison est réussie sur toute réponse 2xx en moins de 10 secondes.
  • Tout le reste — un statut d’erreur, une expiration, un échec de connexion — est réessayé avec un délai exponentiel : le premier réessai après environ 10 secondes, l’écart doublant jusqu’à 8 heures, pour un maximum de 17 tentatives réparties sur environ 3 jours.
  • 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 — un point de terminaison capricieux ne désabonne pas votre application en silence.
  • Comme il y a des réessais, votre gestionnaire doit être idempotent : dédupliquez sur update_id avant d’agir.

⚠️ Vérifiez avant d’honorer

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.