tgpay cryptoAPI
crypto-payapiwebhookssignature

API-Referenz: Webhooks

3 Min. LesezeitAktualisiert 11. Aug. 2026

Webhooks schicken Ereignisse in dem Moment an deinen Server, in dem sie passieren. Lege die Webhook-URL deiner App unter Mehr → Händler-API fest; die Plattform sendet dann für jedes Ereignis, das du abonniert hast, per POST einen signierten JSON-Body.

Die Hülle

{
  "update_id": 123,
  "update_type": "invoice_paid",
  "request_date": "2026-08-11T12:00:00Z",
  "payload": {  }
}

update_id bleibt über alle erneuten Zustellungen desselben Ereignisses stabil – nutze es als Schlüssel für deine Deduplizierung. request_date wird pro Zustellversuch gesetzt. payload ist das vollständige Objekt zum jeweiligen Ereignistyp: das Rechnungsobjekt bei Rechnungsereignissen, das Scheckobjekt oder das Abo-Objekt (die Formate stehen auf den jeweiligen Referenzseiten).

Ereignistypen

update_typeWird ausgelöst, wennPayload
invoice_paideine Rechnung bezahlt wird – wird immer zugestelltRechnungsobjekt
invoice_expiredeine Rechnung unbezahlt ihre Frist überschreitetRechnungsobjekt
check_activatedeiner deiner Schecks eingelöst wirdScheckobjekt
refund_completedeine Rückerstattung ausgeführt wirdRechnungsobjekt mit den refunded_*-Feldern
subscription_activatedein Nutzer einem Plan zustimmtAbo-Objekt
subscription_chargedein Zeitraum abgerechnet wird – charge.kind sagt, welcher: initial, renewal oder resubscribeAbo-Objekt + charge: {period_no, kind, asset, amount, fee, paid_at}
subscription_cancelledein Abo von einer der beiden Seiten gekündigt wirdAbo-Objekt
subscription_expireddie Kulanzfrist unbezahlt abläuftAbo-Objekt

Alles außer invoice_paid ist optional zuschaltbar (eine Erweiterung gegenüber Crypto Bot – ein streng auf Crypto Bot zugeschnittener Empfänger begegnet nie einem unbekannten update_type, solange du ihn nicht angefordert hast). Schalte sie pro App unter Zusätzliche Webhook-Events auf dem Bildschirm Händler-API zu – die Schalter erscheinen, sobald eine Webhook-URL gesetzt ist, und sie sind mit den rohen Bezeichnern aus der Tabelle oben beschriftet.

Die Signatur prüfen

Jede Zustellung trägt den Header TgCryptoPay-API-Signature (Crypto-Pay-API-Signature ist ein Kompatibilitäts-Alias mit demselben Wert): den HMAC-SHA256 des rohen Anfrage-Bodys in Hex, mit dem SHA-256-Digest des Haupt-API-Tokens deiner App als Schlüssel. Es ist das Verfahren von Crypto Bot, bestehender Prüfcode funktioniert also unverändert:

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"])

Prüfe über die roh empfangenen Bytes – eine neu serialisierte Fassung kann sich Byte für Byte unterscheiden und die Prüfung scheitern lassen. Nur der Haupt-Token signiert; eingeschränkte Token tun das nie. Den Haupt-Token zu erneuern wechselt sofort den Schlüssel der Webhook-Signatur – aktualisiere das Geheimnis auf deinem Server also im selben Zug.

Zustellung und Wiederholungen

  • Eine Zustellung gilt bei jeder 2xx-Antwort innerhalb von 10 Sekunden als erfolgreich.
  • Alles andere – ein Fehlerstatus, ein Timeout, ein Verbindungsfehler – wird mit exponentiell wachsenden Abständen wiederholt: der erste Versuch nach etwa 10 Sekunden, der Abstand verdoppelt sich bis auf 8 Stunden, insgesamt bis zu 17 Versuche über rund 3 Tage verteilt.
  • Nach dem letzten Versuch wird die Zustellung verworfen. Die Webhook-URL selbst wird nie automatisch deaktiviert – ein unzuverlässiger Endpunkt meldet deine App nicht stillschweigend ab.
  • Weil es Wiederholungen gibt, muss dein Handler idempotent sein: dedupliziere anhand von update_id, bevor du handelst.

⚠️ Prüfe, bevor du lieferst

Jeder kann per POST an deine Webhook-URL senden. Solange die Signaturprüfung nicht bestanden ist, behandle den Body als nicht vertrauenswürdige Eingabe: Versende keine Bestellung, schreibe keinem Nutzer etwas gut, markiere nichts als bezahlt. Die sichere Reihenfolge ist: Signatur prüfen → anhand von update_id deduplizieren → handeln.