Webhooks erklärt: Signierte Payloads und Retries

Backend2026-10-08TryQuickToolBox

Du hast gerade ein Zahlungs-Gateway über Webhooks integriert. Im Test funktioniert alles einwandfrei, doch in der Produktion gehen manchmal Events verloren oder du erhältst doppelte Benachrichtigungen, die zu Doppelabbuchungen führen. Die Ursache liegt oft darin, wie du signierte Payloads und Retries handhabst. Dieser Artikel erklärt die Mechanik von Webhooks und liefert praktische Schritte für eine robuste, sichere Integration.

Was sind Webhooks?

Webhooks sind benutzerdefinierte HTTP-Callbacks. Wenn ein Ereignis in einem Quellsystem auftritt (z. B. eine Zahlung wird verarbeitet), sendet es eine HTTP-POST-Anfrage an eine von dir angegebene URL, die die Ereignisdaten enthält. Im Gegensatz zum Polling übertragen Webhooks Daten nahezu in Echtzeit, was Latenz und Serverlast reduziert.

Allerdings bringen Webhooks Herausforderungen mit sich: die Authentizität zu verifizieren, Fehler zu behandeln und eine Exactly-once-Verarbeitung sicherzustellen. Packen wir jede einzelne an.

Signierte Payloads: Authentizität verifizieren

Da Webhook-Endpunkte öffentlich erreichbar sind, könnte jeder gefälschte Anfragen senden. Um das zu verhindern, signieren Anbieter die Payload mit einem geheimen Schlüssel. Du verifizierst die Signatur, um sicherzustellen, dass die Anfrage echt ist.

Wie HMAC-Signaturen funktionieren

Die meisten Anbieter verwenden HMAC (Hash-based Message Authentication Code) mit SHA-256. Der Anbieter berechnet eine Signatur aus dem Request-Body und einem gemeinsamen Secret und fügt sie in einen Header ein (z. B. X-Signature). Du berechnest die Signatur auf deiner Seite neu und vergleichst sie.

Beispiel in Python:

import hmac
import hashlib

def verify_signature(payload, secret, received_signature):
    expected = hmac.new(secret.encode(), payload, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, received_signature)

Wichtig: Verwende den rohen Request-Body, nicht das geparste JSON, da das Parsen Whitespace verändern und die Signatur brechen kann.

Häufige Fallstricke

Retries: Fehler souverän behandeln

Dein Endpunkt könnte vorübergehend nicht erreichbar sein, oder Netzwerkprobleme könnten Fehler verursachen. Zuverlässige Webhook-Systeme wiederholen fehlgeschlagene Zustellungen mit exponentiellem Backoff.

Retry-Strategien

Anbieter wiederholen in der Regel bei Nicht-2xx-Antworten oder Timeouts. Gängige Muster:

StrategieBeschreibungBeispiel
Festes IntervallAlle N Sekunden wiederholenAlle 30s, bis zu 5-mal
Exponentielles BackoffVerzögerung bei jedem Versuch verdoppeln1s, 2s, 4s, 8s...
Exponentiell mit JitterZufälligkeit hinzufügen, um Thundering Herd zu vermeiden1s ± 0,5s, 2s ± 1s...

Als Empfänger kannst du die Retry-Policy des Senders nicht steuern, aber du kannst deinen Endpunkt widerstandsfähig gestalten.

Best Practices für Empfänger

  1. Schnell antworten: Gib innerhalb weniger Sekunden 2xx zurück. Verlage die Verarbeitung in einen Hintergrund-Job.
  2. Idempotent sein: Nutze einen Idempotency-Key aus der Payload, um doppelte Verarbeitung zu vermeiden.
  3. Alles loggen: Speichere eingehende Webhooks für Debugging und Replay.
  4. Fehler überwachen: Richte Alerts für wiederholte Fehler ein.

Idempotenz implementieren

Duplikate passieren: Der Sender könnte erneut versuchen, weil deine Antwort langsam war, oder du verarbeitest dasselbe Event versehentlich zweimal. Idempotenz stellt sicher, dass die mehrfache Verarbeitung eines Events dieselbe Wirkung hat wie eine einmalige.

Verwende eine eindeutige Event-ID (oft in der Payload oder den Headern enthalten) und speichere sie mit einem Unique-Constraint in einer Datenbank. Prüfe vor der Verarbeitung, ob die ID existiert; falls ja, überspringe sie.

def process_event(event_id, data):
    if EventLog.exists(event_id):
        return  # already processed
    EventLog.create(event_id)
    # process data...

Für Systeme mit hohem Durchsatz nutze einen verteilten Lock oder eine Datenbanktransaktion, um Race Conditions zu vermeiden.

Sicherheitsüberlegungen

Über die Signaturverifikation hinaus solltest du beachten:

Webhooks lokal testen

Während der Entwicklung brauchst du eine öffentliche URL, um Webhooks zu empfangen. Tools wie ngrok oder localtunnel machen deinen lokalen Server erreichbar. Alternativ bieten viele Anbieter eine CLI, um Events an deinen localhost weiterzuleiten.

Simuliere Fehler, um die Retry-Behandlung zu testen: Gib absichtlich 500-Fehler zurück und beobachte das Retry-Muster des Anbieters.

FAQ

Wie verifiziere ich eine Webhook-Signatur?

Verwende HMAC mit dem gemeinsamen Secret. Berechne den Hash des rohen Request-Bodys und vergleiche ihn mit dem Signatur-Header mithilfe einer konstantzeitigen Vergleichsfunktion.

Was soll ich tun, wenn ich doppelte Webhooks erhalte?

Implementiere Idempotenz, indem du Event-IDs speicherst. Prüfe, ob das Event bereits verarbeitet wurde, bevor du die Geschäftslogik ausführst.

Kann ich mich allein auf Webhook-Retries verlassen?

Nein. Retries helfen, können aber die Zustellung nicht garantieren. Kombiniere für kritische Events Webhooks mit einem Polling-Fallback oder einer Message Queue, die Events persistiert.

Beim Debuggen von Webhook-Payloads musst du manchmal JSON-Daten inspizieren. Nutze unseren JSON Formatter, um Payloads schnell übersichtlich zu formatieren und zu validieren.