API-Referenz: Webshop-Anbindung¶
Diese Seite ist die Nachschlage-Referenz zum Leitfaden Eigenen Webshop anbinden: alle Aufrufe, die ein eigener Webshop (oder eine Webagentur) an der Kasse eines Betriebs nutzen kann, mit Anmeldung, Anfrage- und Antwortfeldern, Fehlercodes und Beispielen. Sie behandelt ausschließlich die aktuelle Schnittstelle unter /api/v1/…; ältere Schnittstellen sind für neue Anbindungen nicht vorgesehen und hier nicht beschrieben.
OpenAPI-Datei herunterladen (openapi-webshop.json)
Die Datei enthält dieselben Aufrufe und Datenobjekte als OpenAPI-3-Beschreibung, zum Beispiel für Postman, Insomnia oder einen Client-Generator. Als Server ist https://{betrieb}/api/v1 eingetragen; betrieb ist die Adresse der Kasse des Betriebs.
Grundlagen¶
Adresse. Alle Aufrufe gehen an die Kasse des Betriebs: https://<betrieb>.<ihre-domain>/api/v1/…. In den Beispielen steht API für diese Adresse einschließlich /api/v1.
Antwortformat. Jede Antwort ist in eine Hülle verpackt: { "success": true, "data": … }. Bei einem Fehler ist success gleich false, data ist null, und errorCode (stabil, für Programme) sowie errorMessage (für Menschen) benennen den Grund; bei fehlerhaften Eingaben listet validationErrors Feld und Meldung. Prüfen Sie immer zuerst success. Die Tabellen unten beschreiben jeweils den Inhalt von data.
Schreibweise. Feldnamen sind camelCase. Beträge sind Dezimalzahlen in der Währung des Betriebs (9.5). Zeitpunkte sind ISO-8601 (2026-11-10T17:44:05Z), in der Regel UTC. Kennungen (art_…, olord_…) sind undurchsichtig: nicht zerlegen, nur weitergeben. Ein ? hinter dem Typ heißt: der Wert kann null sein. Unbekannte zusätzliche Felder in Antworten sind zu ignorieren.
Wiederholsicherheit. Bei POST, PUT, PATCH und DELETE kann die Kopfzeile Idempotency-Key (8 bis 200 Zeichen) mitgesendet werden: derselbe Aufruf mit demselben Schlüssel und Inhalt innerhalb einer Stunde liefert das erste Ergebnis erneut, statt ihn zweimal auszuführen; derselbe Schlüssel mit anderem Inhalt ergibt 422 IDEMPOTENCY_KEY_REUSED. Für Bestellungen gilt das dauerhaft, siehe Bestellung anlegen.
Teiländerungen an Artikeln und Warengruppen laufen als JSON Patch (RFC 6902, Content-Type: application/json-patch+json): eine Liste von Operationen add, replace, remove und test mit Pfad (/price) und Wert. Eine test-Operation vor der Änderung schützt vor dem Überschreiben fremder Änderungen: hat sich der Wert inzwischen geändert, antwortet die Kasse 409 PATCH_TEST_FAILED und schreibt nichts.
Zugangsdaten sind Geheimnisse. Partner-Schlüssel, Bestell-Geheimnisse und Webhook-Geheimnisse gehören nur in Ihren Server, nie in Browser-Code, Repositories oder Protokolle.
Anmeldearten¶
| Kürzel | Bedeutung | Kopfzeile |
|---|---|---|
| keine | Öffentlich erreichbar, ohne Kopfzeile. Gedacht für den Browser des Gastes und für Shop-Server. | – |
| Bestell-Geheimnis | Das Geheimnis, das die Kasse beim Anlegen einer Bestellung genau einmal herausgibt. Es gehört zu genau einer Bestellung. | X-Order-Secret |
| Partner-Schlüssel oder Bearer | Server-zu-Server-Zugang eines Fremdsystems. Der Schlüssel hat feste Bereiche (orders:read, orders:manage, tables:read, events:read) und gehört zu einem technischen Benutzer, dessen Rechte zusätzlich gelten. Ausgestellt unter Einstellungen → System → Partner-Schlüssel oder per Partner-Schlüssel anlegen. |
X-Dikas-Api-Key: dk1_… |
| Bearer | Ein Kassenbenutzer meldet sich mit POST /api/v1/auth/login an ({"username":…,"password":…}, Antwort data.accessToken). Für Anbindungen empfiehlt sich ein eigener Benutzer mit nur den nötigen Rechten. |
Authorization: Bearer … |
| Administrator (Bearer) | Wie Bearer, aber nur mit Administratorrolle. Gilt für die Verwaltung von Webhook-Zielen und Partner-Schlüsseln. | Authorization: Bearer … |
Fehler, die jeder Endpunkt kennen kann¶
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 400 | VALIDATION_ERROR |
Eingabe fehlerhaft; validationErrors nennt je Feld die Meldung. |
| 401 | (kein Inhalt) | Anmeldung fehlt, ist abgelaufen oder ungültig; ebenso ein ungültiger, abgelaufener oder widerrufener Partner-Schlüssel, oder ein Partner-Schlüssel an einem Aufruf, der nur Benutzer-Anmeldung annimmt. |
| 403 | (kein Inhalt) | Ein gültiger Partner-Schlüssel hat den Bereich des Aufrufs nicht, oder dem Benutzer fehlt die nötige Rolle bzw. das nötige Recht. |
| 403 | MODULE_NOT_LICENSED |
Das Modul (Online-Bestellung) ist in der Lizenz des Betriebs nicht enthalten. |
| 404 | ENTITY_NOT_FOUND |
Die Kennung ist unbekannt. Bei Bestell-Aufrufen mit Bestell-Geheimnis auch: Geheimnis fehlt oder passt nicht. |
| 404 | SWITCH_DISABLED |
Online-Bestellung ist im Betrieb ausgeschaltet (Admin → Einstellungen → Betrieb). |
| 429 | (kein Inhalt) | Zu viele fehlgeschlagene Schlüsselprüfungen von derselben Adresse (30 je Minute); später erneut versuchen. |
Übersicht¶
| Aufruf | Zweck | Anmeldung |
|---|---|---|
GET /online-menu/menu |
Speisekarte lesen | keine |
GET /online-menu/status |
Öffnungsstatus lesen | keine |
GET /online-menu/wait-estimate |
Wartezeit lesen | keine |
GET /online-menu/shop-info |
Shop-Angaben lesen | keine |
GET /article-descriptions/{articleId}/images/{attachmentName} |
Artikelbild laden | keine |
POST /online-checkout/create |
Bestellung anlegen | keine |
GET /online-checkout/{id} |
Bestellung lesen | Bestell-Geheimnis |
POST /online-checkout/{id}/init-payment |
Online-Zahlung starten | Bestell-Geheimnis |
POST /online-checkout/{id}/verify-payment |
Zahlung prüfen | Bestell-Geheimnis |
POST /online-checkout/{id}/cancel |
Bestellung stornieren | Bestell-Geheimnis |
GET /online-checkout/pending |
Offene Bestellungen lesen | Partner-Schlüssel (orders:read) oder Bearer |
GET /online-checkout/today |
Heutige Bestellungen lesen | Partner-Schlüssel (orders:read) oder Bearer |
POST /online-checkout/{id}/confirm |
Bestellung annehmen | Partner-Schlüssel (orders:manage) oder Bearer |
POST /online-checkout/{id}/reject |
Bestellung ablehnen | Partner-Schlüssel (orders:manage) oder Bearer |
PUT /online-checkout/{id}/status |
Bestellstatus setzen | Partner-Schlüssel (orders:manage) oder Bearer |
GET /articles/groups |
Warengruppen lesen | Bearer |
POST /articles/groups |
Warengruppe anlegen | Bearer |
PATCH /articles/groups/{documentId} |
Warengruppe ändern | Bearer |
GET /articles |
Artikel lesen | Bearer |
GET /articles/{id} |
Einen Artikel lesen | Bearer |
POST /articles |
Artikel anlegen | Bearer |
PATCH /articles/{id} |
Artikel ändern | Bearer |
GET /events |
Ereignisse lesen | Partner-Schlüssel (events:read) oder Bearer |
GET /webhook-targets |
Webhook-Ziele lesen | Administrator (Bearer) |
POST /webhook-targets |
Webhook-Ziel anlegen | Administrator (Bearer) |
PATCH /webhook-targets/{id} |
Webhook-Ziel ändern | Administrator (Bearer) |
POST /webhook-targets/{id}/rotate-secret |
Webhook-Geheimnis erneuern | Administrator (Bearer) |
DELETE /webhook-targets/{id} |
Webhook-Ziel löschen | Administrator (Bearer) |
GET /webhook-targets/deliveries |
Zustellungen lesen | Administrator (Bearer) |
POST /webhook-targets/deliveries/retry |
Tote Zustellungen wiederholen | Administrator (Bearer) |
GET /partner-api-keys/scopes |
Bereiche lesen | Administrator (Bearer) |
GET /partner-api-keys |
Partner-Schlüssel lesen | Administrator (Bearer) |
POST /partner-api-keys |
Partner-Schlüssel anlegen | Administrator (Bearer) |
POST /partner-api-keys/{id}/rotate |
Partner-Schlüssel erneuern | Administrator (Bearer) |
DELETE /partner-api-keys/{id} |
Partner-Schlüssel widerrufen | Administrator (Bearer) |
Speisekarte und Öffnungsstatus¶
Diese vier Aufrufe sind öffentlich und können direkt aus dem Browser des Gastes oder vom Shop-Server gerufen werden. Sie setzen voraus, dass Online-Bestellung im Betrieb eingeschaltet ist (sonst 404 SWITCH_DISABLED).
Speisekarte lesen¶
GET /api/v1/online-menu/menu
Liefert die veröffentlichte Karte, gegliedert nach Warengruppen, mit Preisen, Optionen, Allergenen und Bildern. Ausgeblendete Gruppen und Artikel fehlen. Ein Artikel mit soldOut: true steht auf der Karte, wird beim Bestellen aber abgewiesen. Die Kasse rechnet beim Bestellen mit ihren Preisen: die Karte daher nicht lange zwischenspeichern.
Anmeldung: Keine Anmeldung, der Aufruf ist öffentlich.
Antwort 200
data: OnlineMenuResponse
| Feld | Typ | Bedeutung |
|---|---|---|
shopName |
Text? | Name des Shops. |
shopDescription |
Text? | Kurzbeschreibung des Shops. |
shopSlogan |
Text? | Slogan des Shops. |
groups |
Liste von OnlineMenuGroup? | Die Warengruppen mit ihren Artikeln. Nur Gruppen und Artikel, die online sichtbar sind. |
allergenDefinitions |
Liste von OnlineMenuAllergen? | Klartext zu den Allergen-Kürzeln der Artikel (allergens). |
Enthaltene Datenobjekte: OnlineMenuAllergen, OnlineMenuGroup.
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 404 | SWITCH_DISABLED |
Online-Bestellung ist im Betrieb ausgeschaltet. |
| 403 | MODULE_NOT_LICENSED |
Das Modul Online-Bestellung fehlt in der Lizenz. |
Beispiel
curl -sS "$API/online-menu/menu" | jq -c '.data | {shopName, groups: [.groups[] | {id, name, articles: [.articles[] | {id, name, price, soldOut}]}]}'
Gekürzt mit jq; die Antwort enthält je Artikel alle Felder der Tabelle.
{"shopName": "Pizzeria Beispiel", "groups": [{"id": "artgrp_2d6002dced5a", "name": "Pizza", "articles": [{"id": "art_917c19d4a18a", "name": "Pizza Margherita", "price": 9.5, "soldOut": false}, {"id": "art_ae2ef2e45883", "name": "Pizza Salami", "price": 11, "soldOut": false}]}]}
Öffnungsstatus lesen¶
GET /api/v1/online-menu/status
Meldet, ob der Betrieb gerade innerhalb der Öffnungszeiten ist, und wann er schließt bzw. das nächste Mal öffnet (Öffnungszeiten und besondere Schließtage des Betriebs).
Anmeldung: Keine Anmeldung, der Aufruf ist öffentlich.
Parameter
| Name | Ort | Typ | Pflicht | Bedeutung |
|---|---|---|---|---|
channel |
Abfrage | Text | nein | Bestellweg: OnlineOrder (Vorgabe), QrTable oder Reservation. Jeder Weg fragt seinen eigenen Betriebsschalter ab. |
Antwort 200
data: ShopStatusResponse
| Feld | Typ | Bedeutung |
|---|---|---|
isOpen |
Ja/Nein | true: innerhalb der Öffnungszeiten. |
currentCloseTime |
Text? | Heutige Schließzeit (22:00), solange geöffnet. |
nextOpenDate |
Text? | Datum der nächsten Öffnung (2026-11-12), wenn geschlossen. |
nextOpenClockTime |
Text? | Uhrzeit der nächsten Öffnung (11:00), wenn geschlossen. |
nextOpenDaysAhead |
Ganzzahl? | Tage bis zur nächsten Öffnung; 0 = heute noch. |
nextOpenTime |
Text? | Veraltet: nächste Öffnung als fertiger deutscher Text. Neue Anbindungen verwenden nextOpenDate und nextOpenClockTime. |
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 404 | SWITCH_DISABLED |
Der angefragte Bestellweg ist im Betrieb ausgeschaltet. |
Beispiel
{"isOpen": true, "nextOpenTime": null, "nextOpenDate": null, "nextOpenClockTime": null, "nextOpenDaysAhead": null, "currentCloseTime": "22:00"}
Wartezeit lesen¶
GET /api/v1/online-menu/wait-estimate
Schätzt aus der Küchenlast, wann eine Abholung fertig bzw. eine Lieferung da wäre, und ob der Betrieb gerade annimmt. Die Kasse hält die Auskunft je Betrieb 30 Sekunden vor; häufiger abzufragen bringt nichts.
Anmeldung: Keine Anmeldung, der Aufruf ist öffentlich.
Antwort 200
data: WaitEstimateResponse
| Feld | Typ | Bedeutung |
|---|---|---|
pickupMinutes |
Ganzzahl | Minuten bis zur Abholung. |
deliveryMinutes |
Ganzzahl | Minuten bis zur Lieferung. |
load |
Text? | Auslastung der Küche: low, normal oder high. |
readyAt |
Zeitpunkt | Voraussichtlich fertig (Abholung). |
deliveryAt |
Zeitpunkt | Voraussichtlich geliefert. |
acceptingOrders |
Ja/Nein | false: der Betrieb nimmt wegen Küchenlast gerade nicht an. |
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 404 | SWITCH_DISABLED |
Online-Bestellung ist im Betrieb ausgeschaltet. |
Beispiel
{"pickupMinutes": 15, "deliveryMinutes": 60, "tableMinutes": 15, "load": "low", "readyAt": "2026-11-10T18:58:36.3342666+01:00", "deliveryAt": "2026-11-10T19:43:36.3342666+01:00", "acceptingOrders": true, "openTickets": 0}
Shop-Angaben lesen¶
GET /api/v1/online-menu/shop-info
Öffentliche Angaben zum Shop: Name, Anschrift und Kontakt, Öffnungszeiten, angebotene Bestellwege und Zahlarten, Mindestbestellwert. Daraus lässt sich im Shop zum Beispiel ablesen, ob PayPal angeboten wird oder Sofortzahlung verlangt ist.
Anmeldung: Keine Anmeldung, der Aufruf ist öffentlich.
Antwort 200
data: OnlineShopConfigResponse
| Feld | Typ | Bedeutung |
|---|---|---|
shopName |
Text? | Name des Shops. |
shopDescription |
Text? | Beschreibung. |
shopSlogan |
Text? | Slogan. |
companyName |
Text? | Firmenname. |
street |
Text? | Straße und Hausnummer. |
zipCode |
Text? | Postleitzahl. |
city |
Text? | Ort. |
country |
Text? | Land. |
phone |
Text? | Telefon. |
email |
Text? | E-Mail-Adresse. |
openingHours |
Liste von OpeningHoursEntry? | Öffnungszeiten je Wochentag. |
pickupEnabled |
Ja/Nein | Abholung wird angeboten. |
deliveryEnabled |
Ja/Nein | Lieferung wird angeboten. |
minOrderAmount |
Dezimalzahl | Mindestbestellwert. |
orderLeadTimeMinutes |
Ganzzahl | Vorlaufzeit für Bestellungen in Minuten. |
maxScheduleDays |
Ganzzahl | Wie viele Tage im Voraus bestellt werden darf. |
stripeEnabled |
Ja/Nein | Kartenzahlung über Stripe ist eingeschaltet. |
payPalEnabled |
Ja/Nein | PayPal ist eingeschaltet. |
cashOnPickupEnabled |
Ja/Nein | Barzahlung bei Abholung ist erlaubt. |
cashOnDeliveryEnabled |
Ja/Nein | Barzahlung bei Lieferung ist erlaubt. |
prepaymentRequiredPickup |
Ja/Nein | Abholung nur mit Online-Zahlung. |
prepaymentRequiredDelivery |
Ja/Nein | Lieferung nur mit Online-Zahlung. |
Enthaltene Datenobjekte: OpeningHoursEntry.
Beispiel
curl -sS "$API/online-menu/shop-info" | jq -c '.data | {shopName, pickupEnabled, deliveryEnabled, minOrderAmount, stripeEnabled, payPalEnabled, cashOnPickupEnabled}'
{"shopName": "Pizzeria Beispiel", "pickupEnabled": true, "deliveryEnabled": true, "minOrderAmount": 0, "stripeEnabled": false, "payPalEnabled": false, "cashOnPickupEnabled": true}
Artikelbild laden¶
GET /api/v1/article-descriptions/{articleId}/images/{attachmentName}
Liefert ein Bild eines Artikels als Datei. Den Dateinamen nennt die Karte in images[].attachmentName (bzw. thumbnailName für die kleine Ansicht).
Anmeldung: Keine Anmeldung, der Aufruf ist öffentlich.
Parameter
| Name | Ort | Typ | Pflicht | Bedeutung |
|---|---|---|---|---|
articleId |
Pfad | Text | ja | Kennung des Artikels (art_…). |
attachmentName |
Pfad | Text | ja | Dateiname aus images[].attachmentName. |
Antwort 200
Das Bild als Datei, in der Regel image/webp. Ein unbekannter Name ergibt 404.
Beispiel
Online-Bestellung¶
Der Weg einer Bestellung: anlegen, Stand abfragen, gegebenenfalls online bezahlen; auf der Seite des Betriebs annehmen oder ablehnen. Der Ablauf im Zusammenhang steht im Leitfaden Eigenen Webshop anbinden.
Bestellung anlegen¶
POST /api/v1/online-checkout/create
Legt eine Bestellung an und übergibt sie an die Kasse: Die Kasse prüft Öffnungszeiten, Verfügbarkeit, Optionen und Liefergebiet, rechnet mit ihren eigenen Preisen und legt einen Auftrag im Lieferservice an. Die Antwort enthält einmalig das Bestell-Geheimnis (guestSecret).
Anmeldung: Keine Anmeldung, der Aufruf ist öffentlich.
Parameter
| Name | Ort | Typ | Pflicht | Bedeutung |
|---|---|---|---|---|
Idempotency-Key |
Kopfzeile | Text | nein | Neuer Wert je Bestellung (8 bis 200 Zeichen), zum Beispiel eine UUID. Wiederholt der Shop den Aufruf nach einem Netzfehler mit demselben Schlüssel und Inhalt, kommt dieselbe Bestellung zurück. Anderer Inhalt: 422 IDEMPOTENCY_KEY_REUSED. Dringend empfohlen. |
Anfrage (application/json)
Die Preise bestimmt die Kasse; ein vom Shop mitgesendeter Preis zählt nicht. Bei Optionen genügt der Name aus der Karte.
| Feld | Typ | Pflicht | Bedeutung |
|---|---|---|---|
orderType |
Ganzzahl | ja | 0 Abholung, 1 Lieferung. (2 ist die QR-Tischbestellung der Kasse und für Shops nicht vorgesehen.) |
customerName |
Text | ja | Name des Gastes, höchstens 200 Zeichen. |
customerEmail |
Text | ja | E-Mail-Adresse des Gastes, gültig, höchstens 200 Zeichen. Die Bestätigung geht dorthin. |
customerPhone |
Text | nein | Telefon, höchstens 30 Zeichen. Für Lieferungen sinnvoll. |
items |
Liste von OnlineOrderItemRequest | ja | Die Positionen, mindestens eine. |
paymentMethod |
Text | nein | cash, stripe oder paypal; immer angeben. Verlangt der Betrieb Sofortzahlung (prepaymentRequired… in Shop-Angaben), ist nur stripe oder paypal zulässig, sonst PREPAYMENT_REQUIRED. |
street |
Text | bedingt | Straße, bei Lieferung Pflicht. |
houseNumber |
Text | nein | Hausnummer (höchstens 20 Zeichen). |
zipCode |
Text | bedingt | Postleitzahl, bei Lieferung Pflicht. |
city |
Text | bedingt | Ort, bei Lieferung Pflicht. |
deliveryNotes |
Text | nein | Hinweis für den Fahrer, höchstens 2000 Zeichen. |
floor |
Text | nein | Stockwerk. |
doorBell |
Text | nein | Klingelschild. |
requestedTime |
Zeitpunkt | nein | Wunschzeitpunkt (ISO-8601). Ohne Angabe so bald wie möglich. |
kitchenNotes |
Text | nein | Hinweis für die Küche. |
tipAmount |
Dezimalzahl | nein | Trinkgeld, 0 bis 10 000; nur mit Online-Zahlung, sonst TIP_ONLINE_ONLY. |
externalReference |
Text | nein | Eigene Bestellnummer des Shops, höchstens 100 Zeichen, ohne Steuerzeichen. Nur mit Benutzer-Anmeldung (Bearer) wirksam; ohne Anmeldung und mit Partner-Schlüssel wird sie ignoriert. Dieselbe Nummer mit demselben Inhalt liefert die vorhandene Bestellung zurück, mit anderem Inhalt 409 EXTERNAL_REFERENCE_CONFLICT. |
Enthaltene Datenobjekte: OnlineOrderItemRequest.
Antwort 200
data: OnlineOrderResponse
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 400 | VALIDATION_ERROR |
Pflichtfeld fehlt oder ist ungültig (keine Position, Menge außerhalb 1 bis 999, Lieferadresse fehlt, ungültige E-Mail-Adresse). |
| 400 | SHOP_CLOSED |
Außerhalb der Öffnungszeiten. |
| 400 | SHOP_OVERLOADED |
Der Betrieb nimmt wegen Küchenlast gerade nicht an. |
| 400 | ARTICLE_SOLD_OUT |
Ein Artikel ist heute nicht verfügbar (soldOut). |
| 400 | ARTICLE_POS_ONLY |
Ein Artikel ist nur an der Kasse verkäuflich (zum Beispiel Gutscheine und Guthaben-Aufladungen). |
| 404 | ENTITY_NOT_FOUND |
Ein Artikel ist unbekannt oder nicht online sichtbar. |
| 400 | INVALID_OPTION |
Option unbekannt, mehrfach gewählt, oder in einer Einzelwahl-Gruppe mehr als eine. |
| 400 | REQUIRED_OPTION_MISSING |
Für eine Pflichtgruppe wurde keine Option gewählt. |
| 400 | MIN_ORDER_AMOUNT |
Mindestbestellwert nicht erreicht. |
| 400 | DELIVERY_AREA_NOT_COVERED |
Die Lieferadresse liegt außerhalb der Liefergebiete. |
| 400 | DELIVERY_MODULE_REQUIRED |
Lieferung braucht das Modul Lieferservice. |
| 400 | PREPAYMENT_REQUIRED |
Der Betrieb verlangt Online-Zahlung (stripe oder paypal). |
| 400 | TIP_ONLINE_ONLY |
Trinkgeld nur mit Online-Zahlung. |
| 400 | AGE_VERIFICATION_REQUIRED |
Ein Artikel ist altersbeschränkt und nur vor Ort bestellbar, nicht online. |
| 400 | ONLINE_ORDER_DISABLED |
Online-Bestellung ist im Betrieb ausgeschaltet. |
| 400 | ONLINEORDER_MODULE_REQUIRED |
Das Modul Online-Bestellung fehlt in der Lizenz. |
| 422 | IDEMPOTENCY_KEY_REUSED |
Derselbe Idempotency-Key mit anderem Inhalt (innerhalb der Wiederholungs-Zwischenspeicherung, eine Stunde). |
| 409 | IDEMPOTENCY_KEY_REUSED |
Der Idempotency-Key gehört schon zu einer anderen Bestellung (nach Ablauf dieser Stunde). |
| 409 | EXTERNAL_REFERENCE_CONFLICT |
Dieselbe externalReference mit anderem Inhalt (nur mit Benutzer-Anmeldung, siehe Feld). |
Bestell-Geheimnis sofort speichern
guestSecret steht nur in dieser Antwort. Wer es nicht speichert, kann die Bestellung später weder abfragen noch bezahlen noch stornieren (mit Benutzer-Anmeldung oder Partner-Schlüssel bleibt die Bestellung über die Listen erreichbar).
Beispiel
curl -sS -X POST "$API/online-checkout/create" -H 'Content-Type: application/json' \
-H "Idempotency-Key: $(cat /proc/sys/kernel/random/uuid)" -d '{
"orderType": 0, "customerName": "Erika Muster", "customerEmail": "erika@example.com", "customerPhone": "0123 456789",
"items": [ { "articleId": "art_917c19d4a18a", "quantity": 1, "notes": "ohne Zwiebeln" } ],
"paymentMethod": "cash" }' | jq -c '.data | {id, orderNumber, status, grandTotal, guestSecret}'
Gekürzt mit jq. Das vollständige Objekt steht unter OnlineOrderResponse.
{"id": "olord_648e7d3cfa87", "orderNumber": "ON-20261110-001", "status": 1, "grandTotal": 9.5, "guestSecret": "q7Xm2LkP9vRtY4cNw8ZsB3hJdF6aGeUo"}
Bestellung lesen¶
GET /api/v1/online-checkout/{id}
Liefert den aktuellen Stand einer Bestellung. Der Shop fragt damit für die Statusseite des Gastes ab (alle 10 bis 15 Sekunden genügen).
Anmeldung: Bestell-Geheimnis (guestSecret aus der Antwort von Bestellung anlegen) in der Kopfzeile X-Order-Secret. Ohne oder mit falschem Geheimnis antwortet die Kasse 404 ENTITY_NOT_FOUND, genau wie bei einer unbekannten Bestellung. Als Ausweichweg für Links gibt es den Abfrageparameter s; die Kopfzeile ist vorzuziehen, weil sie in keinem Zugriffsprotokoll landet. Ein angemeldeter Kassenbenutzer (Bearer) braucht das Geheimnis nicht; ein Partner-Schlüssel ersetzt es nicht.
Parameter
| Name | Ort | Typ | Pflicht | Bedeutung |
|---|---|---|---|---|
id |
Pfad | Text | ja | Kennung des Objekts, wie sie die Kasse in früheren Antworten genannt hat (olord_…, art_…, whz_…, pak_…). |
Antwort 200
data: OnlineOrderResponse
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 404 | ENTITY_NOT_FOUND |
Bestellung unbekannt, oder das Bestell-Geheimnis fehlt bzw. passt nicht. |
Beispiel
curl -sS "$API/online-checkout/$BESTELLUNG" -H "X-Order-Secret: $GEHEIMNIS" | jq -c '.data | {id, status, isPaid, estimatedReadyTime}'
Online-Zahlung starten¶
POST /api/v1/online-checkout/{id}/init-payment
Startet die Zahlung bei Stripe oder PayPal. Stripe: die Antwort liefert clientSecret und publishableKey für Stripe.js im Browser des Gastes. PayPal: die Antwort liefert eine redirectUrl, zu der der Gast weitergeleitet wird. Nur für Bestellungen im Stand 1 oder 2, die noch nicht bezahlt sind.
Anmeldung: Bestell-Geheimnis (guestSecret aus der Antwort von Bestellung anlegen) in der Kopfzeile X-Order-Secret. Ohne oder mit falschem Geheimnis antwortet die Kasse 404 ENTITY_NOT_FOUND, genau wie bei einer unbekannten Bestellung. Als Ausweichweg für Links gibt es den Abfrageparameter s; die Kopfzeile ist vorzuziehen, weil sie in keinem Zugriffsprotokoll landet. Ein angemeldeter Kassenbenutzer (Bearer) braucht das Geheimnis nicht; ein Partner-Schlüssel ersetzt es nicht.
Parameter
| Name | Ort | Typ | Pflicht | Bedeutung |
|---|---|---|---|---|
id |
Pfad | Text | ja | Kennung des Objekts, wie sie die Kasse in früheren Antworten genannt hat (olord_…, art_…, whz_…, pak_…). |
Anfrage (application/json)
| Feld | Typ | Pflicht | Bedeutung |
|---|---|---|---|
provider |
Text | nein | stripe oder paypal. Ohne Angabe richtet sich der Dienst nach der Zahlart der Bestellung. |
returnUrl |
Text | bedingt | PayPal: https-Adresse, auf die der Gast nach dem Bezahlen zurückkommt. Für PayPal Pflicht. |
cancelUrl |
Text | nein | PayPal: Adresse bei Abbruch. Ohne Angabe returnUrl. |
Antwort 200
data: OnlinePaymentInitResponse
| Feld | Typ | Bedeutung |
|---|---|---|
provider |
Text? | stripe oder paypal. |
clientSecret |
Text? | Stripe: Client-Secret des Zahlungsvorgangs für Stripe.js. Bei PayPal leer. |
publishableKey |
Text? | Stripe: öffentlicher Schlüssel des Betriebs für Stripe.js. |
paymentIntentId |
Text? | Stripe: Kennung des Zahlungsvorgangs. |
redirectUrl |
Text? | PayPal: Adresse, zu der der Gast weitergeleitet wird. |
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 404 | ENTITY_NOT_FOUND |
Bestellung unbekannt oder Geheimnis falsch. |
| 400 | ALREADY_PAID |
Die Bestellung ist schon bezahlt. |
| 400 | INVALID_STATUS |
Die Bestellung ist nicht mehr im Stand 1 oder 2. |
| 400 | STRIPE_NOT_CONFIGURED |
Der Betrieb hat Stripe nicht eingerichtet. |
| 400 | PAYPAL_NOT_ENABLED |
PayPal ist im Shop nicht eingeschaltet. |
| 400 | PAYPAL_NOT_CONFIGURED |
Der Betrieb hat PayPal nicht eingerichtet. |
| 400 | RETURN_URL_REQUIRED |
PayPal braucht returnUrl (absolute https-Adresse). |
Die Beispielantwort entfällt: auf einem Betrieb ohne eingerichtetes Stripe antwortet der Aufruf 400 STRIPE_NOT_CONFIGURED.
Beispiel
curl -sS -X POST "$API/online-checkout/$BESTELLUNG/init-payment" -H "X-Order-Secret: $GEHEIMNIS" \
-H 'Content-Type: application/json' -d '{"provider":"stripe"}' | jq -c '.data | {provider, publishableKey, clientSecret}'
Zahlung prüfen¶
POST /api/v1/online-checkout/{id}/verify-payment
Prüft die Zahlung serverseitig bei Stripe bzw. PayPal und markiert die Bestellung erst dann als bezahlt (isPaid). Der Shop ruft ihn nach der Rückkehr des Gastes auf. Eine noch nicht bezahlte Bestellung kommt unverändert zurück.
Anmeldung: Bestell-Geheimnis (guestSecret aus der Antwort von Bestellung anlegen) in der Kopfzeile X-Order-Secret. Ohne oder mit falschem Geheimnis antwortet die Kasse 404 ENTITY_NOT_FOUND, genau wie bei einer unbekannten Bestellung. Als Ausweichweg für Links gibt es den Abfrageparameter s; die Kopfzeile ist vorzuziehen, weil sie in keinem Zugriffsprotokoll landet. Ein angemeldeter Kassenbenutzer (Bearer) braucht das Geheimnis nicht; ein Partner-Schlüssel ersetzt es nicht.
Parameter
| Name | Ort | Typ | Pflicht | Bedeutung |
|---|---|---|---|---|
id |
Pfad | Text | ja | Kennung des Objekts, wie sie die Kasse in früheren Antworten genannt hat (olord_…, art_…, whz_…, pak_…). |
Antwort 200
data: OnlineOrderResponse
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 404 | ENTITY_NOT_FOUND |
Bestellung unbekannt, oder das Bestell-Geheimnis fehlt bzw. passt nicht. |
Beispiel
curl -sS -X POST "$API/online-checkout/$BESTELLUNG/verify-payment" -H "X-Order-Secret: $GEHEIMNIS" | jq -c '.data | {status, isPaid, amountDue}'
Noch nicht bezahlt: die Bestellung kommt unverändert zurück. Nach erfolgreicher Online-Zahlung steht isPaid auf true und amountDue auf 0.
Bestellung stornieren¶
POST /api/v1/online-checkout/{id}/cancel
Storniert eine Bestellung, solange der Betrieb sie noch nicht angenommen hat (Stand unter 4). War sie schon online bezahlt, storniert die Kasse fiskalisch und erstattet den Betrag über den Zahlungsdienst.
Anmeldung: Bestell-Geheimnis (guestSecret aus der Antwort von Bestellung anlegen) in der Kopfzeile X-Order-Secret. Ohne oder mit falschem Geheimnis antwortet die Kasse 404 ENTITY_NOT_FOUND, genau wie bei einer unbekannten Bestellung. Als Ausweichweg für Links gibt es den Abfrageparameter s; die Kopfzeile ist vorzuziehen, weil sie in keinem Zugriffsprotokoll landet. Ein angemeldeter Kassenbenutzer (Bearer) braucht das Geheimnis nicht; ein Partner-Schlüssel ersetzt es nicht.
Parameter
| Name | Ort | Typ | Pflicht | Bedeutung |
|---|---|---|---|---|
id |
Pfad | Text | ja | Kennung des Objekts, wie sie die Kasse in früheren Antworten genannt hat (olord_…, art_…, whz_…, pak_…). |
Antwort 200
data: OnlineOrderResponse
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 404 | ENTITY_NOT_FOUND |
Bestellung unbekannt oder Geheimnis falsch. |
| 400 | CANNOT_CANCEL |
Der Betrieb hat die Bestellung schon angenommen; nur noch der Betrieb kann sie ablehnen. |
Beispiel
curl -sS -X POST "$API/online-checkout/$BESTELLUNG/cancel" -H "X-Order-Secret: $GEHEIMNIS" | jq -c '.data | {id, status}'
Offene Bestellungen lesen¶
GET /api/v1/online-checkout/pending
Die Bestellungen, die der Betrieb noch bearbeiten muss.
Anmeldung: Partner-Schlüssel mit dem Bereich orders:read in der Kopfzeile X-Dikas-Api-Key, oder eine Benutzer-Anmeldung (Bearer-Token). Ein Schlüssel ohne diesen Bereich wird mit 403 abgewiesen, ein ungültiger, abgelaufener oder widerrufener mit 401.
Antwort 200
data: Liste von OnlineOrderResponse?
Beispiel
curl -sS "$API/online-checkout/pending" -H "X-Dikas-Api-Key: $PARTNER_SCHLUESSEL" | jq -c '.data[] | {id, orderNumber, status, grandTotal}'
Heutige Bestellungen lesen¶
GET /api/v1/online-checkout/today
Alle Online-Bestellungen des heutigen Tages, in jedem Stand. Die Antwort enthält den Namen und die Kontaktdaten des Gastes; sie sind nur im Rahmen der Bestellabwicklung zu verwenden.
Anmeldung: Partner-Schlüssel mit dem Bereich orders:read in der Kopfzeile X-Dikas-Api-Key, oder eine Benutzer-Anmeldung (Bearer-Token). Ein Schlüssel ohne diesen Bereich wird mit 403 abgewiesen, ein ungültiger, abgelaufener oder widerrufener mit 401.
Antwort 200
data: Liste von OnlineOrderResponse?
Beispiel
curl -sS "$API/online-checkout/today" -H "X-Dikas-Api-Key: $PARTNER_SCHLUESSEL" | jq -c '[.data[] | {id, status, isPaid}]'
Bestellung annehmen¶
POST /api/v1/online-checkout/{id}/confirm
Nimmt eine Bestellung an: Die Kasse legt den Lieferauftrag an, erzeugt die Küchenbons und druckt sie bzw. zeigt sie auf dem Küchenmonitor, und der Gast bekommt seine Bestätigung. Ein zweiter Aufruf ändert nichts und liefert die Bestellung unverändert zurück. Zum Annehmen nicht den Status 4 setzen: erst confirm löst Bons und Auftrag aus.
Anmeldung: Partner-Schlüssel mit dem Bereich orders:manage in der Kopfzeile X-Dikas-Api-Key, oder eine Benutzer-Anmeldung (Bearer-Token). Ein Schlüssel ohne diesen Bereich wird mit 403 abgewiesen, ein ungültiger, abgelaufener oder widerrufener mit 401.
Parameter
| Name | Ort | Typ | Pflicht | Bedeutung |
|---|---|---|---|---|
id |
Pfad | Text | ja | Kennung des Objekts, wie sie die Kasse in früheren Antworten genannt hat (olord_…, art_…, whz_…, pak_…). |
estimatedMinutes |
Abfrage | Ganzzahl | nein | Zugesagte Dauer in Minuten bis zur Fertigstellung. |
Antwort 200
data: OnlineOrderResponse
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 404 | ENTITY_NOT_FOUND |
Bestellung unbekannt. |
Beispiel
curl -sS -X POST "$API/online-checkout/$BESTELLUNG/confirm?estimatedMinutes=20" -H "X-Dikas-Api-Key: $PARTNER_SCHLUESSEL" | jq -c '.data | {id, status}'
Bestellung ablehnen¶
POST /api/v1/online-checkout/{id}/reject
Lehnt eine Bestellung ab. War sie schon online bezahlt, storniert die Kasse fiskalisch und erstattet den Betrag über den Zahlungsdienst. Ein zweiter Aufruf ändert nichts.
Anmeldung: Partner-Schlüssel mit dem Bereich orders:manage in der Kopfzeile X-Dikas-Api-Key, oder eine Benutzer-Anmeldung (Bearer-Token). Ein Schlüssel ohne diesen Bereich wird mit 403 abgewiesen, ein ungültiger, abgelaufener oder widerrufener mit 401.
Parameter
| Name | Ort | Typ | Pflicht | Bedeutung |
|---|---|---|---|---|
id |
Pfad | Text | ja | Kennung des Objekts, wie sie die Kasse in früheren Antworten genannt hat (olord_…, art_…, whz_…, pak_…). |
Anfrage (application/json)
| Feld | Typ | Pflicht | Bedeutung |
|---|---|---|---|
reason |
Text | nein | Grund, wird in rejectionReason der Bestellung gespeichert. Nicht erzwungen, aber zu empfehlen: der Betrieb sieht ihn. |
Antwort 200
data: OnlineOrderResponse
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 404 | ENTITY_NOT_FOUND |
Bestellung unbekannt. |
Beispiel
curl -sS -X POST "$API/online-checkout/$BESTELLUNG/reject" -H "X-Dikas-Api-Key: $PARTNER_SCHLUESSEL" \
-H 'Content-Type: application/json' -d '{"reason":"Heute geschlossen"}' | jq -c '.data | {id, status, rejectionReason}'
Bestellstatus setzen¶
PUT /api/v1/online-checkout/{id}/status
Setzt den Stand einer Bestellung (zum Beispiel 5 in Zubereitung, 6 bereit, 8 abgeschlossen) und benachrichtigt den Gast bei „bereit“ und „unterwegs“. Der Aufruf ändert nur den Stand: Bons und Aufträge legen confirm und die Kasse an. Eine feste Reihenfolge der Stände wird nicht erzwungen. Die Zuständigkeit klären Shop und Betrieb vorab: führt der Betrieb den Ablauf im Lieferservice, setzt sich der Stand dort; ein zusätzliches Setzen aus dem Shop ist dann nicht nötig.
Anmeldung: Partner-Schlüssel mit dem Bereich orders:manage in der Kopfzeile X-Dikas-Api-Key, oder eine Benutzer-Anmeldung (Bearer-Token). Ein Schlüssel ohne diesen Bereich wird mit 403 abgewiesen, ein ungültiger, abgelaufener oder widerrufener mit 401.
Parameter
| Name | Ort | Typ | Pflicht | Bedeutung |
|---|---|---|---|---|
id |
Pfad | Text | ja | Kennung des Objekts, wie sie die Kasse in früheren Antworten genannt hat (olord_…, art_…, whz_…, pak_…). |
Anfrage (application/json)
| Feld | Typ | Pflicht | Bedeutung |
|---|---|---|---|
status |
Ganzzahl | ja | Neuer Stand, 1 bis 10 (Werte siehe status der Bestellung). |
reason |
Text | nein | Grund; wird bei 9 und 10 als rejectionReason gespeichert. |
Antwort 200
data: OnlineOrderResponse
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 400 | VALIDATION_ERROR |
status liegt nicht zwischen 1 und 10. |
| 404 | ENTITY_NOT_FOUND |
Bestellung unbekannt. |
Beispiel
curl -sS -X PUT "$API/online-checkout/$BESTELLUNG/status" -H "X-Dikas-Api-Key: $PARTNER_SCHLUESSEL" \
-H 'Content-Type: application/json' -d '{"status":5}' | jq -c '.data | {id, status}'
Artikel und Warengruppen¶
Pflegt der Shop die Karte, überträgt er Artikel und Warengruppen mit Benutzer-Anmeldung an die Kasse. Vorab festlegen, wer führend ist: Pflegt der Betrieb dieselben Artikel auch in der Kasse, laufen Preise auseinander. Die Warengruppen sind hierarchisch nummeriert: eine Hauptgruppe hat drei Ziffern (100), jede Untergruppe hängt zwei Ziffern an (10001). Artikel erscheinen nur in Untergruppen. Das Feld groupId am Artikel trägt die Kennung der Gruppe (artgrp_…), nicht die Gruppennummer.
Warengruppen lesen¶
GET /api/v1/articles/groups
Liefert die Warengruppen des Betriebs, auf Wunsch nur aktive oder die Untergruppen einer Hauptgruppe.
Anmeldung: Benutzer-Anmeldung: Authorization: Bearer <Token>, das Token aus POST /api/v1/auth/login. Es gelten die Rechte des Benutzers. Ein Partner-Schlüssel wird an diesem Aufruf nicht angenommen (401).
Parameter
| Name | Ort | Typ | Pflicht | Bedeutung |
|---|---|---|---|---|
activeOnly |
Abfrage | Ja/Nein | nein | true (Vorgabe): deaktivierte Gruppen ausblenden. |
parentGroupId |
Abfrage | Text | nein | Nur Untergruppen dieser Hauptgruppe (Gruppennummer, 100). |
Antwort 200
data: Liste von ArticleGroupResponse?
Beispiel
curl -sS "$API/articles/groups" -H "Authorization: Bearer $TOKEN" | jq -c '.data[] | {id, groupId, name, parentId}'
Je Gruppe eine Zeile (jq -c).
Warengruppe anlegen¶
POST /api/v1/articles/groups
Legt eine Warengruppe an. Die übergeordnete Gruppe ergibt sich aus der Nummer: 10001 gehört zu 100.
Anmeldung: Benutzer-Anmeldung: Authorization: Bearer <Token>, das Token aus POST /api/v1/auth/login. Es gelten die Rechte des Benutzers. Ein Partner-Schlüssel wird an diesem Aufruf nicht angenommen (401).
Anfrage (application/json)
| Feld | Typ | Pflicht | Bedeutung |
|---|---|---|---|
groupId |
Text | ja | Gruppennummer, nur Ziffern: Hauptgruppe 3 Ziffern, jede Untergruppe hängt zwei Ziffern an (100, 10001). Eine vorhandene Nummer ergibt DUPLICATE_GROUP_ID. |
name |
Text | ja | Name. |
shortName |
Text | nein | Kurzname. |
description |
Text | nein | Beschreibung. |
color |
Text | nein | Farbe (#C683CD); ohne Angabe wählt die Kasse eine. |
sortOrder |
Ganzzahl | nein | Sortierwert. |
isActive |
Ja/Nein | nein | Aktiv. |
Antwort 201
data: ArticleGroupResponse
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 400 | DUPLICATE_GROUP_ID |
Die Gruppennummer ist schon vergeben. |
| 400 | VALIDATION_ERROR |
Name oder Gruppennummer fehlen oder sind ungültig. |
Beispiel
curl -sS -X POST "$API/articles/groups" -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"groupId":"10097","name":"Pasta","sortOrder":3,"isActive":true}' | jq -c '.data | {id, groupId, name, parentId}'
Die Antwort hat den Status 201.
Warengruppe ändern¶
PATCH /api/v1/articles/groups/{documentId}
Ändert einzelne Felder einer Warengruppe als JSON Patch (siehe Grundlagen). documentId ist die Kennung artgrp_…. Nicht änderbar sind unter anderem id, groupId und parentId.
Anmeldung: Benutzer-Anmeldung: Authorization: Bearer <Token>, das Token aus POST /api/v1/auth/login. Es gelten die Rechte des Benutzers. Ein Partner-Schlüssel wird an diesem Aufruf nicht angenommen (401).
Parameter
| Name | Ort | Typ | Pflicht | Bedeutung |
|---|---|---|---|---|
documentId |
Pfad | Text | ja | Kennung der Warengruppe (artgrp_…). |
Anfrage (application/json, application/json-patch+json)
Als Content-Type: application/json-patch+json. Beispiel: [{"op":"replace","path":"/sortOrder","value":4}].
Body: Liste von JsonPatchOperation
Antwort 200
data: ArticleGroupResponse
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 404 | ENTITY_NOT_FOUND |
Warengruppe unbekannt. |
| 409 | PATCH_TEST_FAILED |
Eine test-Operation hat nicht gehalten: der Wert wurde inzwischen geändert; validationErrors nennt Pfad, erwarteten und gefundenen Wert. Es wird nichts geschrieben. |
| 400 | PATCH_FIELD_UNKNOWN |
Der Pfad ist unbekannt oder nicht schreibbar. |
| 400 | PATCH_FIELD_READONLY |
Das Feld wird von der Kasse berechnet und ist nicht schreibbar. |
| 400 | PATCH_INVALID |
Der Wert ist ungültig oder das Feld lässt sich nicht leeren. |
Beispiel
curl -sS -X PATCH "$API/articles/groups/$GRUPPE" -H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json-patch+json' -d '[{"op":"replace","path":"/sortOrder","value":4}]' \
| jq -c '.data | {id, name, sortOrder}'
Artikel lesen¶
GET /api/v1/articles
Liefert Artikel, auf Wunsch einer Gruppe, mit Seitenweise-Abruf. Deaktivierte Artikel fehlen in der Voreinstellung.
Anmeldung: Benutzer-Anmeldung: Authorization: Bearer <Token>, das Token aus POST /api/v1/auth/login. Es gelten die Rechte des Benutzers. Ein Partner-Schlüssel wird an diesem Aufruf nicht angenommen (401).
Parameter
| Name | Ort | Typ | Pflicht | Bedeutung |
|---|---|---|---|---|
groupId |
Abfrage | Text | nein | Nur Artikel dieser Gruppe (Kennung artgrp_…). |
activeOnly |
Abfrage | Ja/Nein | nein | true (Vorgabe): deaktivierte Artikel ausblenden. |
limit |
Abfrage | Ganzzahl | nein | Höchstzahl je Aufruf; ohne Angabe alle. |
skip |
Abfrage | Ganzzahl | nein | Wie viele Artikel am Anfang übersprungen werden. |
Antwort 200
data: Liste von ArticleResponse?
Beispiel
curl -sS "$API/articles?groupId=$GRUPPE&limit=50" -H "Authorization: Bearer $TOKEN" | jq -c '.data[] | {id, name, price, groupId}'
{"id": "art_f6f95549ca21", "name": "Spaghetti Bolognese", "price": 13.5, "groupId": "artgrp_a86a901e51a4"}
Einen Artikel lesen¶
GET /api/v1/articles/{id}
Liefert einen Artikel. Das Feld version ist die Versionsmarke, die sich bei jeder Änderung ändert.
Anmeldung: Benutzer-Anmeldung: Authorization: Bearer <Token>, das Token aus POST /api/v1/auth/login. Es gelten die Rechte des Benutzers. Ein Partner-Schlüssel wird an diesem Aufruf nicht angenommen (401).
Parameter
| Name | Ort | Typ | Pflicht | Bedeutung |
|---|---|---|---|---|
id |
Pfad | Text | ja | Kennung des Objekts, wie sie die Kasse in früheren Antworten genannt hat (olord_…, art_…, whz_…, pak_…). |
Antwort 200
data: ArticleResponse
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 404 | ENTITY_NOT_FOUND |
Artikel unbekannt. |
Beispiel
curl -sS "$API/articles/$ARTIKEL" -H "Authorization: Bearer $TOKEN" | jq -c '.data | {id, name, price, taxClass, taxRate, manualSoldOut, hideFromMenu}'
{"id": "art_f6f95549ca21", "name": "Spaghetti Bolognese", "price": 12.5, "taxClass": 1, "taxRate": 7, "manualSoldOut": false, "hideFromMenu": false}
Artikel anlegen¶
POST /api/v1/articles
Legt einen Artikel an. Der Artikel erscheint in der Karte, sobald er aktiv ist, in einer Untergruppe liegt und nicht ausgeblendet ist. Optionen (Extras, Größen) und Allergene pflegt der Betrieb in der Kasse; der Shop liest sie aus der Karte.
Anmeldung: Benutzer-Anmeldung: Authorization: Bearer <Token>, das Token aus POST /api/v1/auth/login. Es gelten die Rechte des Benutzers. Ein Partner-Schlüssel wird an diesem Aufruf nicht angenommen (401).
Anfrage (application/json)
Die Anfrage kennt weitere Felder der Kasse (Lager, Rezepturen, Druckoptionen); für die Anbindung genügen die folgenden.
| Feld | Typ | Pflicht | Bedeutung |
|---|---|---|---|
name |
Text | ja | Name des Artikels. |
taxClass |
Ganzzahl | bedingt | Steuerart: 0 Normalsatz, 1 ermäßigt, 99 steuerfrei. Entweder taxClass oder taxRate ist nötig, sonst ARTIKEL_TYP_ERFORDERLICH. |
taxRate |
Dezimalzahl | bedingt | Steuersatz in Prozent; wird auf die passende Steuerart abgebildet, wenn taxClass fehlt. Entweder taxClass oder taxRate ist nötig. |
groupId |
Text | nein | Kennung der Warengruppe (artgrp_…) — eine Untergruppe; Artikel ohne Gruppe oder in Hauptgruppen erscheinen nicht in der Karte. Die Kasse prüft die Kennung nicht: eine unbekannte wird angenommen, der Artikel ist dann nirgends zugeordnet. |
price |
Dezimalzahl | nein | Verkaufspreis; immer angeben. |
articleNumber |
Text | nein | Artikelnummer. |
shortName |
Text | nein | Kurzname. |
description |
Text | nein | Beschreibung. |
unit |
Text | nein | Einheit (Stück). |
barcode |
Text | nein | Strichcode. |
isActive |
Ja/Nein | nein | Aktiv; sonst weder Kasse noch Shop. |
hideFromMenu |
Ja/Nein | nein | true: nicht im Shop, an der Kasse buchbar. |
manualSoldOut |
Ja/Nein | nein | true: heute nicht verfügbar. |
allergens |
Liste von Text | nein | Allergen-Kürzel. |
sortOrder |
Ganzzahl | nein | Sortierwert. |
pfand |
Dezimalzahl | nein | Pfand je Einheit. |
Antwort 201
data: ArticleResponse
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 400 | VALIDATION_ERROR |
Name fehlt oder ein Wert ist ungültig. |
| 400 | ARTIKEL_TYP_ERFORDERLICH |
Weder taxClass noch taxRate angegeben; die Kasse nimmt keinen Standardsatz an. |
| 400 | ARTICLE_NUMBER_TAKEN |
Die Artikelnummer ist schon vergeben. |
Beispiel
curl -sS -X POST "$API/articles" -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' -d "{
\"articleNumber\":\"2101\", \"name\":\"Spaghetti Bolognese\", \"description\":\"Hackfleischsauce, Parmesan\",
\"groupId\":\"$GRUPPE\", \"price\":12.5, \"taxRate\":7, \"isActive\":true }" | jq -c '.data | {id, name, price}'
Die Antwort hat den Status 201.
Artikel ändern¶
PATCH /api/v1/articles/{id}
Ändert einzelne Felder eines Artikels als JSON Patch (siehe Grundlagen): nur die genannten Felder werden geschrieben, alle anderen bleiben, auch wenn der Betrieb sie inzwischen in der Kasse geändert hat. Jede Änderung sollte eine test-Operation auf den Ausgangswert tragen. Ein Feld auf null zu setzen leert es; Name, Preis und Haken lassen sich nicht leeren. Von der Kasse berechnete Felder (taxRate, Zeitstempel) lassen sich nicht schreiben.
Anmeldung: Benutzer-Anmeldung: Authorization: Bearer <Token>, das Token aus POST /api/v1/auth/login. Es gelten die Rechte des Benutzers. Ein Partner-Schlüssel wird an diesem Aufruf nicht angenommen (401).
Parameter
| Name | Ort | Typ | Pflicht | Bedeutung |
|---|---|---|---|---|
id |
Pfad | Text | ja | Kennung des Objekts, wie sie die Kasse in früheren Antworten genannt hat (olord_…, art_…, whz_…, pak_…). |
Anfrage (application/json, application/json-patch+json)
Als Content-Type: application/json-patch+json. Häufige Pfade: /price (Preis), /manualSoldOut (heute nicht verfügbar), /hideFromMenu (nicht im Shop), /isActive (ganz abschalten), /name, /description.
Body: Liste von JsonPatchOperation
Antwort 200
data: ArticleResponse
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 404 | ENTITY_NOT_FOUND |
Artikel unbekannt. |
| 409 | PATCH_TEST_FAILED |
Eine test-Operation hat nicht gehalten; es wird nichts geschrieben. |
| 400 | PATCH_FIELD_UNKNOWN |
Der Pfad ist unbekannt oder nicht schreibbar. |
| 400 | PATCH_FIELD_READONLY |
Das Feld wird von der Kasse berechnet (taxRate, Zeitstempel). |
| 400 | PATCH_INVALID |
Der Wert ist ungültig oder das Feld lässt sich nicht leeren. |
Beispiel
curl -sS -X PATCH "$API/articles/$ARTIKEL" -H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json-patch+json' \
-d '[{"op":"test","path":"/price","value":12.5},{"op":"replace","path":"/price","value":13.5}]' \
| jq -c '.data | {id, price, version}'
Hat sich der Preis inzwischen geändert, antwortet die Kasse mit 409 und schreibt nichts:
{"success": false, "data": null, "errorCode": "PATCH_TEST_FAILED", "errorMessage": "Zwischenzeitlich geaendert: /price. Bitte neu laden.", "validationErrors": [{"field": "/price", "message": "erwartet: 1, gefunden: 9.5"}]}
Ereignis-Feed¶
Der Feed liefert dieselben Ereignisse, die auch an ein Webhook-Ziel gesendet werden. Er ist der Weg ohne eigene öffentliche Adresse und die Rückfallebene, wenn ein Webhook-Empfänger ausfiel. Die Ereignisse enthalten bewusst keine Namen, Adressen oder Positionen, nur Kennungen und Stand; Einzelheiten holt der Shop mit seinem Schlüssel (orders:read). Zustellung mindestens einmal: Empfänger entdoppeln über id und ordnen über seq. Ereignisse werden 14 Tage aufbewahrt.
Ereignisse lesen¶
GET /api/v1/events
Liefert die Ereignisse nach einem Zeiger. Ohne after kommen die der letzten 24 Stunden. Die Antwort nennt in nextCursor den Zeiger für den nächsten Aufruf, auch wenn es nichts Neues gab. Ein Ereignis ist erst zwei Sekunden nach seiner Entstehung sichtbar.
Anmeldung: Partner-Schlüssel mit dem Bereich events:read in der Kopfzeile X-Dikas-Api-Key, oder eine Benutzer-Anmeldung (Bearer-Token). Ein Schlüssel ohne diesen Bereich wird mit 403 abgewiesen, ein ungültiger, abgelaufener oder widerrufener mit 401.
Parameter
| Name | Ort | Typ | Pflicht | Bedeutung |
|---|---|---|---|---|
after |
Abfrage | Text | nein | Zeiger aus nextCursor der letzten Antwort. |
limit |
Abfrage | Ganzzahl | nein | Größe der Seite, 1 bis 500; Vorgabe 100. |
Antwort 200
data: WebhookEventsPageResponse
| Feld | Typ | Bedeutung |
|---|---|---|
events |
Liste von WebhookEventResponse? | Die Ereignisse, aufsteigend nach Entstehung. |
nextCursor |
Text? | Zeiger für den nächsten Aufruf (after); immer gesetzt, auch ohne neue Ereignisse. |
hasMore |
Ja/Nein | true: weitere Ereignisse liegen sofort bereit. |
Enthaltene Datenobjekte: WebhookEventResponse.
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 400 | INVALID_CURSOR |
Der Zeiger after ist ungültig; den Wert nextCursor der letzten Antwort verwenden. |
Der Zeiger ist ein undurchsichtiger Text (c1.3.2026111017): nur weitergeben, nicht auswerten. Den zuletzt erhaltenen nextCursor speichern und beim nächsten Aufruf als after senden.
Beispiel
curl -sS "$API/events?after=$ZEIGER&limit=100" -H "X-Dikas-Api-Key: $PARTNER_SCHLUESSEL" | jq '.data'
Gekürzt auf zwei Ereignisse.
{
"events": [
{
"id": "olord_4c1c808725b8.1",
"type": "order.created",
"occurredAt": "2026-11-10T17:45:30Z",
"tenant": "pizzeria",
"seq": 1,
"apiVersion": "2026-11-01",
"data": {
"orderId": "olord_4c1c808725b8",
"orderNumber": "ON-20261110-006",
"orderType": 0
}
},
{
"id": "olord_4c1c808725b8.2",
"type": "order.status_changed",
"occurredAt": "2026-11-10T17:45:30Z",
"tenant": "pizzeria",
"seq": 2,
"apiVersion": "2026-11-01",
"data": {
"orderId": "olord_4c1c808725b8",
"orderNumber": "ON-20261110-006",
"status": 4,
"previousStatus": 1,
"isPaid": false
}
}
],
"nextCursor": "c1.3.2026111017",
"hasMore": false
}
Webhook-Ziele¶
Ein Administrator des Betriebs legt fest, an welche https-Adressen die Kasse Ereignisse sendet (höchstens drei Ziele je Betrieb). Die Zustellung ist signiert und wird bei Fehlern über Stunden wiederholt. Signatur, Ereignisarten und Testvektor stehen im Leitfaden Eigenen Webshop anbinden. Das Geheimnis eines Ziels (whsec_…) steht nur in der Antwort von Anlegen und Erneuern.
Webhook-Ziele lesen¶
GET /api/v1/webhook-targets
Liefert alle Ziele des Betriebs, ohne Geheimnis.
Anmeldung: Benutzer-Anmeldung (Bearer) eines Administrators. Ein Partner-Schlüssel erreicht diesen Aufruf nie; ein Benutzer ohne Administratorrolle erhält 403.
Antwort 200
data: Liste von WebhookTargetResponse
Beispiel
curl -sS "$API/webhook-targets" -H "Authorization: Bearer $ADMIN_TOKEN" | jq -c '.data[] | {id, name, url, enabled}'
{"id": "whz_0123456789abcdef", "name": "Webshop", "url": "https://shop.example.de/dikas/ereignisse", "enabled": true}
Webhook-Ziel anlegen¶
POST /api/v1/webhook-targets
Legt ein Ziel an. Die Antwort enthält das Geheimnis zur Signaturprüfung genau dieses eine Mal.
Anmeldung: Benutzer-Anmeldung (Bearer) eines Administrators. Ein Partner-Schlüssel erreicht diesen Aufruf nie; ein Benutzer ohne Administratorrolle erhält 403.
Anfrage (application/json)
| Feld | Typ | Pflicht | Bedeutung |
|---|---|---|---|
name |
Text | ja | Bezeichnung, höchstens 120 Zeichen. |
url |
Text | ja | https-Adresse, Port 443, öffentlich erreichbar, ohne Zugangsdaten in der Adresse. |
eventTypes |
Liste von Text | nein | Gewünschte Ereignisarten (order.created, order.status_changed, payment.received, order.cancelled, ticket.ready); ohne Angabe alle. |
Antwort 201
data: WebhookTargetCreatedResponse
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 400 | WEBHOOK_TARGET_REJECTED |
Die Adresse wird abgelehnt: nicht https, nicht Port 443, nicht öffentlich auflösbar, interne oder private Adresse, oder Zugangsdaten in der Adresse. errorMessage nennt den Grund. |
| 400 | WEBHOOK_TARGET_LIMIT |
Es gibt schon drei Ziele. |
| 400 | INVALID_NAME |
Name fehlt oder ist zu lang. |
| 400 | INVALID_EVENT_TYPE |
Eine Ereignisart ist unbekannt. |
Geheimnis sofort speichern
Das Geheimnis lässt sich nicht erneut abrufen. Ist es verloren, hilft nur Geheimnis erneuern.
Beispiel
curl -sS -X POST "$API/webhook-targets" -H "Authorization: Bearer $ADMIN_TOKEN" -H 'Content-Type: application/json' \
-d '{"name":"Webshop","url":"https://shop.example.de/dikas/ereignisse"}' | jq '.data | {id, secret, eventTypes, enabled}'
Die Antwort hat den Status 201. Leere eventTypes heißt: alle Ereignisarten. (Das Geheimnis hier ist ein Platzhalter.)
{
"id": "whz_0123456789abcdef",
"secret": "whsec_Zm9vYmFyLWJlaXNwaWVsLW5pY2h0LWVjaHQtMDAwMQ",
"eventTypes": [],
"enabled": true
}
Webhook-Ziel ändern¶
PATCH /api/v1/webhook-targets/{id}
Ändert Name, Adresse, Ereignisarten oder den Schalter. Fehlende Felder bleiben unverändert. Eine neue Adresse wird wie beim Anlegen geprüft.
Anmeldung: Benutzer-Anmeldung (Bearer) eines Administrators. Ein Partner-Schlüssel erreicht diesen Aufruf nie; ein Benutzer ohne Administratorrolle erhält 403.
Parameter
| Name | Ort | Typ | Pflicht | Bedeutung |
|---|---|---|---|---|
id |
Pfad | Text | ja | Kennung des Objekts, wie sie die Kasse in früheren Antworten genannt hat (olord_…, art_…, whz_…, pak_…). |
Anfrage (application/json)
| Feld | Typ | Pflicht | Bedeutung |
|---|---|---|---|
name |
Text | nein | Neue Bezeichnung. |
url |
Text | nein | Neue Adresse; wird wie beim Anlegen geprüft. |
eventTypes |
Liste von Text | nein | Neue Ereignisarten. |
enabled |
Ja/Nein | nein | Ziel ein- oder ausschalten. |
Antwort 200
data: WebhookTargetResponse
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 400 | WEBHOOK_TARGET_REJECTED |
Die Adresse wird abgelehnt: nicht https, nicht Port 443, nicht öffentlich auflösbar, interne oder private Adresse, oder Zugangsdaten in der Adresse. errorMessage nennt den Grund. |
| 404 | ENTITY_NOT_FOUND |
Ziel unbekannt. |
| 400 | INVALID_EVENT_TYPE |
Eine Ereignisart ist unbekannt. |
Beispiel
curl -sS -X PATCH "$API/webhook-targets/$ZIEL" -H "Authorization: Bearer $ADMIN_TOKEN" -H 'Content-Type: application/json' \
-d '{"eventTypes":["order.status_changed"],"enabled":true}' | jq -c '.data | {id, eventTypes, enabled}'
Webhook-Geheimnis erneuern¶
POST /api/v1/webhook-targets/{id}/rotate-secret
Erzeugt ein neues Geheimnis (steht in der Antwort). Das alte gilt für die Übergangsfrist daneben weiter; in dieser Zeit stehen beide Signaturen im Kopf der Zustellung.
Anmeldung: Benutzer-Anmeldung (Bearer) eines Administrators. Ein Partner-Schlüssel erreicht diesen Aufruf nie; ein Benutzer ohne Administratorrolle erhält 403.
Parameter
| Name | Ort | Typ | Pflicht | Bedeutung |
|---|---|---|---|---|
id |
Pfad | Text | ja | Kennung des Objekts, wie sie die Kasse in früheren Antworten genannt hat (olord_…, art_…, whz_…, pak_…). |
Anfrage (application/json)
| Feld | Typ | Pflicht | Bedeutung |
|---|---|---|---|
graceDays |
Ganzzahl | nein | Wie viele Tage das alte Geheimnis daneben gilt, 1 bis 30; ohne Angabe 7. |
Antwort 200
data: WebhookTargetCreatedResponse
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 404 | ENTITY_NOT_FOUND |
Ziel unbekannt. |
| 400 | INVALID_GRACE |
graceDays liegt nicht zwischen 1 und 30. |
Beispiel
curl -sS -X POST "$API/webhook-targets/$ZIEL/rotate-secret" -H "Authorization: Bearer $ADMIN_TOKEN" \
-H 'Content-Type: application/json' -d '{"graceDays":7}' | jq '.data | {id, secret, previousSecretValidUntil}'
Das Geheimnis hier ist ein Platzhalter.
{
"id": "whz_0123456789abcdef",
"secret": "whsec_Zm9vYmFyLWJlaXNwaWVsLW5pY2h0LWVjaHQtMDAwMQ",
"previousSecretValidUntil": "2026-11-17T17:45:01.9995529Z"
}
Webhook-Ziel löschen¶
DELETE /api/v1/webhook-targets/{id}
Löscht ein Ziel. Noch offene Zustellungen werden als tot sichtbar; die Ereignisse bleiben im Feed.
Anmeldung: Benutzer-Anmeldung (Bearer) eines Administrators. Ein Partner-Schlüssel erreicht diesen Aufruf nie; ein Benutzer ohne Administratorrolle erhält 403.
Parameter
| Name | Ort | Typ | Pflicht | Bedeutung |
|---|---|---|---|---|
id |
Pfad | Text | ja | Kennung des Objekts, wie sie die Kasse in früheren Antworten genannt hat (olord_…, art_…, whz_…, pak_…). |
Antwort 204
Ohne Inhalt.
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 404 | ENTITY_NOT_FOUND |
Ziel unbekannt (auch bei einem zweiten Aufruf). |
Beispiel
curl -sS -X DELETE "$API/webhook-targets/$ZIEL" -H "Authorization: Bearer $ADMIN_TOKEN" -w '%{http_code}\n'
Ausgabe: 204, ohne Inhalt.
Zustellungen lesen¶
GET /api/v1/webhook-targets/deliveries
Zeigt die Zustellungen der Ereignisse an die Ziele: wann zuletzt versucht, mit welchem Fehler. Ohne status die offenen und die toten. Ein Fehlertext enthält nie den Rumpf der Gegenseite.
Anmeldung: Benutzer-Anmeldung (Bearer) eines Administrators. Ein Partner-Schlüssel erreicht diesen Aufruf nie; ein Benutzer ohne Administratorrolle erhält 403.
Parameter
| Name | Ort | Typ | Pflicht | Bedeutung |
|---|---|---|---|---|
status |
Abfrage | Text | nein | Offen, Erledigt oder Tot. |
limit |
Abfrage | Ganzzahl | nein | Höchstens 500; Vorgabe 100. |
Antwort 200
data: Liste von WebhookDeliveryResponse
| Feld | Typ | Bedeutung |
|---|---|---|
id |
Text | Kennung der Zustellung. |
eventId |
Text | Kennung des Ereignisses. |
targetId |
Text | Kennung des Ziels. |
status |
Text | Offen, Erledigt oder Tot. |
attempts |
Ganzzahl | Bisherige Versuche. |
nextAttemptAt |
Zeitpunkt | Nächster Versuch. |
lastError |
Text? | Fehlercode des letzten Versuchs (HTTP_500, TIMEOUT, TLS); nie ein Rumpf. |
lastHttpStatus |
Ganzzahl? | HTTP-Status der letzten Antwort des Empfängers. |
deliveredAt |
Zeitpunkt? | Zugestellt am. |
createdDate |
Zeitpunkt | Angelegt am. |
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 400 | INVALID_STATUS |
status ist nicht Offen, Erledigt oder Tot. |
Beispiel
curl -sS "$API/webhook-targets/deliveries?status=Tot" -H "Authorization: Bearer $ADMIN_TOKEN" | jq -c '.data[] | {eventId, status, attempts, lastError}'
Tote Zustellungen wiederholen¶
POST /api/v1/webhook-targets/deliveries/retry
Sendet tote Zustellungen erneut, mit derselben Ereignis-Kennung. Ohne ids alle toten. Die Antwort nennt die Zahl der zurückgesetzten Zustellungen.
Anmeldung: Benutzer-Anmeldung (Bearer) eines Administrators. Ein Partner-Schlüssel erreicht diesen Aufruf nie; ein Benutzer ohne Administratorrolle erhält 403.
Anfrage (application/json)
| Feld | Typ | Pflicht | Bedeutung |
|---|---|---|---|
ids |
Liste von Text | nein | Kennungen der Zustellungen; ohne Angabe alle toten. |
Antwort 200
data: Ganzzahl
Beispiel
curl -sS -X POST "$API/webhook-targets/deliveries/retry" -H "Authorization: Bearer $ADMIN_TOKEN" -H 'Content-Type: application/json' -d '{}' | jq .data
Ohne tote Zustellungen: 0.
Partner-Schlüssel¶
Ein Partner-Schlüssel ist der Server-zu-Server-Zugang eines Shops. Er gehört zu einem Betrieb und zu einem technischen Benutzer (aktiv, weder Administrator noch Manager), dessen Rechte zusätzlich gelten. Er wird in der Kopfzeile X-Dikas-Api-Key gesendet (dk1_<Kennung>.<Geheimnis>), nicht als Authorization: Bearer, und gilt nur an Aufrufen, die einen seiner Bereiche nennen. Schlüssel, Benutzer und Einstellungen erreicht er nie. Die Verwaltung ist Administratoren vorbehalten und geht auch in Einstellungen → System → Partner-Schlüssel.
Bereiche lesen¶
GET /api/v1/partner-api-keys/scopes
Die zulässigen Bereiche und der Name der Kopfzeile.
Anmeldung: Benutzer-Anmeldung (Bearer) eines Administrators. Ein Partner-Schlüssel erreicht diesen Aufruf nie; ein Benutzer ohne Administratorrolle erhält 403.
Antwort 200
data: PartnerApiScopesResponse
| Feld | Typ | Bedeutung |
|---|---|---|
scopes |
Liste von Text | Alle Bereiche. |
header |
Text | Name der Kopfzeile, in der der Schlüssel gesendet wird. |
Beispiel
Bedeutung der Bereiche: orders:read Bestellungen lesen (pending, today), orders:manage annehmen, ablehnen und Status setzen, tables:read Tische lesen, events:read den Ereignis-Feed lesen.
{"scopes": ["orders:read", "orders:manage", "tables:read", "events:read"], "header": "X-Dikas-Api-Key"}
Partner-Schlüssel lesen¶
GET /api/v1/partner-api-keys
Alle Schlüssel des Betriebs, ohne Geheimnis. status ist active, expired oder revoked.
Anmeldung: Benutzer-Anmeldung (Bearer) eines Administrators. Ein Partner-Schlüssel erreicht diesen Aufruf nie; ein Benutzer ohne Administratorrolle erhält 403.
Antwort 200
data: Liste von PartnerApiKeyResponse
Beispiel
curl -sS "$API/partner-api-keys" -H "Authorization: Bearer $ADMIN_TOKEN" | jq -c '.data[] | {id, keyId, name, scopes, status}'
{"id": "pak_0123456789abcdef", "keyId": "0123456789abcdef", "name": "Webshop", "scopes": ["orders:read", "orders:manage", "events:read"], "status": "active"}
Partner-Schlüssel anlegen¶
POST /api/v1/partner-api-keys
Legt einen Schlüssel an. Die Antwort enthält den vollständigen Schlüssel (key) genau dieses eine Mal. Der Schlüssel läuft nach expiresInDays ab (Vorgabe 365, höchstens 400); höchstens 50 gültige Schlüssel je Betrieb.
Anmeldung: Benutzer-Anmeldung (Bearer) eines Administrators. Ein Partner-Schlüssel erreicht diesen Aufruf nie; ein Benutzer ohne Administratorrolle erhält 403.
Anfrage (application/json)
| Feld | Typ | Pflicht | Bedeutung |
|---|---|---|---|
name |
Text | ja | Bezeichnung, höchstens 120 Zeichen, zum Beispiel der Name des Shops. |
scopes |
Liste von Text | ja | Erlaubte Bereiche, mindestens einer (orders:read, orders:manage, tables:read, events:read). |
apiUserId |
Text | ja | Kennung des technischen Benutzers, dessen Kassenrechte zusätzlich gelten. Kein Administrator, kein Manager. |
expiresInDays |
Ganzzahl | nein | Gültigkeit in Tagen, 1 bis 400; ohne Angabe 365. |
Antwort 201
data: PartnerApiKeyCreatedResponse
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 400 | API_USER_INVALID |
Der technische Benutzer existiert nicht oder ist gesperrt. |
| 400 | API_USER_PRIVILEGED |
Der technische Benutzer ist Administrator oder Manager. |
| 400 | PARTNER_KEY_LIMIT |
Es gibt schon 50 gültige Schlüssel. |
| 400 | VALIDATION_ERROR |
Name, Bereich oder Gültigkeit fehlen oder sind ungültig. |
| 403 | FORBIDDEN |
Kein Administrator. |
Schlüssel sofort speichern
Der Schlüssel wird nicht gespeichert und nie wieder angezeigt. Ist er verloren, hilft nur Erneuern oder ein neuer Schlüssel.
Beispiel
curl -sS -X POST "$API/partner-api-keys" -H "Authorization: Bearer $ADMIN_TOKEN" -H 'Content-Type: application/json' \
-d "{\"name\":\"Webshop\",\"scopes\":[\"orders:read\",\"orders:manage\",\"events:read\"],\"apiUserId\":\"$BENUTZER\",\"expiresInDays\":365}" \
| jq '.data | {id, key, scopes, expiresAt, status}'
Die Antwort hat den Status 201. Der Schlüssel hier ist ein Platzhalter.
{
"id": "pak_0123456789abcdef",
"key": "dk1_0123456789abcdef.Zm9vYmFyLWJlaXNwaWVsLXNjaGx1ZXNzZWwtMDAwMQ",
"scopes": [
"orders:read",
"orders:manage",
"events:read"
],
"expiresAt": "2027-11-10T17:45:29.775954Z",
"status": "active"
}
Partner-Schlüssel erneuern¶
POST /api/v1/partner-api-keys/{id}/rotate
Erneuert den Schlüssel: gleiche Kennung, neues Geheimnis (steht in der Antwort). Das alte gilt noch 24 Stunden (previousValidUntil), damit der Shop ohne Unterbrechung umstellen kann.
Anmeldung: Benutzer-Anmeldung (Bearer) eines Administrators. Ein Partner-Schlüssel erreicht diesen Aufruf nie; ein Benutzer ohne Administratorrolle erhält 403.
Parameter
| Name | Ort | Typ | Pflicht | Bedeutung |
|---|---|---|---|---|
id |
Pfad | Text | ja | Kennung des Objekts, wie sie die Kasse in früheren Antworten genannt hat (olord_…, art_…, whz_…, pak_…). |
Anfrage (application/json)
| Feld | Typ | Pflicht | Bedeutung |
|---|---|---|---|
expiresInDays |
Ganzzahl | nein | Neue Gültigkeit in Tagen, 1 bis 400; ohne Angabe 365. |
Antwort 200
data: PartnerApiKeyCreatedResponse
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 404 | ENTITY_NOT_FOUND |
Schlüssel unbekannt. |
| 400 | PARTNER_KEY_REVOKED |
Ein widerrufener Schlüssel lässt sich nicht erneuern. |
Beispiel
curl -sS -X POST "$API/partner-api-keys/$SCHLUESSEL_ID/rotate" -H "Authorization: Bearer $ADMIN_TOKEN" \
-H 'Content-Type: application/json' -d '{"expiresInDays":365}' | jq '.data | {id, key, previousValidUntil}'
Der Schlüssel hier ist ein Platzhalter.
{
"id": "pak_0123456789abcdef",
"key": "dk1_0123456789abcdef.Zm9vYmFyLWJlaXNwaWVsLXNjaGx1ZXNzZWwtMDAwMQ",
"previousValidUntil": "2026-11-11T17:45:34.1449777Z"
}
Partner-Schlüssel widerrufen¶
DELETE /api/v1/partner-api-keys/{id}
Widerruft den Schlüssel. Das wirkt mit der nächsten Anfrage; auch ein noch gültiges altes Geheimnis ist danach ungültig.
Anmeldung: Benutzer-Anmeldung (Bearer) eines Administrators. Ein Partner-Schlüssel erreicht diesen Aufruf nie; ein Benutzer ohne Administratorrolle erhält 403.
Parameter
| Name | Ort | Typ | Pflicht | Bedeutung |
|---|---|---|---|---|
id |
Pfad | Text | ja | Kennung des Objekts, wie sie die Kasse in früheren Antworten genannt hat (olord_…, art_…, whz_…, pak_…). |
Antwort 200
data: PartnerApiKeyResponse
Fehler
| HTTP | errorCode |
Bedeutung |
|---|---|---|
| 404 | ENTITY_NOT_FOUND |
Schlüssel unbekannt. |
Beispiel
curl -sS -X DELETE "$API/partner-api-keys/$SCHLUESSEL_ID" -H "Authorization: Bearer $ADMIN_TOKEN" | jq -c '.data | {id, status, revokedAt}'
Datenobjekte¶
Die Datenobjekte, auf die die Aufrufe oben verweisen. Felder, die hier nicht stehen, sind für die Anbindung nicht vorgesehen und können sich ändern.
ArticleGroupResponse¶
Eine Warengruppe.
| Feld | Typ | Bedeutung |
|---|---|---|
id |
Text? | Kennung (artgrp_…); sie gehört in groupId am Artikel. |
groupId |
Text? | Gruppennummer: Hauptgruppe 3 Ziffern (100), jede Untergruppe hängt zwei Ziffern an (10001). |
name |
Text? | Name. |
shortName |
Text? | Kurzname. |
description |
Text? | Beschreibung. |
parentId |
Text? | Gruppennummer der übergeordneten Gruppe; leer bei Hauptgruppen. |
color |
Text? | Farbe. |
sortOrder |
Ganzzahl | Sortierwert. |
isActive |
Ja/Nein | Aktiv. |
version |
Text? | Versionsmarke der Kasse. |
ArticleResponse¶
Ein Artikel der Kasse (die für Webshops wichtigen Felder).
| Feld | Typ | Bedeutung |
|---|---|---|
id |
Text? | Kennung (art_…). |
version |
Text? | Versionsmarke der Kasse, ändert sich bei jeder Änderung. |
articleNumber |
Text? | Artikelnummer. |
name |
Text? | Name. |
shortName |
Text? | Kurzname. |
description |
Text? | Beschreibung. |
groupId |
Text? | Kennung der Warengruppe (artgrp_…), nicht die Gruppennummer. |
price |
Dezimalzahl | Verkaufspreis. |
taxClass |
Ganzzahl? | Steuerart: 0 Normalsatz, 1 ermäßigt, 99 steuerfrei. |
taxRate |
Dezimalzahl? | Steuersatz in Prozent; von der Kasse aus taxClass bestimmt und nicht schreibbar. |
unit |
Text? | Einheit (Stück). |
barcode |
Text? | Strichcode. |
isActive |
Ja/Nein | false: weder Kasse noch Shop. |
hideFromMenu |
Ja/Nein | true: nicht im Shop, an der Kasse buchbar. |
manualSoldOut |
Ja/Nein | true: heute nicht verfügbar (der „86er“-Schalter). |
sortOrder |
Ganzzahl | Sortierwert. |
allergens |
Liste von Text? | Allergen-Kürzel. |
pfand |
Dezimalzahl | Pfand je Einheit. |
ArticleWebImage¶
Ein Bild eines Artikels.
| Feld | Typ | Bedeutung |
|---|---|---|
attachmentName |
Text? | Dateiname des Bildes, für Artikelbild laden. |
thumbnailName |
Text? | Dateiname der kleinen Ansicht. |
caption |
Text? | Bildunterschrift. |
sortOrder |
Ganzzahl | Reihenfolge. |
isPrimary |
Ja/Nein | Hauptbild des Artikels. |
JsonPatchOperation¶
Eine Operation nach RFC 6902.
| Feld | Typ | Bedeutung |
|---|---|---|
op |
Text? | replace, add, remove oder test. |
path |
Text? | Pfad des Feldes mit führendem Schrägstrich (/price). |
value |
beliebig | Neuer bzw. erwarteter Wert (beliebiger JSON-Wert); bei remove entfällt er. |
OnlineMenuAllergen¶
Ein Allergen-Kürzel mit Klartext.
| Feld | Typ | Bedeutung |
|---|---|---|
code |
Text? | Kürzel, wie es an den Artikeln steht (A). |
name |
Text? | Bezeichnung (Glutenhaltiges Getreide). |
OnlineMenuGroup¶
Eine Warengruppe der Karte.
| Feld | Typ | Bedeutung |
|---|---|---|
id |
Text? | Kennung der Gruppe (artgrp_…). |
name |
Text? | Name der Gruppe. |
color |
Text? | Farbe der Gruppe (#C683CD), falls gepflegt. |
sortOrder |
Ganzzahl | Sortierwert; kleinere Werte zuerst. |
parentName |
Text? | Name der Hauptgruppe, zu der die Gruppe gehört. |
articles |
Liste von OnlineMenuItem? | Die Artikel der Gruppe. |
OnlineMenuItem¶
Ein Artikel der Karte.
| Feld | Typ | Bedeutung |
|---|---|---|
id |
Text? | Kennung des Artikels (art_…); gehört in items[].articleId beim Bestellen. |
name |
Text? | Name. |
description |
Text? | Kurzbeschreibung. |
price |
Dezimalzahl | Verkaufspreis je Einheit in der Währung des Betriebs, ohne Optionen und ohne Pfand. |
pfand |
Dezimalzahl | Pfand je Einheit, 0 ohne Pfand. Die Kasse fügt es beim Bestellen als eigene Position hinzu; es ist nicht in price enthalten. |
webTitle |
Text? | Abweichender Titel für den Shop, falls gepflegt. |
longDescription |
Text? | Ausführliche Beschreibung. |
ingredients |
Text? | Zutaten (Freitext). |
spicyLevel |
Ganzzahl | Schärfegrad (0 = nicht scharf). |
isVegan |
Ja/Nein | Vegan. |
isVegetarian |
Ja/Nein | Vegetarisch. |
isGlutenFree |
Ja/Nein | Glutenfrei. |
preparationTimeMinutes |
Ganzzahl? | Zubereitungsdauer in Minuten, falls gepflegt. |
soldOut |
Ja/Nein | true: heute nicht verfügbar. Der Artikel steht weiter auf der Karte, wird beim Bestellen aber mit ARTICLE_SOLD_OUT abgewiesen. |
allergens |
Liste von Text? | Allergen-Kürzel; Klartext in allergenDefinitions. |
additives |
Liste von Text? | Zusatzstoffe (Freitext). |
images |
Liste von ArticleWebImage? | Bilder des Artikels; abrufbar über Artikelbild laden. |
options |
Liste von OnlineMenuOptionGroup? | Wählbare Optionen (Extras, Größen) in Gruppen. |
OnlineMenuOption¶
Eine wählbare Option.
| Feld | Typ | Bedeutung |
|---|---|---|
name |
Text? | Name; er dient beim Bestellen zur Auswahl (selectedOptions[].name). |
price |
Dezimalzahl | Aufpreis. Bei isPercent ein Prozentsatz vom Artikelpreis (10 = 10 %), sonst ein Geldbetrag. |
isPercent |
Ja/Nein | true: price ist ein Prozentsatz. |
isDefault |
Ja/Nein | Vorgewählt. |
appMode |
Ganzzahl | 0 normal, 1 Standard (vorgewählt), 2 im Preis enthalten (kein Aufschlag). |
soldOut |
Ja/Nein | true: die Option ist heute nicht verfügbar. |
OnlineMenuOptionGroup¶
Eine Gruppe wählbarer Optionen eines Artikels.
| Feld | Typ | Bedeutung |
|---|---|---|
id |
Text? | Kennung der Gruppe. |
caption |
Text? | Überschrift (Extras). |
isNeeded |
Ja/Nein | true: mindestens eine Option muss gewählt werden, sonst REQUIRED_OPTION_MISSING. |
mode |
Ganzzahl | 1: höchstens eine Option der Gruppe (Einzelwahl), sonst Mehrfachwahl. |
freeCount |
Ganzzahl | Anzahl der Optionen der Gruppe, die ohne Aufpreis enthalten sind (die günstigsten zuerst). |
deductOnDeselect |
Ja/Nein | true: eine vorgewählte Option lässt sich abwählen (ohne …) und mindert dann den Preis. |
options |
Liste von OnlineMenuOption? | Die Optionen. |
OnlineOrderItem¶
Eine Position einer Bestellung, wie die Kasse sie berechnet hat.
| Feld | Typ | Bedeutung |
|---|---|---|
articleId |
Text? | Kennung des Artikels. |
articleName |
Text? | Name zum Zeitpunkt der Bestellung. |
quantity |
Ganzzahl | Menge. |
unitPrice |
Dezimalzahl | Einzelpreis einschließlich der gewählten Optionen. |
totalPrice |
Dezimalzahl | unitPrice mal quantity. |
notes |
Text? | Hinweis zur Position. |
selectedOptions |
Liste von OnlineOrderItemOption? | Die gewählten Optionen mit ihrem Aufpreis. |
isAutoDeposit |
Ja/Nein | true: die Position ist das von der Kasse ergänzte Pfand. |
taxRate |
Dezimalzahl? | Steuersatz in Prozent. |
OnlineOrderItemOption¶
Eine gewählte Option einer Position.
| Feld | Typ | Pflicht | Bedeutung |
|---|---|---|---|
name |
Text | ja | Name der Option genau wie in der Karte (options[].options[].name). |
price |
Dezimalzahl | nein | Aufpreis in Geld. In der Anfrage wird er nicht übernommen: die Kasse bestimmt ihn aus dem Artikel. |
inPrice |
Ja/Nein | nein | true: im Preis enthalten, kein Aufschlag. |
OnlineOrderItemRequest¶
Eine Position der Bestellung.
| Feld | Typ | Pflicht | Bedeutung |
|---|---|---|---|
articleId |
Text | ja | Kennung des Artikels aus der Karte (art_…). |
quantity |
Ganzzahl | ja | Menge, 1 bis 999. |
notes |
Text | nein | Hinweis zur Position (ohne Zwiebeln). |
selectedOptions |
Liste von OnlineOrderItemOption | nein | Gewählte Optionen. Pflichtgruppen der Karte (isNeeded) müssen vertreten sein. |
OnlineOrderResponse¶
Eine Online-Bestellung mit Positionen, Summen und Stand.
| Feld | Typ | Bedeutung |
|---|---|---|
id |
Text? | Kennung der Bestellung (olord_…). |
orderNumber |
Text? | Bestellnummer zum Anzeigen (ON-20261110-001). |
status |
Ganzzahl | Stand: 1 eingegangen, 2 Zahlung läuft, 3 bezahlt, 4 angenommen, 5 in Zubereitung, 6 bereit, 7 unterwegs, 8 abgeschlossen, 9 storniert, 10 abgelehnt. |
orderType |
Ganzzahl | 0 Abholung, 1 Lieferung. |
createdDate |
Zeitpunkt | Angelegt (UTC). |
changedDate |
Zeitpunkt | Zuletzt geändert (UTC). |
customerName |
Text? | Name des Gastes. |
customerEmail |
Text? | E-Mail des Gastes. |
customerPhone |
Text? | Telefon des Gastes. |
street |
Text? | Lieferadresse: Straße. |
houseNumber |
Text? | Lieferadresse: Hausnummer. |
zipCode |
Text? | Lieferadresse: Postleitzahl. |
city |
Text? | Lieferadresse: Ort. |
deliveryNotes |
Text? | Hinweis für den Fahrer. |
items |
Liste von OnlineOrderItem? | Die Positionen. |
subtotal |
Dezimalzahl | Summe der Positionen. |
deliveryFee |
Dezimalzahl | Liefergebühr. |
tipAmount |
Dezimalzahl | Trinkgeld. |
grandTotal |
Dezimalzahl | Gesamtbetrag. |
requestedTime |
Zeitpunkt? | Wunschzeitpunkt des Gastes. |
estimatedReadyTime |
Zeitpunkt? | Voraussichtlich fertig. |
confirmedAt |
Zeitpunkt? | Angenommen am. |
completedAt |
Zeitpunkt? | Abgeschlossen am. |
paymentMethod |
Text? | Zahlart (cash, stripe, paypal). |
isPaid |
Ja/Nein | true: bezahlt. |
paidAt |
Zeitpunkt? | Bezahlt am. |
amountDue |
Dezimalzahl | Noch zu zahlender Betrag. |
kitchenNotes |
Text? | Hinweis für die Küche. |
rejectionReason |
Text? | Grund bei Ablehnung oder Stornierung. |
guestSecret |
Text? | Bestell-Geheimnis. Nur in der Antwort von create gesetzt, danach nie wieder; sofort speichern. |
{
"id": "olord_648e7d3cfa87",
"orderNumber": "ON-20261110-001",
"status": 1,
"orderType": 0,
"createdDate": "2026-11-10T17:44:05.1968974Z",
"changedDate": "2026-11-10T17:44:05.2818688Z",
"customerName": "Erika Muster",
"customerEmail": "erika@example.com",
"customerPhone": "0123 456789",
"street": null,
"houseNumber": null,
"zipCode": null,
"city": null,
"deliveryNotes": null,
"items": [
{
"articleId": "art_917c19d4a18a",
"articleName": "Pizza Margherita",
"quantity": 1,
"unitPrice": 9.5,
"totalPrice": 9.5,
"notes": "ohne Zwiebeln",
"selectedOptions": [],
"isAutoDeposit": false,
"taxRate": 7
}
],
"subtotal": 9.5,
"deliveryFee": 0,
"tipAmount": 0,
"grandTotal": 9.5,
"requestedTime": null,
"estimatedReadyTime": null,
"confirmedAt": null,
"completedAt": null,
"paymentMethod": "cash",
"isPaid": false,
"paidAt": null,
"amountDue": 9.5,
"kitchenNotes": null,
"rejectionReason": null,
"guestSecret": "q7Xm2LkP9vRtY4cNw8ZsB3hJdF6aGeUo"
}
OpeningHoursEntry¶
Öffnungszeit eines Wochentags.
| Feld | Typ | Bedeutung |
|---|---|---|
dayOfWeek |
Ganzzahl | Wochentag, 0 Sonntag bis 6 Samstag. |
isClosed |
Ja/Nein | true: an diesem Tag geschlossen. |
openTime |
Text? | Öffnet (11:00). |
closeTime |
Text? | Schließt (22:00). |
breakStart |
Text? | Beginn der Pause, falls vorhanden. |
breakEnd |
Text? | Ende der Pause. |
PartnerApiKeyCreatedResponse¶
Ein Partner-Schlüssel mit dem Geheimnis; nur in den Antworten von Anlegen und Erneuern.
| Feld | Typ | Bedeutung |
|---|---|---|
id |
Text | Kennung (pak_…). |
keyId |
Text | Öffentlicher Teil des Schlüssels (nach dk1_). |
name |
Text | Bezeichnung. |
scopes |
Liste von Text | Die erlaubten Bereiche. |
apiUserId |
Text | Der technische Benutzer. |
createdDate |
Zeitpunkt | Angelegt am. |
expiresAt |
Zeitpunkt | Läuft ab am. |
revokedAt |
Zeitpunkt? | Widerrufen am. |
lastUsedAt |
Zeitpunkt? | Zuletzt benutzt am. |
previousValidUntil |
Zeitpunkt? | Nach einer Erneuerung: bis wann das alte Geheimnis noch gilt. |
status |
Text | active, expired oder revoked. |
key |
Text | Der vollständige Schlüssel (dk1_<Kennung>.<Geheimnis>). Wird nicht gespeichert und nie wieder angezeigt. |
PartnerApiKeyResponse¶
Ein Partner-Schlüssel, ohne Geheimnis.
| Feld | Typ | Bedeutung |
|---|---|---|
id |
Text | Kennung (pak_…). |
keyId |
Text | Öffentlicher Teil des Schlüssels (nach dk1_). |
name |
Text | Bezeichnung. |
scopes |
Liste von Text | Die erlaubten Bereiche. |
apiUserId |
Text | Der technische Benutzer. |
createdDate |
Zeitpunkt | Angelegt am. |
expiresAt |
Zeitpunkt | Läuft ab am. |
revokedAt |
Zeitpunkt? | Widerrufen am. |
lastUsedAt |
Zeitpunkt? | Zuletzt benutzt am. |
previousValidUntil |
Zeitpunkt? | Nach einer Erneuerung: bis wann das alte Geheimnis noch gilt. |
status |
Text | active, expired oder revoked. |
WebhookEventResponse¶
Ein Ereignis, wie es der Feed ausliefert und wie es an ein Webhook-Ziel gesendet wird.
| Feld | Typ | Bedeutung |
|---|---|---|
id |
Text? | Eindeutige Kennung (<Bestellung>.<seq>); Empfänger entdoppeln darüber. |
type |
Text? | order.created, order.status_changed, payment.received, order.cancelled oder ticket.ready. |
occurredAt |
Text? | Zeitpunkt (UTC). |
tenant |
Text? | Kennung des Betriebs. |
seq |
Ganzzahl | Laufende Nummer je Bestellung (aufsteigend, lückenlos); darüber ordnen Empfänger und erkennen Lücken. |
apiVersion |
Text? | Version der Nutzlasten. |
data |
beliebig | Die Nutzlast je type, ohne personenbezogene Angaben; Einzelheiten holt der Empfänger mit seinem Schlüssel. Beispiele: order.created: orderId, orderNumber, orderType; order.status_changed: orderId, orderNumber, status, previousStatus, isPaid. |
WebhookTargetCreatedResponse¶
Ein Webhook-Ziel mit dem Geheimnis; nur in den Antworten von Anlegen und Erneuern.
| Feld | Typ | Bedeutung |
|---|---|---|
id |
Text | Kennung (whz_…). |
name |
Text | Bezeichnung. |
url |
Text | https-Adresse des Empfängers. |
eventTypes |
Liste von Text | Gewünschte Ereignisarten; leer heißt alle. |
enabled |
Ja/Nein | false: das Ziel bekommt nichts; die Ereignisse bleiben im Feed. |
disabledReason |
Text? | GONE (der Empfänger antwortete 410) oder MANUAL; sonst leer. |
disabledAt |
Zeitpunkt? | Wann das Ziel abgeschaltet wurde. |
pausedUntil |
Zeitpunkt? | Wegen vieler Fehler in Folge pausiert bis. |
previousSecretValidUntil |
Zeitpunkt? | Ende der Übergangsfrist des alten Geheimnisses nach einer Erneuerung. |
operatorException |
Ja/Nein | Der Betreiber hat für dieses Ziel ein privates Netz oder einen anderen Port freigegeben. |
createdDate |
Zeitpunkt | Angelegt am (UTC). |
secret |
Text | Das Geheimnis (whsec_…) zur Prüfung der Signatur. Wird nur in dieser Antwort ausgegeben. |
WebhookTargetResponse¶
Ein Webhook-Ziel, ohne Geheimnis.
| Feld | Typ | Bedeutung |
|---|---|---|
id |
Text | Kennung (whz_…). |
name |
Text | Bezeichnung. |
url |
Text | https-Adresse des Empfängers. |
eventTypes |
Liste von Text | Gewünschte Ereignisarten; leer heißt alle. |
enabled |
Ja/Nein | false: das Ziel bekommt nichts; die Ereignisse bleiben im Feed. |
disabledReason |
Text? | GONE (der Empfänger antwortete 410) oder MANUAL; sonst leer. |
disabledAt |
Zeitpunkt? | Wann das Ziel abgeschaltet wurde. |
pausedUntil |
Zeitpunkt? | Wegen vieler Fehler in Folge pausiert bis. |
previousSecretValidUntil |
Zeitpunkt? | Ende der Übergangsfrist des alten Geheimnisses nach einer Erneuerung. |
operatorException |
Ja/Nein | Der Betreiber hat für dieses Ziel ein privates Netz oder einen anderen Port freigegeben. |
createdDate |
Zeitpunkt | Angelegt am (UTC). |
Weiter¶
-
Eigenen Webshop anbinden: der Ablauf Schritt für Schritt, mit Webhook-Signatur und Testvektor