Adressen benachrichtigen

Ein API-Schlüssel lässt Ihr System bei uns anfragen. Dieses Kapitel beschreibt die Gegenrichtung: BetterPickUp meldet sich von selbst bei einer Adresse, die Sie angeben, sobald sich an einem Vorgang etwas tut. Wer bisher alle zehn Sekunden nachgefragt hat, ob etwas passiert ist, braucht das dann nicht mehr.

Die Nachricht ist ein Anstoß, keine Auskunft. Sie nennt, welcher Vorgang sich geändert hat und wie, und sonst nichts. Alles Weitere holt Ihr System über die API, und dafür braucht es einen eigenen API-Schlüssel. Das ist Absicht: so verlassen Daten über Ihre Gäste das Haus nur auf Anfrage und über einen Weg mit Berechtigungen.

Einrichten

  1. Verwaltung → Integrationen → Neue Integration.
  2. Eine eigene Adresse benachrichtigen wählen, dann Adresse einrichten.
  3. Standort wählen. Gemeldet werden nur Vorgänge dieses Standorts. Für zwei Filialen richten Sie zwei Adressen ein, auch wenn dieselbe Stelle sie empfängt.
  4. Name vergeben. Daran erkennen Sie die Adresse später in der Liste wieder.
  5. Adresse eintragen, die Ihr System bereitstellt. Sie muss mit https beginnen.
  6. Unter Wobei soll benachrichtigt werden mindestens ein Ereignis auswählen.
  7. Anlegen.

Danach erscheint das Geheimnis genau einmal, in dem Fenster, das dem Anlegen folgt. Damit prüft Ihr System, dass eine Nachricht wirklich von uns kommt. Schreiben Sie es sofort auf: es ist danach nirgends mehr abrufbar, auch nicht für uns. Ein verlorenes Geheimnis wird ersetzt und nicht wiedergefunden, und dazu legen Sie die Adresse neu an.

Name, Adresse und Ereignisse lassen sich später ändern, ohne dass das Geheimnis sich ändert. Eine Adresse lässt sich außerdem ausschalten, ohne sie zu löschen; ausgeschaltet bekommt sie nichts, und was währenddessen passiert, wird nicht nachgeholt.

Welche Ereignisse es gibt

Fünf, und alle fünf betreffen einen Vorgang. Über Konten, Standorte, Geräte oder Medien wird nichts gemeldet.

  • Ein Vorgang wurde angelegt, in der Nachricht OrderCreated
  • Ein Vorgang hat den Zustand gewechselt, in der Nachricht OrderStatusChanged. Das ist das häufigste der fünf, es tritt an jedem Vorgang mehrfach auf
  • Ein Vorgang wurde bearbeitet, in der Nachricht OrderDetailsChanged, also Name, Notiz, Herkunft oder Summe wurden korrigiert
  • Ein Gast ist auf dem Weg, in der Nachricht OrderOnTheWaySignalled
  • Ein Gast hat das zurückgenommen, in der Nachricht OrderOnTheWayWithdrawn

Was ankommt

Eine Anfrage der Art POST an Ihre Adresse, mit dem Inhaltstyp application/json und vier Feldern im Rumpf:

  • eventId: die Kennung dieses Ereignisses. Sie bleibt gleich, wenn dieselbe Nachricht ein zweites Mal kommt
  • kind: eines der fünf Ereignisse oben, als Name geschrieben, also OrderStatusChanged und nicht 2
  • orderId: der Vorgang, um den es geht
  • occurredAtUtc: wann es passiert ist, nicht wann die Nachricht abgeschickt wurde

Dazu zwei Köpfe: X-BetterPickUp-Signature mit der Signatur und X-BetterPickUp-Event mit derselben eventId, die auch im Rumpf steht.

Kein Gastname, keine Notiz, kein Preis und kein Abholort. Diese Liste ist die Zusage, und sie ist im Quelltext durch einen Test festgehalten, damit ihr nicht unbemerkt ein fünftes Feld zuwächst.

Die Signatur prüfen

Der Kopf X-BetterPickUp-Signature sieht so aus:

t=1786598400,v1=9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08

t ist der Zeitpunkt des Absendens in Sekunden seit 1970, v1 die Signatur als Hexadezimalzahl in Kleinbuchstaben. Sie ist ein HMAC mit SHA-256 über der Zeichenkette aus Zeitstempel, einem Punkt und dem Rumpf, mit Ihrem Geheimnis als Schlüssel.

Dass der Zeitstempel innerhalb des Signierten steht, ist der Punkt daran. Wer nur den Rumpf prüft, macht jede einmal mitgelesene Nachricht auf ewig wiederverwendbar: ein Fremder könnte sie mit einem eigenen Zeitstempel erneut schicken, und die Signatur ginge auf.

Prüfen Sie über dem Rumpf, wie er angekommen ist, Zeichen für Zeichen. Wer ihn vorher als JSON einliest und wieder ausgibt, bekommt eine andere Zeichenkette und damit eine andere Signatur. Das ist der häufigste Grund dafür, dass eine korrekte Nachricht abgelehnt wird.

import hashlib
import hmac


def signatur_gueltig(geheimnis: str, kopf: str, rumpf: bytes) -> bool:
    """Prueft X-BetterPickUp-Signature gegen den unveraenderten Rumpf."""
    teile = dict(t.split("=", 1) for t in kopf.split(",") if "=" in t)
    zeitstempel, signatur = teile.get("t"), teile.get("v1")

    if not zeitstempel or not signatur:
        return False

    erwartet = hmac.new(
        geheimnis.encode("utf-8"),
        zeitstempel.encode("utf-8") + b"." + rumpf,
        hashlib.sha256,
    ).hexdigest()

    # compare_digest und nicht ==, damit die Laufzeit nichts ueber die Signatur verraet.
    return hmac.compare_digest(erwartet, signatur)

Wie alt ein Zeitstempel sein darf, entscheiden Sie. Wir setzen dafür bewusst kein Fenster: nur Sie wissen, wie lange Ihre eigene Warteschlange eine Nachricht halten darf. Fünf Minuten sind ein üblicher Wert.

Mindestens einmal, nie genau einmal

Eine Nachricht kann zweimal ankommen. Das passiert, wenn wir sie abgeschickt haben und der Ausgang der Zustellung uns nicht mehr erreicht hat; dann gilt sie als offen und wird erneut geschickt. Genau einmal zuzusagen hieße, den Zustand Ihres Systems zu kennen, und den kennen wir nicht.

Deshalb trägt jede Nachricht die eventId, und die bleibt über Wiederholungen hinweg dieselbe. Merken Sie sich die zuletzt gesehenen Kennungen und verwerfen Sie eine, die Sie schon hatten. Das ist die eine Sache, die ein Empfänger selbst tun muss.

Als angekommen gilt eine Nachricht, sobald Sie mit einem Code aus dem Bereich 2xx antworten. Alles andere zählt als Fehlschlag, auch 404 und 401. Ein Fehlschlag wird bis zu fünfmal versucht, mit Wartezeiten von einer Minute, fünf Minuten, fünfzehn Minuten und einer Stunde. Danach gilt die Nachricht als aufgegeben und wird nicht mehr geschickt. Zusammen sind das gut sechs Stunden, also lange genug, dass ein über Mittag neu gestarteter Empfänger noch alles bekommt.

Antworten Sie schnell. Nach zehn Sekunden ohne Antwort brechen wir ab und zählen den Versuch als Fehlschlag. Nehmen Sie die Nachricht an, legen Sie sie in Ihre eigene Warteschlange und antworten Sie; die Arbeit selbst gehört hinter diese Antwort.

Was die Liste über den Zustand sagt

Unter Verwaltung → Integrationen steht neben jeder Adresse, wie es der Warteschlange geht: wie viele Nachrichten warten, wie viele aufgegeben wurden, wann zuletzt etwas durchgekommen ist und woran der letzte Versuch gescheitert ist. Steht dort Noch nichts durchgekommen und wächst die Zahl der wartenden, hat Ihr Empfänger noch nie mit 2xx geantwortet.

Der Inhalt der Nachrichten steht dort nicht, auch nicht aufgeklappt. Er enthält Vorgangskennungen, und ein Bildschirm, den jemand im Büro offen stehen lässt, ist kein Ort dafür.

Regeln für die Adresse

  • Sie muss https sein. Eine signierte Nachricht über eine offene Leitung ist immer noch eine Nachricht über eine offene Leitung.
  • Sie darf nicht ins eigene Netz zeigen. Adressen mit localhost und mit Zahlen aus den privaten Bereichen 10., 172.16. bis 172.31., 192.168. und 169.254. werden abgelehnt. Ein Rechnername wird dabei nicht aufgelöst, denn wohin er morgen zeigt, ist heute nicht zu wissen.
  • Sie darf höchstens 2048 Zeichen lang sein.

Woran Sie erkennen, dass es geklappt hat

Legen Sie einen Vorgang an, während Ihr Empfänger läuft. Binnen weniger Sekunden kommt eine Nachricht mit kind gleich OrderCreated an, die Signatur geht auf, und unter Verwaltung → Integrationen steht bei dieser Adresse ein Zeitpunkt für die letzte Zustellung und keine wartende Nachricht.

Kommt nichts an, sehen Sie zuerst dort nach. Wartende Nachrichten mit einem Fehler wie HTTP 502 bedeuten, dass wir Ihren Empfänger erreicht haben und er abgelehnt hat. Kein Eintrag überhaupt bedeutet, dass die Adresse ausgeschaltet ist oder das Ereignis nicht ausgewählt wurde.

Stand: 13.08.2026