tgpay cryptoAPI
crypto-payapiwebhookssignature

API-Referenz: Webhooks

3 Min. LesezeitAktualisiert 9. Okt. 2026

Webhooks schicken Ereignisse an deinen Server, nachdem sie eingetreten sind. Trage unter Mehr → Händler-API im Feld Webhook-URL (optional) die URL deiner App ein; die Plattform sendet dann für jedes Ereignis, das du abonniert hast, per POST einen signierten JSON-Body.

Nachrichtenformat

{
  "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, das Überweisungsobjekt oder das Abo-Objekt (die Formate stehen auf den jeweiligen Referenzseiten).

Ereignistypen

update_typeWird ausgelöst, wennPayload
invoice_paideine Rechnung bezahlt wird – keine gesonderte Aktivierung nötigRechnungsobjekt
invoice_expiredeine Rechnung unbezahlt ihre Frist überschreitetRechnungsobjekt
check_activatedein Scheck oder der Anteil eines Empfängers eingelöst wirdScheckobjekt; bei einer Empfängerliste zusätzlich activated_slot
check_expiredein Scheck mit Empfängerliste abläuft und nicht eingelöste Anteile zur App zurückkehrenScheckobjekt mit recipients und deren claimed_at-Werten
transfer_completedeine Überweisung abgeschlossen oder eine On-Chain-Auszahlung bestätigt wirdÜberweisungs- oder Auszahlungsobjekt
transfer_returnedeine nicht eingelöste ausstehende Überweisung zur App zurückkehrt oder eine On-Chain-Auszahlung fehlschlägt und der einbehaltene Betrag zurückgegeben wirdÜberweisungs- oder Auszahlungsobjekt
refund_completedeine Rückerstattung ausgeführt wirdRechnungsobjekt mit den refunded_*-Feldern
subscription_activatedein Nutzer einem Plan zustimmtAbo-Objekt
subscription_chargeddie Zahlung für einen Zeitraum eingezogen 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

In der App erstellte On-Chain-Auszahlungen verwenden dieselben Überweisungsereignisse. Ihr Payload enthält kind: "withdrawal", Blockchain-Felder wie network, address und txid sowie den Status completed oder failed. Ihre transfer_id gehört zu einer separaten ID-Folge. Unterscheide deshalb anhand von kind, bevor du die ID verwendest. Die herunterladbare OpenAPI-Referenz beschreibt beide Payload-Varianten.

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 im Bereich Webhook zu. Die Schalter tragen die Bezeichner aus der Tabelle oben. Speichere eine Webhook-URL, damit Ereignisse zugestellt werden können.

Die Signatur prüfen

Jede Zustellung trägt den Header TgPayCrypto-API-Signature (TgCryptoPay-API-Signature und Crypto-Pay-API-Signature gelten als 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["TgPayCrypto-API-Signature"])

Berechne die Signatur aus den 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 einer 2xx-Antwort vor Ablauf des Zustellversuchs als erfolgreich. Antworte zügig und verarbeite längere Aufgaben separat.
  • Ein Fehlerstatus, Timeout oder Verbindungsfehler führt zu Wiederholungen mit wachsenden Abständen, bis zum Versuchslimit der Plattform. Die Zustellung ist nicht garantiert; gleiche Zahlungen nach einem Ausfall mit getInvoices ab.
  • 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.