Die kurze Antwort auf „Was ist ein Webhook?“: Wenn in einem System ein Ereignis eintritt (eine Zahlung wird eingezogen, ein Paket zugestellt, eine Bestellung storniert), sendet dieses System von sich aus eine HTTP-Anfrage an eine von Ihnen festgelegte Adresse. Bei einer normalen API stellen Sie die Frage; beim Webhook kommt die Nachricht zu Ihnen. Der Unterschied wirkt klein, verändert aber Kosten, Latenz und Angriffsfläche einer Integration von Anfang bis Ende. Dieser Artikel erklärt, wie Webhooks funktionieren, wo sie eingesetzt werden, was ein korrekt gebauter Empfänger leisten muss und was Sie vorab entwerfen müssen, wenn Ihr eigenes System Webhooks an andere senden soll. Nach diesen Regeln bauen wir die Integrationsschicht in Projekten für individuelle Software.
Webhook oder API: Was ist der Unterschied?
Beide sprechen über HTTP; der Unterschied liegt in Richtung und Zeitpunkt. Bei einer API sind Sie der Client: Sie fragen „Ist diese Bestellung bezahlt?“, und die Gegenseite meldet den aktuellen Zustand. Um die Antwort zu erfahren, klickt entweder ein Nutzer auf einen Button, oder Ihr System stellt dieselbe Frage in festen Abständen erneut; das nennt man Polling. Beim Webhook übergeben Sie eine Adresse („Melde dich hier, wenn eine Zahlung eingeht“), und das andere System sendet beim Ereignis eine POST-Anfrage dorthin. Sie fragen nicht, Sie hören zu. Die Grundbegriffe haben wir in Was ist eine API-Integration? erklärt; hier geht es nur um die Webhook-Seite.
Polling und Webhooks sind keine Konkurrenten, sondern ergänzen sich. Bei häufigen Ereignissen, auf die sofort reagiert werden muss (Zahlungsbestätigung, eingehende Nachricht), ist der Webhook das richtige Werkzeug: Ein System, das alle fünf Sekunden „Schon da?“ fragt, verschwendet Anfragen und ist im Schnitt trotzdem zweieinhalb Sekunden zu spät. Bei seltenen Ereignissen und einer Gegenseite ohne Webhooks bleibt nur Polling; das gilt für die meisten Buchhaltungsprogramme, siehe Integration von Buchhaltungssoftware.
So funktioniert ein Webhook, Schritt für Schritt
- Sie stellen in Ihrem System einen öffentlichen HTTPS-Endpunkt bereit, zum Beispiel /api/webhooks/payment. Er akzeptiert nur POST und erwartet keine Nutzersitzung.
- Sie registrieren diese URL im Dashboard oder über die API des Anbieters; der Anbieter gibt Ihnen einen geheimen Schlüssel (Secret).
- Tritt das Ereignis ein, sendet der Anbieter Typ und Daten als JSON an diese URL, mit einer aus dem Secret erzeugten Signatur im Request-Header.
- Ihr Server prüft die Signatur, speichert das Ereignis, antwortet dem Anbieter schnell mit 200 und erledigt die eigentliche Arbeit (Bestellung als bezahlt markieren, E-Mail senden) getrennt davon.
- Antwortet Ihr Server nicht oder zu spät mit 200, sendet der Anbieter dasselbe Ereignis in wachsenden Abständen erneut; deshalb kann ein Ereignis mehrfach ankommen.
Wo werden Webhooks eingesetzt?
In den Unternehmensprojekten, die wir sehen, tauchen Webhooks am häufigsten bei Zahlung, Versand, Marktplätzen und Messaging auf. Bei der Zahlungsintegration markiert nicht die Erfolgsseite des Nutzers die Bestellung als bezahlt, sondern der geprüfte Webhook des Anbieters. Bei der Versandintegration meldet der Paketdienst jede Statusänderung (in Zustellung, zugestellt, retourniert), und Ihre Sendungsverfolgung aktualisiert sich ohne Nachfrage. Bei der Marktplatz-Integration kommen neue Bestellungen und Stornierungen so an, bei der WhatsApp Business API eingehende Nachrichten und Zustellberichte. Gemeinsam ist allen: Das Ereignis passiert außerhalb Ihres Systems, und Sie kontrollieren den Zeitpunkt nicht.
Die erste Regel für Webhooks: Ein Webhook ist eine Benachrichtigung, nicht die Quelle der Wahrheit. Wurde das Geld wirklich eingezogen, wurde die Bestellung wirklich storniert? Im Zweifel prüfen Sie mit der Ereignis-ID über die API des Anbieters. Ein guter Empfänger vertraut Webhooks, ist aber nie allein von ihnen abhängig.
Webhook-Sicherheit: Signaturprüfung und doppelte Zustellungen
Ein Webhook-Endpunkt ist per Definition öffentlich; wer die Adresse kennt, kann eine gefälschte Anfrage mit „Zahlung eingegangen“ senden. Deshalb signiert jeder Anbieter die Anfrage mit dem Secret, und Sie berechnen die Signatur über den rohen Body neu und vergleichen. Zwei klassische Fehler: den Body erst als JSON zu parsen und dann zu signieren (Leerzeichen und Feldreihenfolge ändern sich, die Signatur passt nie) und mit einfacher Gleichheit zu vergleichen (anfällig für Timing-Angriffe). Das zweite große Thema sind doppelte Zustellungen: Bekommt der Anbieter keine 200, sendet er dasselbe Ereignis erneut; ist Ihre Geschäftslogik nicht pro Ereignis-ID eindeutig, wird der Bestand zweimal abgebucht oder es gehen zwei E-Mails für dieselbe Bestellung raus. Der folgende Next.js Route Handler setzt alle drei Regeln um: Signaturvergleich in konstanter Zeit über den rohen Body, Eindeutigkeit per Ereignis-ID und Auslagerung der schweren Arbeit in eine Queue, damit der Anbieter schnell eine Antwort bekommt.
// app/api/webhooks/payment/route.ts
import { createHmac, timingSafeEqual } from 'node:crypto';
import { NextResponse } from 'next/server';
export async function POST(req: Request) {
// Die Signatur wird über den ROHEN Body berechnet; kein JSON.parse vorher.
const raw = await req.text();
const received = req.headers.get('x-signature') ?? '';
const expected = createHmac('sha256', process.env.PAYMENT_WEBHOOK_SECRET!)
.update(raw)
.digest('hex');
// Vergleich in konstanter Zeit: verhindert Timing-Angriffe.
if (
received.length !== expected.length ||
!timingSafeEqual(Buffer.from(received), Buffer.from(expected))
) {
return new NextResponse('invalid signature', { status: 401 });
}
const event = JSON.parse(raw) as { id: string; type: string; data: unknown };
// Idempotenz: Kommt dasselbe Ereignis erneut, läuft die Logik nicht nochmal.
const isNew = await db.webhookEvents.insertIfAbsent({
id: event.id,
type: event.type,
payload: raw,
receivedAt: new Date(),
});
if (!isNew) return NextResponse.json({ ok: true, duplicate: true });
// Schwere Arbeit (Bestand, E-Mail, Rechnung) in die Queue; schnelle 200.
await queue.enqueue('process-webhook', { eventId: event.id });
return NextResponse.json({ ok: true });
}Das rohe Ereignis zu speichern ist keine leere Pedanterie. Schlägt der Job in der Queue fehl, können Sie den Datensatz erneut verarbeiten; streiten Sie mit dem Anbieter darüber, ob ein Ereignis zugestellt wurde, haben Sie Beweise; und wenn Sie ein neues Feld unterstützen, können Sie vergangene Ereignisse erneut einlesen. Queue und Fehlerverfolgung haben wir in Fehlerüberwachung und Logging beschrieben; ein Webhook-Empfänger ist das beste Beispiel für den dortigen „Stille-Alarm“, denn ein ausbleibender Webhook erzeugt keinen Fehler, er wird einfach still.
Was, wenn ein Webhook nie ankommt? Wiederholungen und Nachfüllen
Ist Ihr Server eine Stunde lang nicht erreichbar, gehen die Ereignisse dieser Stunde nicht verloren, aber wie lange sie wiederholt werden, hängt vom Anbieter ab: manche versuchen es einige Stunden, manche drei Tage, manche deaktivieren den Endpunkt nach fünf Fehlschlägen komplett. Deshalb werden zwei Dinge von Anfang an eingerichtet. Erstens: Die Wiederholungsrichtlinie des Anbieters und die Bedingung, unter der der Endpunkt deaktiviert wird, stehen im Übergabedokument. Zweitens: ein periodischer Abgleich: Einmal pro Nacht werden die Ereignisse oder Transaktionen der letzten 24 Stunden vom Anbieter abgerufen, mit Ihren Datensätzen verglichen und die Lücken verarbeitet. Der Webhook ist der schnelle Weg, der Abgleich der Sicherheitsgurt. Eine Integration ohne beides verliert eines Tages still Daten.
Wenn Ihr eigenes System Webhooks senden soll
Bauen Sie ein Händlerportal, ein SaaS-Produkt oder ein Unternehmens-Dashboard, wird eines Tages ein Kunde sagen: „Benachrichtigt unser System, wenn eine Bestellung angelegt wird.“ An diesem Tag müssen Sie alles liefern, was Sie von einem Empfänger erwartet haben: Ereignisse tragen eine eindeutige ID und einen Zeitstempel; jede Anfrage ist mit einem kundenspezifischen Secret signiert; Zustellungen laufen aus einer Queue, und fehlgeschlagene werden in wachsenden Abständen wiederholt (1 Min, 5 Min, 30 Min, 2 Std); das Kunden-Dashboard zeigt ein Zustellprotokoll und einen „Erneut senden“-Button. Am häufigsten übersehen wird die Versionierung der Ereignisse: Ein neues Feld hinzuzufügen ist in Ordnung, ein bestehendes Feld umzubenennen oder umzudeuten bricht die Integrationen Ihrer Kunden; das Ereignisschema ist Teil des Vertrags. Zum Design öffentlicher APIs siehe REST oder GraphQL, zur allgemeinen Angriffsfläche Website-Sicherheit.
Fünf Fehler, die ein Webhook-Projekt ruinieren
- Die Signatur nicht prüfen oder „später ergänzen“: Der Endpunkt ist öffentlich, er läuft vom ersten Tag an signiert.
- Die eigentliche Arbeit innerhalb der Webhook-Anfrage erledigen: Wird der Mailserver langsam, läuft der Anbieter in ein Timeout, sendet erneut, und die Arbeit wird doppelt gemacht.
- Die Ereignis-ID nicht speichern: Eine erneute Zustellung wird nicht erkannt, dieselbe Bestellung wird zweimal verarbeitet.
- Den Live-Webhook des Anbieters auf eine Testumgebung zeigen lassen: Test- und Live-Schlüssel sind getrennt, die Endpunkte müssen es auch sein.
- Den Webhook als einzige Quelle der Wahrheit behandeln: ohne Abgleichsjob fällt ein Ausfall erst auf, wenn ein Kunde anruft.
Fazit
Ein Webhook ist der schnellste und günstigste Weg, zwei Systeme zu verbinden; Ärger macht nicht der Webhook, sondern ein unvollständiger Empfänger. Signaturprüfung, Eindeutigkeit per Ereignis-ID, Queue und Abgleichsjob: Stehen diese vier Teile, läuft Ihre Zahlungs-, Versand-, Marktplatz- oder Messaging-Integration jahrelang still und zuverlässig. Wenn Sie ein Projekt mit Integrationsschicht planen, sehen Sie sich unser Angebot für individuelle Software an oder fordern Sie ein Angebot an; in der Discovery-Phase klären wir gemeinsam, welche Anbieter Webhooks bieten und wo Sie mit Polling und Abgleich arbeiten müssen.