DOHandbuch · Die Offensive
Neuerungen API Zur App

REST-API für die Warenwirtschaft (Onlineshop anbinden)

Ihre Artikeldaten liegen in der Warenwirtschaft — Namen, Beschreibungen, Preise, Bilder und Bestände. Über die REST-API kann ein Onlineshop diese Daten automatisch übernehmen, statt dass jemand sie ein zweites Mal eintippt. Verkauft der Shop etwas, kann er den Bestand sogar zurückmelden.

Was ist eine API — in einem Satz?

Eine API ist eine Tür, durch die ein anderes Programm Ihre Daten abholen darf. Sie vergeben dafür einen Schlüssel und entscheiden, ob dieser Schlüssel nur schauen (lesen) oder auch etwas verändern (schreiben) darf.

Dieser Artikel hat zwei Teile: Der erste Teil ist für Sie als Betreiber — Schlüssel anlegen und verwalten. Der zweite Teil ist die technische Referenz, die Sie Ihrem Shop-Entwickler weitergeben können.

Teil 1: Für den Betreiber

Wo finde ich das?

Gehen Sie auf Einstellungen → Anbindungen → „REST-API für WaWi". Direkt neben dem Menüpunkt sitzt ein kleines ⓘ-Symbol — es öffnet die vollständige technische Dokumentation im Fenster, inklusive der Internet-Adresse Ihrer Installation und fertiger Beispiele zum Kopieren. Genau diese Ansicht ist es, die Ihr Shop-Entwickler braucht.

Schlüssel anlegen — Schritt für Schritt

1

„Neuer Schlüssel" anklicken.

2

Eine Bezeichnung eingeben, zum Beispiel „Onlineshop". Der Name erscheint später bei jeder Bestandsbuchung in der Artikel-Historie — so sehen Sie, welches System gebucht hat.

3

Rechte wählen. „Lesen" braucht jeder Shop. „Schreiben" nur, wenn der Shop Bestände zurückmelden oder Artikel anlegen soll. Wenn Sie unsicher sind: erst nur Lesen — nachträglich umstellen ist jederzeit möglich.

4

Schlüssel sofort kopieren. Er erscheint genau einmal. Danach ist er nicht mehr abrufbar — bei uns liegt nur eine Prüfsumme, so wie bei einem Passwort.

5

Den Schlüssel an den Shop-Entwickler geben — am besten nicht per normaler E-Mail, sondern über einen Passwort-Manager oder telefonisch.

Schlüssel verloren?

Kein Problem und kein Datenverlust: Legen Sie einen neuen an und widerrufen Sie den alten. Ein Anzeigen des alten Schlüssels ist absichtlich nicht möglich — genau das schützt Sie, falls jemand Fremdes Zugriff auf Ihr Konto bekäme.

Was die Liste Ihnen zeigt

Zu jedem Schlüssel sehen Sie: die Bezeichnung, den Anfang des Schlüssels (zum Auseinanderhalten), die vergebenen Rechte, wer ihn angelegt hat, wann er zuletzt benutzt wurde und wie viele Aufrufe es gab. Wird ein Schlüssel nie benutzt, ist er entweder falsch hinterlegt — oder er wird nicht mehr gebraucht und kann weg.

Widerrufen oder löschen?

  • Widerrufen (Ein/Aus-Symbol): Der Schlüssel ist sofort ungültig, bleibt aber in der Liste. Praktisch, wenn Sie später nachvollziehen wollen, welcher Zugang wann aktiv war.
  • Löschen: entfernt den Eintrag vollständig. Der Schlüssel funktioniert danach ebenfalls nicht mehr.

Beides greift sofort beim nächsten Aufruf des Shops — es gibt keine Wartezeit.

Was der Shop überhaupt sieht

Nur Artikel, bei denen im Produktfenster im Reiter „OnlineShop" das Häkchen „Im Onlineshop zeigen" gesetzt ist. Alles andere — Kabinettware, Verbrauchsmaterial, Altbestände — bleibt unsichtbar. Sie steuern das Shop-Sortiment also weiterhin in der Warenwirtschaft, nicht im Shop.

Ihre Daten bleiben Ihre Daten

Der Betrieb steckt im Schlüssel selbst. Ein Schlüssel kann deshalb technisch keine Daten eines anderen Betriebs sehen — auch dann nicht, wenn jemand fremde Artikelnummern durchprobiert. Und: Einkaufspreise werden zwar ausgeliefert, gehören aber nie in den Shop; Ihr Entwickler sollte das Feld gar nicht verwenden.

Wenn etwas nicht klappt

Der Entwickler meldet … Das prüfen Sie
„Schlüssel unbekannt oder deaktiviert" Steht der Schlüssel in der Liste auf aktiv? Wurde er versehentlich gelöscht oder beim Kopieren abgeschnitten?
„kein Leserecht" / „kein Schreibrecht" Recht in der Liste umstellen — es wirkt sofort.
„Ich sehe nur wenige Artikel" Häkchen „Im Onlineshop zeigen" bei den fehlenden Artikeln setzen (geht auch per Excel-Massenpflege).
„Ich sehe keine Bilder" Artikel ohne Bild werden mit leerer Bildliste geliefert. Bilder pflegen oder per ZIP-Import hochladen.
„Der Bestand stimmt nicht" In der Artikel-Historie steht jede Buchung mit dem Schlüssel-Namen. Dort sehen Sie, was der Shop gebucht hat.

Teil 2: Technische Referenz (für den Shop-Entwickler)

Dieselben Angaben stehen in der App unter Einstellungen → Anbindungen hinter dem ⓘ-Symbol — dort mit der echten Basis-Adresse der Installation und Kopier-Schaltflächen.

Basis-Adresse und Authentifizierung

https://IHRE-DOMAIN/api/wawi_api.php

# Schlüssel als Kopfzeile, eine der beiden Varianten:
Authorization: Bearer pc_wawi_…
X-API-Key: pc_wawi_…

Anfragen und Antworten sind JSON in UTF-8. GET braucht Leserecht, alles andere Schreibrecht. Fehler kommen als JSON mit error und – wo hilfreich – hint.

Zwei gleichwertige Schreibweisen

# Pfad-Form
GET /api/wawi_api.php/products/123

# Query-Form — funktioniert garantiert auf jedem Server
GET /api/wawi_api.php?resource=products&id=123

Alle Endpunkte

Methode & Pfad Recht Zweck
GET /metalesenSelbsttest: Rechte und Feldlisten des Schlüssels. Bester erster Aufruf.
GET /productslesenArtikelliste, seitenweise. Standard: nur freigegebene Artikel.
GET /products/{id}lesenEin Artikel, alternativ über ?ean= oder ?article_number=.
POST /productsschreibenArtikel anlegen. Pflicht: article_number, name.
PATCH /products/{id}schreibenEinzelne Felder ändern; nicht gesendete Felder bleiben unberührt.
GET /stocklesenBestände je Artikel und Standort.
PATCH /stockschreibenBestand buchen — relativ (change) oder absolut (quantity).

Löschen ist bewusst nicht vorgesehen. Statt zu löschen setzt der Shop online_shop: 0 — der Artikel verschwindet aus dem Sortiment, bleibt aber für Kasse, Bestellungen und Buchhaltung erhalten.

Parameter der Artikelliste

Parameter Standard Bedeutung
online_shop11 = nur freigegebene, 0 = nur nicht freigegebene, all = alle.
searchSucht in Name, Shop-Name, Artikelnummer, EAN.
updated_sinceNur seit diesem Zeitpunkt geänderte Artikel — die Basis für den laufenden Abgleich.
page / limit1 / 50Blättern; limit maximal 200.

Beispiel-Antwort

{
 "pagination": { "page": 1, "limit": 50, "total": 412, "pages": 9, "showing": 50 },
 "products": [
 {
 "id": "1204",
 "article_number": "80612345",
 "ean": "3474636612345",
 "name": "Serie Expert Absolut Repair Shampoo 300ml",
 "b2c_name": "Absolut Repair Shampoo",
 "selling_price": 21.9,
 "tax_class_id": "1",
 "uvp_price": 29.9,
 "online_shop": 1,
 "short_description": "Aufbauendes Shampoo für strapaziertes Haar.",
 "long_description": "…",
 "application": "Ins feuchte Haar einmassieren, ausspülen.",
 "ingredients": "Aqua, Sodium Laureth Sulfate, …",
 "warnings": "Kontakt mit den Augen vermeiden.",
 "image_url": "https://…/uploads/shop/abc.jpg",
 "images": ["https://…/uploads/shop/abc.jpg", "https://…/uploads/shop/abc-2.jpg"],
 "min_stock": 2,
 "updated_at": "2026-07-24 18:03:11"
 }
 ]
}

Felder zum Lesen

id, article_number, ean, name, b2c_name, category, unit, purchase_price, selling_price, uvp_price, tax_class_id, online_shop, short_description, long_description, application, ingredients, warnings, image_url, images, kab_vk, sparte, min_stock, nettogew_g, bruttogew_g, laenge_mm, breite_mm, hoehe_mm, stufe1_geschaeftsbereich, stufe2_produktserie, stufe3_submarke, supplier_id, created_at, updated_at.

Wichtig für die Shop-Anzeige: b2c_name vor name verwenden (wenn gefüllt); images statt einzelner Bildfelder nutzen (Hauptbild steht vorn); Maße und Gewichte für die Versandkosten; purchase_price ist der Einkaufspreis und darf nie sichtbar werden.

Netto oder brutto? Die wichtigste Regel

purchase_price und selling_price sind Netto-Preise — genau wie in der Warenwirtschaft. Der Shop schlägt die Mehrwertsteuer selbst auf: Shop-Preis = selling_price × (1 + MwSt/100). Der passende Satz steckt in tax_class_id.

uvp_price ist dagegen brutto — so veröffentlichen die Hersteller ihre Preisempfehlung. Ein Streichpreis wird deshalb nur gezeigt, wenn uvp_price gefüllt und größer als der gerechnete Brutto-Preis ist. Wer ihn versehentlich mit selling_price vergleicht, zeigt eine um die Mehrwertsteuer zu hohe Ersparnis.

selling_price = 21,90 (netto)
MwSt = 19 %
Shop-Preis = 21,90 × 1,19 = 26,06 € (brutto)

uvp_price = 29,90 (brutto, unverändert übernehmen)
Ersparnis = (29,90 − 26,06) / 29,90 = 13 %

Felder zum Schreiben

name, b2c_name, category, unit, purchase_price, selling_price, uvp_price, online_shop, min_stock, short_description, long_description, application, ingredients, warnings, image_url, image_urls.

Ein leerer Text ("") leert das Feld. Nicht mitgesendete Felder bleiben unverändert. image_urls erwartet eine JSON-Liste als Text, z. B. ["https://…/a.jpg","https://…/b.jpg"].

Absichtlich gesperrt: Artikelnummer, EAN, Lieferant

Diese drei sind die Identität des Artikels in Wareneingang, Kasse und Buchhaltung. Würde der Shop sie ändern, passen Bestellungen und Kassenbelege nicht mehr zusammen. Sie werden ausschließlich in der Warenwirtschaft gepflegt.

Bestand buchen

# relativ — empfohlen, z. B. ein Stück nach einem Shop-Verkauf
PATCH ?resource=stock { "product_id": 1204, "location_id": 2, "change": -1 }

# absolut — nur für Inventur / vollständigen Abgleich
PATCH ?resource=stock { "product_id": 1204, "location_id": 2, "quantity": 7 }

Die Antwort enthält quantity_before und quantity. Fehlt die Bestandszeile, wird sie angelegt. Ohne location_id wird auf den Bestand ohne Standort-Zuordnung gebucht. Jede Buchung landet mit dem Schlüssel-Namen in der Bestands-Historie.

Warum change und nicht quantity?

Verkaufen Shop und Kasse im selben Moment, überschreibt ein absolutes quantity die zweite Buchung — die Ware fehlt dann im Regal, nicht im System. change: -1 rechnet dagegen immer auf den aktuellen Stand.

Fehlercodes

Code Ursache und Abhilfe
401Kopfzeile fehlt, oder Schlüssel falsch / widerrufen / deaktiviert.
403Recht fehlt (lesen bzw. schreiben) — wird in der App je Schlüssel vergeben.
404Artikel gehört nicht zu diesem Betrieb / existiert nicht, oder unbekannte Ressource.
405Methode nicht vorgesehen (z. B. DELETE).
409Artikelnummer beim Anlegen schon vergeben — stattdessen PATCH nutzen.
422Pflichtfeld fehlt oder kein schreibbares Feld dabei; hint nennt die erlaubten Felder.
500 / 503Buchung zurückgerollt bzw. Datenbank nicht erreichbar. Mit wachsender Wartezeit erneut versuchen (2 s, 4 s, 8 s) — nicht in einer engen Schleife.

Grenzen und empfohlener Takt

  • Artikel je Seite: maximal 200 (Standard 50).
  • Bestandszeilen je Aufruf: maximal 500 (Standard 200).
  • Aktive Schlüssel je Betrieb: 20.
  • Katalog stündlich per updated_since, Bestand bei Bedarf. Kein Dauer-Abruf im Sekundentakt — die Warenwirtschaft bedient gleichzeitig Kasse und Salon-Displays.

Ablauf einer Anbindung

1

GET /meta aufrufen — bestätigt Schlüssel und Rechte, ohne etwas zu verändern.

2

Vollständigen Katalog holen (page bis pages hochzählen) und Bilder in den Shop übernehmen.

3

Zeitpunkt des Lauf-Endes speichern und künftig nur noch updated_since abfragen.

4

Artikel mit online_shop: 0 im Shop ausblenden — nicht löschen, damit Bestellhistorie und Links erhalten bleiben.

5

Optional: nach jedem Shop-Verkauf PATCH /stock mit change: -1.

Die Schnittstelle ist über HTTPS erreichbar und arbeitet ausschließlich mit dem Betrieb, zu dem der Schlüssel gehört. Lesende Aufrufe sind auch aus dem Browser erlaubt; schreibende Aufrufe sollten immer vom Shop-Server ausgehen, damit der Schlüssel nicht öffentlich wird.

← Zur Übersicht Zuletzt aktualisiert: 25.07.2026