{"id":18049,"date":"2026-09-24T12:00:02","date_gmt":"2026-09-24T06:15:02","guid":{"rendered":"https:\/\/www.bay20.com\/de\/?p=18049"},"modified":"2026-09-24T12:29:12","modified_gmt":"2026-09-24T06:44:12","slug":"wie-richtet-man-bigcommerce-webhooks-ein-und-ueberprueft-sie","status":"publish","type":"post","link":"https:\/\/www.bay20.com\/de\/wie-richtet-man-bigcommerce-webhooks-ein-und-ueberprueft-sie\/","title":{"rendered":"Wie richtet man BigCommerce-Webhooks ein und \u00fcberpr\u00fcft sie?"},"content":{"rendered":"\n<p>Die meisten <a href=\"https:\/\/www.bay20.com\/de\/bigcommerce-entwicklungsunternehmen\/\" target=\"_blank\" rel=\"noopener\" title=\"\">BigCommerce<\/a>-Integrationen beginnen mit einer Abfrage. Sie richten ein Skript ein, das alle paar Minuten den \u201eOrders\u201c-Endpunkt, den \u201eProducts\u201c-Endpunkt oder eine andere f\u00fcr Sie relevante Ressource \u00fcberpr\u00fcft, und die meisten dieser \u00dcberpr\u00fcfungen liefern keine neuen Ergebnisse. Das funktioniert zwar, ist aber ineffizient und schr\u00e4nkt die Reaktionsgeschwindigkeit Ihres Systems auf \u00c4nderungen ein. Webhooks l\u00f6sen dieses Problem auf elegante Weise: Anstatt dass Ihr Code bei BigCommerce nachfragt, ob sich etwas ge\u00e4ndert hat, informiert BigCommerce Sie sofort, sobald dies der Fall ist. Die Registrierung eines Webhooks erfordert lediglich einen einzigen API-Aufruf. Das Vertrauen in die Daten, die anschlie\u00dfend an Ihrem Endpunkt ankommen, ist der Teil, der tats\u00e4chlich etwas Sorgfalt erfordert \u2013 und genau diesen Teil lassen die meisten Tutorials au\u00dfer Acht.<\/p>\n\n\n\n<p>\u00dcbersetzt mit DeepL.com (kostenlose Version)<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"980\" height=\"421\" src=\"https:\/\/www.bay20.com\/de\/wp-content\/uploads\/2026\/09\/bigcommerce-webhook-980x421.png\" alt=\"\" class=\"wp-image-18043\" srcset=\"https:\/\/www.bay20.com\/de\/wp-content\/uploads\/2026\/09\/bigcommerce-webhook-980x421.png 980w, https:\/\/www.bay20.com\/de\/wp-content\/uploads\/2026\/09\/bigcommerce-webhook-300x129.png 300w, https:\/\/www.bay20.com\/de\/wp-content\/uploads\/2026\/09\/bigcommerce-webhook-768x330.png 768w, https:\/\/www.bay20.com\/de\/wp-content\/uploads\/2026\/09\/bigcommerce-webhook-800x344.png 800w, https:\/\/www.bay20.com\/de\/wp-content\/uploads\/2026\/09\/bigcommerce-webhook.png 1000w\" sizes=\"auto, (max-width: 980px) 100vw, 980px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Einen Webhook erstellen<\/h2>\n\n\n\n<p>Hierf\u00fcr gibt es keine Umschaltfunktion im Dashboard; Webhooks sind ausschlie\u00dflich \u00fcber die API verf\u00fcgbar. Sie k\u00f6nnen einen Webhook mit einer POST-Anfrage an den Endpunkt \/v3\/hooks erstellen.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>POST https:\/\/api.bigcommerce.com\/stores\/{store_hash}\/v3\/hooks\nX-Auth-Token: {access_token}\nContent-Type: application\/json\nAccept: application\/json\n\n{\n  \"scope\": \"store\/order\/statusUpdated\",\n  \"destination\": \"https:\/\/yourapp.example.com\/webhooks\",\n  \"is_active\": true,\n  \"headers\": {}\n}<\/code><\/pre>\n\n\n\n<p>Als \u201escope\u201c gibt man das <a href=\"https:\/\/docs.bigcommerce.com\/developer\/docs\/integrations\/webhooks\/event-reference\/events\" target=\"_blank\" rel=\"noopener\" title=\"\">Ereignis<\/a> an, \u00fcber das man informiert werden m\u00f6chte: \u201estore\/order\/created\u201c, \u201estore\/product\/updated\u201c, \u201estore\/cart\/abandoned\u201c usw. Als \u201edestination\u201c wird angegeben, wohin die Nutzdaten gesendet werden sollen; dabei muss es sich um eine HTTPS-Verbindung auf dem Standardport 443 handeln. Benutzerdefinierte Ports werden nicht unterst\u00fctzt, versuchen Sie es also gar nicht erst. Das \u201eheaders\u201c-Objekt ist optional, aber es lohnt sich trotzdem, es zu verwenden. Alle Schl\u00fcssel-Wert-Paare, die du dort hinterlegst, werden bei jedem Callback zur\u00fcckgesendet. Das bietet dir eine einfache M\u00f6glichkeit, zus\u00e4tzlich zur ordnungsgem\u00e4\u00dfen Signaturpr\u00fcfung ein gemeinsames Geheimnis oder eine Basic-Authentifizierung einzubinden.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Einschr\u00e4nkungen, die man im Voraus kennen sollte<\/h3>\n\n\n\n<p>Einige Einschr\u00e4nkungen sind hier erst dann offensichtlich, wenn man bereits darauf gesto\u00dfen ist:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Es kann bis zu einer Minute dauern, bis ein neu erstellter Webhook tats\u00e4chlich zu funktionieren beginnt. Keine Panik, wenn Ihr erstes Testereignis nicht sofort angezeigt wird \u2013 der Webhook ist nicht defekt, sondern hat sich einfach noch nicht \u201eaufgew\u00e4rmt\u201c.<\/li>\n\n\n\n<li>Pro eindeutiger Kombination aus Shop, API-Client und Geltungsbereich stehen dir maximal 10 Webhooks zur Verf\u00fcgung. Und pro Shop, Client, Geltungsbereich und Ziel ist jeweils nur ein Webhook zul\u00e4ssig \u2013 die doppelte Registrierung desselben Geltungsbereichs, der auf dieselbe URL verweist, funktioniert also nicht.<\/li>\n\n\n\n<li>Webhooks sind nur f\u00fcr das Token sichtbar, das sie erstellt hat. Es gibt keine M\u00f6glichkeit, eine Liste aller Webhooks f\u00fcr alle Token eines Shops abzurufen, was wirklich \u00e4rgerlich ist, wenn du eine Multi-App-Konfiguration debugst und herausfinden willst, warum ein Ereignis nicht dort angezeigt wird, wo du es erwarten w\u00fcrdest.<\/li>\n\n\n\n<li>Ein Abonnement wird nach 90 Tagen Inaktivit\u00e4t automatisch und ohne Benachrichtigung deaktiviert. Wenn du einen Bereich mit geringem Datenverkehr hast, lohnt es sich, eine regelm\u00e4\u00dfige \u00dcberpr\u00fcfung einzubauen, ob der Webhook noch aktiv ist, anstatt erst drei Monate sp\u00e4ter festzustellen, dass er einfach aufgeh\u00f6rt hat zu funktionieren.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Die Nutzlast gibt absichtlich nicht viele Informationen preis.<\/h2>\n\n\n\n<p>Wenn ein Ereignis ausgel\u00f6st wird, \u00fcbergibt BigCommerce Ihnen nicht die vollst\u00e4ndige Ressource. Es reicht gerade aus, um zu erkennen, dass sich etwas ge\u00e4ndert hat und wo Sie danach suchen m\u00fcssen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"store_id\": \"1000\",\n  \"producer\": \"stores\/abc123\",\n  \"scope\": \"store\/order\/statusUpdated\",\n  \"data\": {\n    \"type\": \"order\",\n    \"id\": 173331\n  },\n  \"hash\": \"...\",\n  \"created_at\": 1561479335\n}<\/code><\/pre>\n\n\n\n<p>Wenn Sie die Bestelldetails tats\u00e4chlich ben\u00f6tigen, erfolgt dies \u00fcber einen separaten Aufruf der REST-API unter Verwendung der in \u201edata\u201c enthaltenen ID. Das \u00fcberrascht viele beim ersten Mal; man hat das Gef\u00fchl, der Webhook sollte einem einfach alles auf Anhieb liefern, doch die geringe Datenmenge ist beabsichtigt. Dadurch bleibt die \u00dcbertragung schnell, und es wird sichergestellt, dass die Daten, auf deren Grundlage Sie handeln, nicht bereits veraltet sind, wenn Sie dazu kommen, den Webhook-Text zu lesen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Die meisten Menschen verzichten darauf, die Signatur zu \u00fcberpr\u00fcfen<\/h2>\n\n\n\n<p>Die \u00dcberpr\u00fcfung der Signatur ist der Schritt, den viele \u00fcberspringen \u2013 und ehrlich gesagt ist genau dieser Schritt am wichtigsten. Jeder, der zuf\u00e4llig auf Ihre Ziel-URL st\u00f6\u00dft, kann eine gef\u00e4lschte Nutzlast per POST an diese senden, wenn Sie nicht \u00fcberpr\u00fcfen, woher die Anfrage tats\u00e4chlich stammt. BigCommerce signiert seine Webhook-Anfragen gem\u00e4\u00df der Standard-Webhooks-Spezifikation, sodass sich die \u00dcberpr\u00fcfung auf drei Header beschr\u00e4nkt: \u201ewebhook-id\u201c, \u201ewebhook-timestamp\u201c und \u201ewebhook-signature\u201c.<\/p>\n\n\n\n<p>Die Signatur selbst ist ein HMAC-SHA256, der \u00fcber {webhook-id}.{webhook-timestamp}.{raw request body} berechnet und mit dem Client-Secret Ihrer App signiert wird. Auf Ihrer Seite berechnen Sie denselben HMAC mit Ihrem Client-Secret neu und vergleichen ihn mit der von BigCommerce \u00fcbermittelten Signatur. Der Zeitstempel dient speziell dem Schutz vor Replay-Angriffen; \u00fcberpr\u00fcfen Sie daher auch, ob er tats\u00e4chlich aktuell ist \u2013 eine \u00dcbereinstimmung der Signaturen allein reicht nicht aus.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">So k\u00f6nnen Sie die Signatur \u00fcberpr\u00fcfen:<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>import crypto from \"crypto\";\n\nfunction verifyWebhookSignature(rawBody, headers, clientSecret) {\n  const webhookId = headers&#91;\"webhook-id\"];\n  const timestamp = headers&#91;\"webhook-timestamp\"];\n  const receivedSignature = headers&#91;\"webhook-signature\"]; \/\/ format: \"v1,&lt;base64&gt;\"\n\n  \/\/ reject anything more than a few minutes old, guards against replay\n  const age = Math.abs(Date.now() \/ 1000 - Number(timestamp));\n  if (age &gt; 300) return false;\n\n  const signedContent = `${webhookId}.${timestamp}.${rawBody}`;\n  const secretBytes = Buffer.from(clientSecret, \"base64\");\n  let expectedSignature = crypto\n    .createHmac(\"sha256\", secretBytes)\n    .update(signedContent)\n    .digest(\"base64\");\n\n  const receivedSigValue = receivedSignature.split(\",\")&#91;1] || \"\";\n\n  return crypto.timingSafeEqual(\n    Buffer.from(expectedSignature),\n    Buffer.from(receivedSigValue)\n  );\n}<\/code><\/pre>\n\n\n\n<p>Zwei Dinge sollten hier gesondert hervorgehoben werden, da dies die beiden Fehlerquellen sind, die beim ersten Versuch h\u00e4ufig auftreten. Damit dies \u00fcberhaupt funktioniert, ben\u00f6tigen Sie den rohen, noch nicht geparsten Body. Wenn der Body-Parser Ihres Frameworks die Anfrage zum Zeitpunkt der \u00dcberpr\u00fcfung bereits in ein JSON-Objekt umgewandelt hat, stimmt der Hash nicht \u00fcberein, da sowohl Leerzeichen als auch die Reihenfolge der Schl\u00fcssel einen Einfluss darauf haben. Rufen Sie den rohen Body ab, bevor irgendeine Parsing-Middleware darauf zugreift. Und verwenden Sie \u201etimingSafeEqual\u201c anstelle eines einfachen \u201e===\u201c \u2013 ein normaler String-Vergleich gibt Zeitinformationen preis, die es theoretisch erm\u00f6glichen, die Signatur Byte f\u00fcr Byte zu erraten.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Schnell antworten, die eigentliche Arbeit sp\u00e4ter erledigen<\/h2>\n\n\n\n<p>BigCommerce erwartet eine schnelle HTTP-200-Antwort \u2013 und das ist auch so gemeint. Wenn Ihr Endpunkt zu lange braucht, um zu antworten, wird die \u00dcbermittlung als fehlgeschlagen markiert und in die Wiederholungswarteschlange verschoben, selbst wenn Ihr Code eigentlich einwandfrei funktioniert hat \u2013 nur eben langsam. Die L\u00f6sung besteht darin, den Webhook sofort zu best\u00e4tigen und die eigentliche Verarbeitung an eine andere Stelle zu verlagern \u2013 eine Warteschlange, einen Hintergrundjob oder was auch immer Ihr Stack daf\u00fcr bereits verwendet:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>app.post(\"\/webhooks\", express.raw({ type: \"application\/json\" }), (req, res) =&gt; {\n  const isValid = verifyWebhookSignature(req.body, req.headers, process.env.BC_CLIENT_SECRET);\n  if (!isValid) return res.sendStatus(401);\n\n  const event = JSON.parse(req.body);\n  res.sendStatus(200);\n  processEventAsync(event);\n});<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Wiederholungsversuche verhalten sich nicht ganz so, wie man vermuten w\u00fcrde<\/h2>\n\n\n\n<p>Hier ist ein Detail, das man leicht \u00fcbersieht, bis es einem zum Verh\u00e4ngnis wird: BigCommerce entscheidet anhand der Reaktion Ihrer gesamten Domain, ob ein Wiederholungsversuch unternommen wird \u2013 nicht f\u00fcr jeden einzelnen Webhook. Wenn Sie also zwei separate Webhooks haben, die auf yourapp.com\/webhook-1 und yourapp.com\/webhook-2 verweisen, kann ein Fehler bei einem davon das Wiederholungsverhalten des anderen beeinflussen, da BigCommerce die Domain als Ganzes \u00fcberwacht und nicht jeden Endpunkt einzeln. Das sollten Sie bedenken, wenn Sie mehrere Abonnements betreiben und davon ausgehen, dass diese jeweils unabh\u00e4ngig voneinander ausfallen und wiederhergestellt werden. Das ist jedoch nicht der Fall.<\/p>\n\n\n\n<p>Fehlgeschlagene \u00dcbermittlungen werden etwa 48 Stunden lang erneut versucht. Nach Ablauf dieses Zeitfensters deaktiviert sich der Webhook von selbst. Ein versteckter Fehler, der Ihren Handler zwei Tage lang lahmlegt, hinterl\u00e4sst also nicht nur einen R\u00fcckstand, den Sie aufarbeiten m\u00fcssen, sondern f\u00fchrt letztendlich dazu, dass die Ereignisse g\u00e4nzlich ausbleiben. Es lohnt sich, auf Ihrer Seite eine Art Warnung f\u00fcr eine Reihe aufeinanderfolgender 4xx- oder 5xx-Antworten einzurichten, anstatt erst durch ein Support-Ticket zu erfahren, dass die Auftragssynchronisierung bereits vor drei Wochen unbemerkt eingestellt wurde.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Rauschen mit Datenfiltern reduzieren<\/h2>\n\n\n\n<p>Wenn Sie sich nur f\u00fcr einen Teil der Ereignisse innerhalb eines bestimmten Bereichs interessieren, unterst\u00fctzt BigCommerce Datenfilter, sodass Sie nicht selbst irrelevante Ereignisse aussortieren m\u00fcssen, nachdem diese bereits eingegangen sind. Anstatt jedes einzelne \u201estore\/order\/statusUpdated\u201c-Ereignis zu erhalten, unabh\u00e4ngig davon, wie sich der Status ge\u00e4ndert hat, k\u00f6nnen Sie nach Werten im Datenobjekt der Nutzlast filtern und lassen sich nur diejenigen zusenden, auf die Sie tats\u00e4chlich reagieren m\u00f6chten. Es lohnt sich, dies von Anfang an einzurichten, anstatt Filterlogik in Ihren Handler zu schreiben, die die API eigentlich f\u00fcr Sie h\u00e4tte \u00fcbernehmen k\u00f6nnen.<\/p>\n\n\n\n<p><strong>Kontaktieren Sie uns:<\/strong> wargis@bay20.com\/manish@bay20.com | +91-9582784309\/+91-8800519185 oder besuchen Sie <a href=\"https:\/\/www.bay20.com\/de\/\" target=\"_blank\" rel=\"noopener\" title=\"\"><strong>Bay20<\/strong><\/a> noch heute!<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Die meisten BigCommerce-Integrationen beginnen mit einer Abfrage. Sie richten ein Skript ein, das alle paar Minuten den \u201eOrders\u201c-Endpunkt, den \u201eProducts\u201c-Endpunkt oder eine andere f\u00fcr Sie relevante Ressource \u00fcberpr\u00fcft, und die meisten dieser \u00dcberpr\u00fcfungen liefern keine neuen Ergebnisse. Das funktioniert zwar, ist aber ineffizient und schr\u00e4nkt die Reaktionsgeschwindigkeit Ihres Systems auf \u00c4nderungen ein. Webhooks l\u00f6sen dieses [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":18047,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13],"tags":[],"class_list":["post-18049","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-bigcommerce"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.bay20.com\/de\/wp-json\/wp\/v2\/posts\/18049","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.bay20.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.bay20.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.bay20.com\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.bay20.com\/de\/wp-json\/wp\/v2\/comments?post=18049"}],"version-history":[{"count":5,"href":"https:\/\/www.bay20.com\/de\/wp-json\/wp\/v2\/posts\/18049\/revisions"}],"predecessor-version":[{"id":18057,"href":"https:\/\/www.bay20.com\/de\/wp-json\/wp\/v2\/posts\/18049\/revisions\/18057"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.bay20.com\/de\/wp-json\/wp\/v2\/media\/18047"}],"wp:attachment":[{"href":"https:\/\/www.bay20.com\/de\/wp-json\/wp\/v2\/media?parent=18049"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.bay20.com\/de\/wp-json\/wp\/v2\/categories?post=18049"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.bay20.com\/de\/wp-json\/wp\/v2\/tags?post=18049"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}