Häufige Integrationsaufgaben

Häufige API-Aufgaben nach Job

Bestellungen heraus, Bestand hinein, Preise hinein, Kundenstamm hinein — die vier Jobs, aus denen fast jede ERP-Integration besteht, jeder mit Ressource, Form, Webhook-Alternative und Falle.

Neunzig Prozent dessen, was ein ERP-Integrator hier baut, sind vier Jobs. Dieser Artikel ist das Rezept für jeden: welche Schnittstelle, welche Ressource, was ungefähr zurückkommt, und das, was schiefgeht.

Die Beispiele sind illustrativ. Basis-URL, Header, Paging-Parameter und der Antwort-Umschlag sind real und stabil. Feldnamen innerhalb von items und data hängen an Ihren installierten Apps — lesen Sie die exakte Form aus der https://api.revenexx.com/v1/openapi.json Ihres Tenants, und nehmen Sie Topic-Namen aus Events › Event Catalog. Programmieren Sie nicht gegen die Feldnamen unten.

Die vier Jobs im Überblick

JobRichtungVolumenNötige LatenzSchnittstelle
Bestellungen herausPlattform → ERPEinzelnSofortWebhook, plus Abgleichs-Poll
Bestand hineinERP/WMS → PlattformTausende ZeilenMinuten bis StundenMassenimport, oder Live-Lesen für die wenigen, die zählen
Preise hineinERP → PlattformTausende ZeilenNächtlichMassenimport
Kundenstamm hineinERP → PlattformHunderte ZeilenNächtlich, plus live für KreditMassenimport, plus Live-Lesen im Checkout

Lesen Sie das Muster: Genau einer der vier will die REST API in einer Schleife, und es ist der, der Einzeldatensätze behandelt. Die anderen drei sind Dateien. Das ist keine Einschränkung der Plattform — es ist das, was die Form der Daten Ihnen sagt. Siehe Integrationsmuster.

Job 1: Bestellungen heraus

Jede hier aufgegebene Bestellung muss Ihr ERP erreichen, einmal, mit allem, was das ERP zum Buchen braucht.

Der Webhook-Weg — der richtige

Abonnieren Sie das Order-created-Topic in Events › Event Catalog und lassen Sie das ERP es empfangen. Die Zustellung trägt Event-Id, Topic, Zeitstempel und Signatur — siehe Webhooks einrichten.

Der Event-Body sagt Ihnen, dass eine Bestellung existiert und welche. Die meisten Integrationen holen danach die volle Bestellung, denn ein Event-Payload ist absichtlich klein:

GET /v1/orders/{id} HTTP/1.1
Host: api.revenexx.com
X-Revenexx-Tenant: acme-eu
X-Revenexx-Api-Key: rvxk_…

Der Pull-Weg — als Sicherheitsnetz, nicht als Mechanismus

Listen Sie Bestellungen, die seit Ihrem letzten erfolgreichen Lauf aufgetaucht sind:

GET /v1/orders?limit=100&order=created_at.desc HTTP/1.1

Paging ist limit und offset, Sortierung ist order=<feld>.<richtung>, und die Antwort ist immer derselbe Umschlag:

{ "items": [ ... ], "total": 248, "limit": 100, "offset": 0 }

Fahren Sie das stündlich als Abgleich, nicht alle dreißig Sekunden als Ersatz für den Webhook. Ein Webhook ist ein Zustellversuch, keine Garantie; ohne den Abgleichslauf verliert ein Empfänger, der sein ganzes Wiederholungsfenster hindurch down war, still Bestellungen.

Zurückbestätigen

Sobald das ERP die Bestellung gebucht hat, sagen Sie es. Die Bestellressource stellt genau dafür Aktionen bereit:

POST /v1/orders/{id}/acknowledge
POST /v1/orders/{id}/cancel
POST /v1/orders/{id}/complete

Die Bestätigung schließt den Kreis: Sie unterscheidet „die Plattform hat sie gesendet" von „das ERP hat sie", und sie ist der Join, auf dem Ihr Abgleichsbericht läuft.

Was das ERP tatsächlich braucht

Lassen Sie den Integrator nicht nur den Kopf mitnehmen. B2B-Bestellungen tragen Positionsdaten, ohne die das ERP die Zeile gar nicht buchen kann:

Getragen aufWasWarum es zählt
Bestellungcustomer_order_numberDie eigene PO-Nummer des Käufers. Ohne sie kann seine Buchhaltung die Rechnung nicht zuordnen
BestellungDie drei Statusstatus, payment_status und fulfillment_status sind unabhängig — siehe Die drei Bestellstatus
PositionKostenstelleEine Bestellung kann die Budgets von drei Abteilungen berühren
PositionDie eigene Artikelnummer des KäufersSeine Teilenummer, nicht Ihre
PositionPositionstextDer Hinweis zu Maschine, Halle oder Kostenstelle

Die Falle

Eine zweimal übertragene Bestellung sind zwei Zustellungen. Deduplizieren Sie auf der Event-Id, die über Wiederholungen stabil ist, und nie auf einer selbst erzeugten. Und denken Sie daran, dass die Hoheit über die Bestellung mit der Übertragung wandert: Sobald das ERP sie hat, gehört ihm ihr Status — siehe Das führende System festlegen.

Job 2: Bestand hinein

Ihr Lager oder ERP weiß, was im Regal liegt. Der Shop muss es zeigen, ohne zu lügen.

Zuerst das Modell

FeldBedeutung
on_handWas physisch da ist, je Standort und Artikel
reservedWas bereits jemandem versprochen ist
availableon_hand − reserved. Berechnet, nie gespeichert, nie geschrieben
reorder_pointIhr eigener Einkaufsauslöser (Meldebestand), nicht der des Kunden

available ist die Zahl, die ein Käufer sehen sollte. Wer available so schreibt, als wäre es on_hand, zählt die Reservierungen doppelt und erzeugt Phantom-Fehlbestände.

Der Bulk-Weg — der richtige für das ganze Lager

Schieben Sie nach Zeitplan eine Bestandsdatei mit dem vollen Zustand. Voller Zustand, keine Deltas: Eine zweimal angewendete Delta-Bestandsdatei lässt den Bestand um genau die Bewegungen eines Laufs falsch stehen, still, ohne Fehler irgendwo.

Die Bulk-Ebene nimmt die Datei als Job, nicht als Request — Sie registrieren sie, sie verarbeitet, Sie fragen den Zustand ab:

POST /v1/io/uploads      → eine kurzlebige signierte Upload-URL
POST /v1/io/imports      → die hochgeladene Datei gegen ein Profil registrieren
GET  /v1/io/bulk-jobs/{job_id}   → Zeilen gelesen, geschrieben, abgewiesen

Oder legen Sie die Datei auf SFTP ab und lassen ein geplantes Profil sie aufnehmen — was die meisten ERPs tatsächlich tun.

Der REST-Weg — für die wenigen Artikel, die zählen

Einzelne Bestände lesen oder korrigieren:

GET /v1/inventories/stock?limit=100
GET /v1/inventories/availability?sku=4711-A
POST /v1/inventories/movements

Nutzen Sie das für Korrekturen und für die Handvoll hochwertiger Artikel, bei denen eine nächtliche Zahl nicht reicht. Nutzen Sie es nicht in einer Schleife über Ihren Katalog — siehe Rate-Limits.

Die Event-Alternative, in der Gegenrichtung

Die Plattform kann Ihnen sagen, wenn ein Bestand eine Schwelle unterschreitet, damit Ihr Einkaufssystem nicht pollen muss. Abonnieren Sie das Low-Stock-Topic, und Sie bekommen einen Push, wenn ein Artikel unter seinen Meldebestand fällt.

Die Falle

Lassen Sie den Shop nie Bestand schreiben. Bestand ist die laufende Summe eines Bewegungsjournals; eine Zahl, die jemand darüber getippt hat, kann eine Woche später niemand mehr erklären. Korrigieren Sie mit einer gebuchten Bewegung, und siehe Wenn Bestandszahlen driften.

Job 3: Preise hinein

Preise sind das Feld, in dem Falschsein eine Gutschrift kostet — dieser Job bekommt die meiste Sorgfalt.

Zuerst das Modell

Ein Preis ist kein Feld am Produkt. Er ist eine Zeile in einer Preisliste, und die Liste trägt den Geltungsbereich: Währung, Kunde, Kanal, Markt, Gültigkeitsfenster, Priorität. Diese Indirektion erlaubt einem Artikel gleichzeitig einen Katalogpreis, einen Vertragspreis, einen Staffelpreis und einen Schweiz-Preis — siehe Wie Pricing funktioniert.

„Preise schieben" heißt deshalb immer: Zeilen in die richtige Liste schieben.

Der Bulk-Weg — bei Volumen der einzig vernünftige

POST /v1/io/uploads
POST /v1/io/imports    → gegen ein Preis-Importprofil
GET  /v1/io/bulk-jobs/{job_id}

Eine Preisimportdatei enthält typischerweise Listencode, SKU, Ab-Menge, Betrag, Währung und Gültigkeitsdaten. Das Mapping — welche Spalte welches Feld wird, und welche Felder die Datei nicht anfassen darf — lebt im Profil, siehe Feld-Mapping und Preise importieren.

Die Listenstruktur zurücklesen ist ein gewöhnlicher REST-Aufruf:

GET /v1/prices/lists?limit=50

Einen Preis auflösen

Wenn etwas den Preis für einen Käufer, einen Artikel und eine Menge braucht — eine Bestelllisten-Umwandlung, ein Angebotswerkzeug, eine Kontrolle —, ist das ein Resolve-Aufruf, kein Lookup, denn er muss die ganze Prioritätskette ablaufen:

POST /v1/prices/resolve

Nutzen Sie ihn, statt die Prioritätsregeln im ERP nachzubauen. Zwei Implementierungen der Preisauflösung werden sich widersprechen, und der Widerspruch taucht auf einer Rechnung auf.

Die Falle

Auslaufende Gültigkeitsfenster scheitern offen, nicht geschlossen. Ein Vertragspreis, dessen valid_until verstreicht, wirft keinen Fehler; die nächstbeste Liste greift, und der Käufer zahlt mehr. Legen Sie die Gültigkeitsdaten von Vertragspreisen auf einen Review-Kalender — siehe Preislisten-Hygiene.

Job 4: Kundenstamm hinein

Das ERP weiß, wer Ihre Kunden sind. Die Plattform weiß, wie sie sich anmelden.

Die Entität aufteilen, bevor irgendwer Code schreibt

Das ist das Gespräch über Feld-Hoheit, und es wird je Feld geführt, nicht je Entität:

FeldEigentümerRichtung
KundennummerERPERP → Plattform
Firmenname, AdressenERPERP → Plattform
ZahlungsbedingungenERPERP → Plattform
Kreditlimit, SperrstatusERPLive im Checkout lesen
Shop-Logins, Kontakte, RollenPlattformNur Plattform
Freigaberegeln, Kostenstellen, BudgetsPlattformNur Plattform

Das ERP kennt kein Shop-Login, und die Plattform hat kein Kreditlimit zu erfinden. Siehe Das führende System festlegen.

Der Bulk-Weg

Organisationen und ihre Adressen kommen nächtlich als Datei, abgeglichen über die Kundennummer — ein stabiler Geschäftsschlüssel, nie eine interne Id. Jeder Import sollte heißen „mach den Datensatz so", damit ein Wiederholungslauf konvergiert statt zu duplizieren.

Der REST-Weg

GET  /v1/customers/organizations?limit=100
GET  /v1/customers/contacts?limit=100
GET  /v1/customers/organization_metrics

Die Metrics-Ressource lohnt sich für BI: Sie trägt Umsatz und Bestellzahlen je Konto über 30, 90 und 365 Tage plus last_order_at, für Sie gepflegt statt jedes Mal berechnet. Siehe Die Kennzahlen, die im B2B zählen.

Das Live-Lesen, das nicht optional ist

Kreditlimit und Sperrstatus müssen im Checkout aktuell sein, nicht von letzter Nacht. An einen Kunden zu liefern, den Ihre Buchhaltung heute Morgen gesperrt hat, ist der eine Fehler in diesem Artikel, der echtes Geld kostet. Machen Sie daraus einen Live-Aufruf, und entscheiden Sie, was passiert, wenn das ERP nicht antwortet — ablehnen, oder durchlassen und markieren. Beides ist vertretbar; nicht zu entscheiden ist es nicht.

Die Falle

Synchronisieren Sie keine Kontakte aus dem ERP. Die Kontakttabelle des ERP sind Rechnungsempfänger und eine Telefonnummer von 2014. Shop-Kontakte haben Rollen, Berechtigungen, Freigabelimits und Kostenstellenzuordnungen, die kein ERP abbildet. Lassen Sie die Plattform sie besitzen — siehe Kontakte und Rollen.

Die zwei Regeln, die für alle vier gelten

Über einen stabilen Geschäftsschlüssel abgleichen. SKU, Kundennummer, Bestellnummer. Eine interne Datenbank-Id, die das andere System nie gesehen hat, ist kein Schlüssel, über den Sie abgleichen können.

Jeden Schreibzugriff idempotent machen. Dinge scheitern auf halbem Weg. Ein Timeout sagt Ihnen nichts darüber, ob die andere Seite den Request verarbeitet hat. Hat die Operation zweimal ausgeführt dieselbe Wirkung wie einmal, lautet die Erholung von jedem Fehler „noch einmal laufen lassen" — und einen Idempotency-Key-Header gibt es hier nicht, Idempotenz muss also eine Eigenschaft Ihrer Daten sein, nicht eines Headers. Siehe Eine Integration durchgängig testen.

Weiter