Was ist ein Webhook? Unterschied zu Polling und API-Abruf, mit Auswahlhilfe und Checkliste
Ein Webhook ist eine automatische Benachrichtigung: Tritt in einem System ein Ereignis ein, etwa eine bezahlte Bestellung, ruft dieses System von sich aus eine Internetadresse auf, die Sie vorher hinterlegt haben, und liefert die Daten gleich mit. Bei einem API-Abruf oder Polling fragen dagegen Sie selbst nach, ob es etwas Neues gibt. Webhooks eignen sich, wenn Sie schnell reagieren müssen und Ihr Empfänger öffentlich per HTTPS erreichbar ist. Dieser Artikel erklärt die Felder, die Sie in Shop, Zahlungsanbieter oder Automatisierungswerkzeug sehen, hilft bei der Wahl zwischen Webhook, Polling und Export und liefert eine Checkliste samt Testbefehl.
Stand 08.11.2026. Grundlage: Dokumentation von Stripe, GitHub, WooCommerce, n8n und curl.
- Was ein Webhook ist, in einem Absatz
- Webhook, API-Abruf und Polling: der Unterschied
- Was Sie in den Webhook-Feldern eintragen
- Webhook, Polling oder Export: welcher Weg passt?
- Checkliste für den Empfänger
- Den Empfänger testen: curl und Stripe CLI
- Was bei Ausfällen und Fehlern passiert
- Wann es komplizierter wird
- Vorbeugen: drei Gewohnheiten
Was ein Webhook ist, in einem Absatz
Stellen Sie sich einen Briefkasten vor: Statt jede Stunde beim Zahlungsanbieter nachzufragen, ob Geld eingegangen ist, hinterlegen Sie eine Adresse. Sobald etwas passiert, wirft der Anbieter eine Nachricht dort ein. Technisch ist das eine HTTP-Anfrage (meist POST) mit den Ereignisdaten, in der Regel als JSON. GitHub beschreibt es so: Sie geben eine URL an, und tritt ein abonniertes Ereignis ein, schickt GitHub die Daten dorthin. Ihr Server muss unter dieser Adresse erreichbar sein und die Anfrage annehmen.
Die Begriffe in den Einstellungen meinen dasselbe:
- Webhook-URL, Endpoint, Delivery URL, Payload URL: die Adresse des Empfängers.
- Trigger, Topic, Ereignistyp: das Ereignis, bei dem gesendet wird.
- Secret, Signing Secret: ein gemeinsames Geheimnis, mit dem der Empfänger prüfen kann, ob die Nachricht echt ist.
Webhook, API-Abruf und Polling: der Unterschied
Beim API-Abruf fragen Sie gezielt ab, etwa die Details einer Bestellung. Wiederholen Sie diese Abfrage im festen Takt, um Neues zu entdecken, heißt das Polling. Beim Webhook dreht sich die Richtung um: Die Gegenseite meldet sich, wenn etwas geschehen ist.
GitHub nennt in seiner Dokumentation die Vor- und Nachteile recht klar. Webhooks liefern Daten, sobald das Ereignis eintritt, und verbrauchen weniger Ressourcen als ständiges Nachfragen. Wer sehr viele Objekte per API überwacht, kann schnell sein Anfragelimit aufbrauchen. Braucht man die Information dagegen selten oder nur von wenigen Objekten, genügt ein normaler API-Abruf.
Beide Wege schließen sich nicht aus. Eine Webhook-Nachricht ist oft kurz und sagt nur, was passiert ist. Wenn Sie den aktuellen Stand eines Objekts brauchen, holen Sie ihn danach per API ab. Stripe bietet dafür neben vollständigen Ereignisobjekten („Snapshot“) auch schlanke Ereignisse („Thin“) an, bei denen Sie das zugehörige Objekt bei Bedarf über die API nachladen.
Was Sie in den Webhook-Feldern eintragen
In Shop- oder Zahlungseinstellungen begegnen Ihnen im Kern vier Angaben. Die Bezeichnungen unterscheiden sich je nach Anbieter:
| Angabe | Was gemeint ist | Beispiele aus der Praxis |
|---|---|---|
| Adresse | Wohin der Sender die Nachricht schickt. Sie gehört dem Empfänger, nicht dem Sender. | Stripe: Endpoint-URL im Format https://ihre-domain.de/pfad. WooCommerce: Delivery URL. |
| Geheimnis | Schlüssel für die Signatur. Wird beim Empfänger hinterlegt, damit er Fälschungen erkennt. | Stripe: Signing Secret, beginnt mit whsec_. WooCommerce: Feld „Secret“; bleibt das Feld leer, erzeugt WooCommerce beim Speichern ein zufälliges Secret. Hinterlegen Sie das tatsächlich gespeicherte Webhook-Secret beim Empfänger. |
| Ereignis | Wann gesendet wird. | Stripe: ausgewählte Ereignistypen. WooCommerce: Topic wie Bestellungen, Produkte, Kunden, Gutscheine. |
| Status | Ob der Webhook läuft. | WooCommerce: Active, Paused oder Disabled. |
In WooCommerce legen Sie einen Webhook unter WooCommerce > Settings > Advanced > Webhooks über „Add webhook“ an. Beim ersten Speichern mit dem Status Active sendet WooCommerce eine Ping-Nachricht an die Delivery URL.
Wenn ein Automatisierungswerkzeug der Empfänger ist
Bei n8n erzeugt der Webhook-Knoten die Adresse. n8n unterscheidet eine Test-URL, die nach „Listen for Test Event“ (bzw. „Execute workflow“ bei inaktivem Workflow) Daten im Editor anzeigt, und eine Production-URL, die erst nach dem Veröffentlichen des Workflows gilt. Beim Zahlungsanbieter oder Shop tragen Sie die Production-URL ein, sobald der Ablauf fertig ist. Die Test-URL taugt nur für den Probelauf. Zur Absicherung bietet der Knoten unter anderem Basic Auth, Header Auth und JWT.
Webhook, Polling oder Export: welcher Weg passt?
Die folgende Übersicht stellt die drei Wege nach den Kriterien gegenüber, die in der Praxis entscheiden. Die Angaben zu Webhook und Polling stützen sich auf die Dokumentation von Stripe, GitHub und WooCommerce; die Spalte „Export“ ist eine praktische Einordnung, keine Herstellerangabe.
| Kriterium | Webhook | Polling (API im Takt) | Export (Datei, Stapel) |
|---|---|---|---|
| Aktualität | Meldung kurz nach dem Ereignis | Verzögerung bis zum nächsten Abruf; ein kürzerer Takt bedeutet mehr Anfragen | Stand zum Zeitpunkt des Exports, etwa täglich |
| Ausfallsicherheit | Empfänger muss erreichbar sein. Stripe wiederholt automatisch bis zu drei Tage. GitHub und WooCommerce Core wiederholen fehlgeschlagene Zustellungen nicht automatisch. WooCommerce kann den Webhook nach aufeinanderfolgenden Zustellfehlern zusätzlich deaktivieren. | Empfänger holt später nach, solange die Quelle die Daten noch bereithält; dazu braucht er einen Merker „zuletzt abgeholt“ | Datei bleibt liegen, Import lässt sich wiederholen |
| Datenmenge | Einzelne Ereignisse; bei GitHub ist die Nutzlast auf 25 MB begrenzt | Auch größere Mengen, seitenweise; Anfragelimit beachten | Große Bestände, ganze Tabellen |
| Aufwand | Öffentlich erreichbarer HTTPS-Empfänger, Signaturprüfung, Schutz vor Doppelverarbeitung | Zeitplan, Merker, Umgang mit dem Anfragelimit | Gering beim Einrichten; Abgleich und Fehlersuche meist von Hand |
| Passt zum Beispiel für | Zahlung bestätigt, Bestellung angelegt, Code hochgeladen | Quelle ohne Webhooks; Empfänger nicht öffentlich erreichbar (Stripe verlangt eine öffentlich erreichbare HTTPS-Adresse) | Buchhaltungsübergabe, Monatsabschluss, Erstbefüllung |
So entscheiden Sie
- Reaktion binnen Sekunden nötig (Zugang freischalten, Lager buchen) und Empfänger öffentlich per HTTPS erreichbar: Webhook.
- Minuten oder Stunden Verzug sind in Ordnung, oder die Quelle bietet keine Webhooks: Polling.
- Große Datenmengen in festen Abständen, ohne Zeitdruck: Export.
- Geld oder Zugang hängen am Ereignis: Webhook als schnellen Auslöser einsetzen und zusätzlich in Abständen per API abgleichen. Stripe empfiehlt ausdrücklich, fehlende Objekte bei Bedarf über die API nachzuladen.
Checkliste für den Empfänger
Betreiben Sie den Empfänger selbst, etwa als PHP-Skript auf Ihrem Server, sollte er diese Punkte erfüllen:
- HTTPS mit gültigem Zertifikat. Bei Stripe ist HTTPS im Live-Modus Pflicht, unterstützt werden TLS 1.2 und 1.3. GitHub prüft Zertifikate standardmäßig und rät, das beizubehalten.
- Nur POST mit dem unveränderten Rohtext verarbeiten. Die Signatur wird über den Rohtext gebildet. Stripe warnt, dass jede Veränderung am Rohtext die Prüfung scheitern lässt; GitHub prüft die Signatur, bevor das JSON gelesen wird.
- Signatur prüfen. Stripe sendet den Header
Stripe-Signature(HMAC mit SHA-256, Zeitstempel inklusive; die offiziellen Bibliotheken tolerieren standardmäßig 5 Minuten Abweichung). GitHub sendetX-Hub-Signature-256mit dem Präfixsha256=. Vergleichen Sie Signaturen mit einer Funktion für konstante Laufzeit, nicht mit einem einfachen Gleichheitszeichen. WooCommerce sendet standardmäßig eine Base64-kodierte HMAC-SHA256-Signatur des unveränderten Payload-Bodys im HeaderX-WC-Webhook-Signature; das Secret dient dabei als Schlüssel. - Schnell mit 2xx antworten. GitHub erwartet die Antwort innerhalb von 10 Sekunden und wertet sonst die Zustellung als gescheitert. Stripe verlangt die 2xx-Antwort vor jeder aufwendigen Logik. Legen Sie die eigentliche Arbeit in eine Warteschlange.
- Doppelte Ereignisse erkennen (Idempotenz). Stripe empfiehlt, die Ereignis-IDs verarbeiteter Ereignisse zu speichern und bekannte zu überspringen. In einzelnen Fällen entstehen zwei getrennte Ereignisse; dann helfen die ID des Objekts in
data.objectund der Ereignistyp. Bei GitHub dient der HeaderX-GitHub-Deliveryals eindeutige Kennung; er bleibt bei einer erneuten Zustellung gleich. Antworten Sie auch bei einem erkannten Duplikat mit 2xx, damit der Sender nicht weiter wiederholt. - Keine feste Reihenfolge voraussetzen. Stripe garantiert nicht, dass Ereignisse in der erzeugten Reihenfolge ankommen. Verlassen Sie sich auch nicht auf den Zeitstempel
created, denn er hat Sekundenauflösung. - Wiederholungen und Nachholen einplanen. Protokollieren Sie jede Anfrage mit ID und Ergebnis. Entscheiden Sie vorab, wie Sie verpasste Ereignisse nachholen (siehe Abschnitt zu Ausfällen).
- Nur benötigte Ereignisse abonnieren und Signaturgeheimnisse schützen. Stripe rät davon ab, alle Ereignistypen zu empfangen. Zugangsdaten gehören laut GitHub nicht in die URL. Signaturgeheimnisse lassen sich bei Stripe austauschen; das alte Secret kann bis zu 24 Stunden parallel gültig bleiben.
Den Empfänger testen: curl und Stripe CLI
Bevor Sie einen Webhook im Live-Betrieb eintragen, schicken Sie dem Empfänger eine Probe. Prüfen Sie die Sicherheit und die Doppelverarbeitung in zwei getrennten Abläufen.
Ablauf 1: Sicherheitsprüfung
Der folgende Befehl sendet ein erfundenes JSON an Ihre Adresse. -i gibt die Statuszeile und die Antwortheader aus, sodass Sie den HTTP-Status unmittelbar sehen. --json setzt laut curl-Handbuch den Content-Type auf JSON und sendet per POST; die Option gibt es ab curl 7.82.0.
curl -i --json '{"id":"evt_test_001","type":"test.ereignis","data":{"nummer":"1001"}}' https://ihre-domain.de/webhook-empfaengerWas Sie erwarten dürfen: Hat Ihr Empfänger eine Signaturprüfung, muss er diese unsignierte Anfrage ablehnen (in den Stripe-Beispielen mit Status 400). Das ist ein gutes Ergebnis. Nimmt er sie mit 2xx an und löst eine Aktion aus, kann jeder, der die Adresse kennt, Ereignisse fälschen.
Ablauf 2: Doppelverarbeitung
Dieser Ablauf braucht ein korrekt signiertes Ereignis, denn ein geprüfter Empfänger lehnt die unsignierte Anfrage aus Ablauf 1 ab. Senden Sie dasselbe Ereignis zweimal, etwa über „Redeliver“ bei GitHub oder das manuelle erneute Senden bei Stripe. Bei gleicher Ereignis-ID darf nichts doppelt gebucht werden.
Für echte, korrekt signierte Testereignisse bietet Stripe die Stripe CLI. Erst leiten Sie Ereignisse an Ihren lokalen Empfänger weiter, in einem zweiten Terminal lösen Sie ein Beispielereignis aus:
stripe listen --forward-to localhost:4242/webhook
stripe trigger payment_intent.succeededDer erste Befehl gibt das Signing Secret für den lokalen Test aus. Er läuft laut Stripe in der CLI im Terminal, nicht in der Workbench Shell. Ohne öffentliche HTTPS-Adresse kann alternativ ein Tunneldienst wie ngrok eine temporäre Adresse bereitstellen.
Bei GitHub lassen sich zurückliegende Zustellungen über die Webhook-Einstellungen erneut senden („Redeliver“), bei n8n hilft „Listen for Test Event“. Fertige Testvorlagen für PHP-Empfänger finden Sie im Prüfpaket für Webhooks.
Testen Sie mit erfundenen Daten und nach Möglichkeit gegen ein Testsystem. Ein Beispielereignis, das im Live-Shop eine Rechnung oder Freischaltung anstößt, ist schwer zurückzunehmen.
Was bei Ausfällen und Fehlern passiert
Jeder Anbieter geht anders damit um, wenn Ihr Empfänger nicht oder falsch antwortet:
| Anbieter | Was als Erfolg zählt | Wiederholung |
|---|---|---|
| Stripe | 2xx. Weiterleitungen (3xx) werten sie als Fehler. | Live: automatisch bis zu drei Tage mit zunehmenden Abständen. Sandbox: dreimal binnen weniger Stunden. Manuell erneut senden: im Dashboard bis 15 Tage, per CLI bis 30 Tage nach dem Ereignis. |
| GitHub | 2xx binnen 10 Sekunden | Keine automatische Wiederholung. Erneutes Senden von Hand oder per API für Zustellungen der letzten 3 Tage. |
| WooCommerce | 2xx, 301 oder 302 | Keine automatische Wiederholung im WooCommerce Core. Nach aufeinanderfolgenden Fehlzustellungen setzt WooCommerce den Webhook auf „Disabled“. Der Schwellenwert (Standard 5) lässt sich per Filter woocommerce_max_webhook_delivery_failures ändern. Protokolle: WooCommerce > Status > Logs, Quelle webhooks-delivery. |
Daraus folgt für den Alltag: Ein Webhook, den WooCommerce deaktiviert hat, liefert nichts mehr, bis Sie ihn wieder auf Active stellen. Ereignisse aus der Zwischenzeit kommen nicht von selbst nach. Prüfen Sie den Status deshalb gelegentlich, und gleichen Sie nach einem Ausfall die betroffene Zeit per API oder Export ab.
Was bei Zahlungsanbietern konkret schiefgehen kann, etwa eine bezahlte Bestellung ohne Zugang, steht im Artikel Stripe-Webhook: bezahlt, aber kein Zugang.
Wann es komplizierter wird
Der einfache Fall ist eine Verbindung zwischen zwei Standardprodukten, bei der ein Werkzeug wie n8n den Empfang übernimmt: Adresse eintragen, Ereignis wählen, Testlauf, fertig. Aufwendiger wird es in diesen Lagen:
- Eigener Empfänger: Signaturprüfung, Rohtext, Idempotenz und Warteschlange müssen Sie selbst sauber umsetzen. Fehler hier bleiben oft unbemerkt, bis ein Ereignis doppelt oder gar nicht verarbeitet wird.
- Hohe Last: Stripe weist darauf hin, dass Spitzen, etwa zum Monatsanfang bei erneuerten Abos, einen synchron arbeitenden Empfänger überfordern können. Eine Warteschlange glättet das.
- Abhängigkeiten zwischen Ereignissen: Kommt „Rechnung bezahlt“ vor „Abo angelegt“ an, muss der Empfänger das fehlende Objekt selbst per API holen.
- Mehrere Systeme in einer Kette: Shop, Zahlung, Lager und Buchhaltung gleichzeitig zu verbinden, ist eher eine Integrationsaufgabe als eine Einstellung. Hierzu gibt es einen Überblick unter Schnittstellen und Integration.
Vorbeugen: drei Gewohnheiten
- Legen Sie nach dem Einrichten einen Testlauf an und notieren Sie, welches Ereignis welche Aktion auslösen soll.
- Prüfen Sie regelmäßig den Zustellstatus beim Sender (Stripe: Reiter „Event deliveries“, WooCommerce: Status des Webhooks und Log).
- Planen Sie für wichtige Ereignisse einen Abgleich ein, der fehlende Daten über die API oder einen Export nachholt.
Wer einen eigenen Empfänger in PHP betreibt, kann Signaturprüfung, schnelle Antwort und Doppelverarbeitung mit Testanfragen durchspielen, bevor echte Ereignisse eintreffen. Dafür sind die Webhook-Testvorlagen für PHP im Prüfpaket gedacht.
Mehr dazu: Webhook-Testvorlagen für PHP
Quellen
- Stripe: Webhook-Endpoint einrichten, absichern und testen, docs.stripe.com
- GitHub: Über Webhooks, docs.github.com
- GitHub: Best Practices für Webhooks, docs.github.com
- GitHub: Webhook-Zustellungen validieren, docs.github.com
- GitHub: Webhooks erneut zustellen, docs.github.com
- GitHub: Webhook-Ereignisse und Payloads, docs.github.com
- WooCommerce: Webhooks, woocommerce.com
- WooCommerce Developer Docs: Webhooks, developer.woocommerce.com
- WooCommerce: Admin-Quellcode, Secret-Verarbeitung, woocommerce.github.io
- WooCommerce: Fehlerbehandlung in class-wc-webhook.php, raw.githubusercontent.com
- n8n: Webhook-Knoten, docs.n8n.io
- n8n: Workflow development, localhost mit Tunnel, docs.n8n.io
- curl: Handbuch, curl.se
Alle Quellen gelesen am 08.11.2026.
Erstellt von der Redaktion Die Netzhandwerker mit KI-Unterstützung. Die Sachangaben wurden vor der Veröffentlichung automatisch gegen die genannten Quellen geprüft.