Eigenen Webshop an DiKAS anbinden¶
Diese Seite richtet sich an Webagenturen und Entwickler, die für einen Betrieb einen eigenen Webshop (zum Beispiel mit Node.js und React) mit der DiKAS-Kasse verbinden. Sie zeigt die einzelnen Möglichkeiten, von der Speisekarte über die Bestellung bis zum Artikel-Update, und welche Sie wofür wählen.
Alle Aufrufe gehen an die Kasse des Betriebs (https://<betrieb>.<ihre-domain>) und verwenden ausschließlich die aktuelle Schnittstelle unter /api/v1/…. Die ältere Schnittstelle unter /rest/… ist für neue Anbindungen nicht vorgesehen.
Nachschlagen
Alle Aufrufe mit Anmeldung, Feldern, Fehlercodes und Beispielen stehen in der API-Referenz zur Webshop-Anbindung; sie gibt es auch als OpenAPI-Datei für Postman oder einen Client-Generator.
Voraussetzungen im Betrieb
- Die Lizenz enthält das Modul Online-Bestellung (für Lieferung zusätzlich Lieferservice).
- Unter Admin → Einstellungen → Betrieb ist Online-Bestellung aktiviert (Einrichtung des Shops: Online-Shop). Sonst antworten die Aufrufe mit
404 SWITCH_DISABLED. - Es gibt mindestens eine Warengruppe mit Artikeln, siehe Artikel anlegen.
Welche Möglichkeit passt?¶
| Ich möchte … | Möglichkeit | Anmeldung |
|---|---|---|
| keinen eigenen Code schreiben | Der Online-Shop von DiKAS | keine |
| die Speisekarte aus DiKAS in meinem Shop anzeigen | Karte lesen | keine, öffentlich |
| die Karte in meinem Shop pflegen und nach DiKAS übertragen | Artikel schreiben | Benutzer-Anmeldung |
| Bestellungen aus meinem Shop an die Kasse übergeben | Bestellung übergeben | keine; Bestell-Geheimnis je Bestellung |
| dem Gast „angenommen“, „fertig“ anzeigen | Status zurückmelden | Bestell-Geheimnis oder Partner-Schlüssel |
| Online bezahlen lassen | Bezahlen | je Zahlart |
Der Ablauf einer Bestellung, die aus einem eigenen Shop kommt:
- Der Shop zeigt die Karte (aus DiKAS gelesen oder vom Shop geführt).
- Der Gast bestellt im Shop; der Shop übergibt die Bestellung an die Kasse.
- Die Kasse legt einen Auftrag im Lieferservice an und druckt ihn bzw. zeigt ihn auf dem Küchenmonitor. Der Betrieb nimmt an oder lehnt ab (oder die Kasse nimmt automatisch an).
- Der Shop erfährt den Stand: durch Abfragen, über einen Webhook oder über den Ereignis-Feed.
Zugänge im Überblick¶
| Zugang | Wofür | Wo ausgestellt |
|---|---|---|
| ohne Anmeldung | Karte lesen, Bestellung abgeben, Status einer Bestellung mit Bestell-Geheimnis | – |
Partner-Schlüssel (X-Dikas-Api-Key: dk1_…) |
Server-zu-Server: offene und heutige Bestellungen lesen (orders:read), annehmen/ablehnen/Status setzen (orders:manage), Tische lesen (tables:read), Ereignis-Feed lesen (events:read) |
Einstellungen → System → Partner-Schlüssel (Administrator) |
| Benutzer-Anmeldung (Bearer) | Artikel und Gruppen pflegen, alles, was ein Kassenbenutzer darf | POST /api/v1/auth/login, Benutzer mit nur den nötigen Rechten |
Ein Partner-Schlüssel gehört zu einem Betrieb und zu einem technischen Benutzer (aktiv, weder Administrator noch Manager). Er hat ein Ablaufdatum (Standard 365 Tage, höchstens 400), lässt sich erneuern (das alte Geheimnis gilt noch 24 Stunden) und sofort widerrufen. Er wird einmal angezeigt, speichern Sie ihn sofort. Gesendet wird er in der Kopfzeile X-Dikas-Api-Key, nicht als Authorization: Bearer. Alles, was nicht zu seinen Bereichen gehört, lehnt die Kasse ab, auch Schlüssel, Benutzer und Einstellungen.
So kommen Sie an den Zugang¶
Die Beispiele verwenden curl und jq; API ist die Adresse der Kasse mit /api/v1. Jede Antwort der Kasse hat dieselbe Hülle: success, data, errorCode, errorMessage.
1. Benutzer-Anmeldung (Bearer-Token). Anmelden mit Benutzername und Passwort:
API=https://mein-betrieb.example.de/api/v1
curl -sS -X POST "$API/auth/login" -H 'Content-Type: application/json' \
-d "{\"username\":\"$BENUTZER\",\"password\":\"$PASSWORT\"}"
Die Antwort enthält den Token im Feld data.accessToken:
{
"success": true,
"data": {
"success": true,
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…",
"refreshToken": "xV3k…",
"expiresAt": "2026-11-10T23:08:00Z",
"requiresTotp": false
},
"errorCode": null,
"errorMessage": null
}
Den Token nehmen Sie mit jq heraus und senden ihn bei jedem weiteren Aufruf im Kopf Authorization: Bearer …:
TOKEN=$(curl -sS -X POST "$API/auth/login" -H 'Content-Type: application/json' \
-d "{\"username\":\"$BENUTZER\",\"password\":\"$PASSWORT\"}" | jq -r .data.accessToken)
curl -sS "$API/articles" -H "Authorization: Bearer $TOKEN"
Der Token läuft zum Zeitpunkt expiresAt ab; mit dem refreshToken holen Sie einen neuen, siehe REST API. Ist requiresTotp wahr, hat der Benutzer die Zwei-Faktor-Anmeldung eingeschaltet. Für einen Server-Zugang legen Sie dafür einen eigenen technischen Benutzer ohne diese Pflicht an.
2. Partner-Schlüssel (Server zu Server). Ein Administrator stellt ihn unter Einstellungen → System → Partner-Schlüssel aus, oder per Schnittstelle (Anmeldung als Administrator mit Token wie oben, apiUserId ist die Kennung des technischen Benutzers aus GET /api/v1/staff):
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":"usr_9bf8f71a2db5","expiresInDays":365}'
{
"success": true,
"data": {
"key": "dk1_bae9d9de99992c14.Q2vP…",
"id": "pak_bae9d9de99992c14",
"keyId": "bae9d9de99992c14",
"name": "Webshop",
"scopes": ["orders:read", "orders:manage", "events:read"],
"apiUserId": "usr_9bf8f71a2db5",
"expiresAt": "2027-11-10T17:48:22Z",
"status": "active"
}
}
Das Feld data.key ist der Partner-Schlüssel. Er steht nur in dieser einen Antwort: Speichern Sie ihn sofort, später ist er nicht mehr abrufbar (nur erneuern). Gesendet wird er in der Kopfzeile X-Dikas-Api-Key, nicht als Bearer:
PARTNER_SCHLUESSEL='dk1_bae9d9de99992c14.Q2vP…'
curl -sS "$API/online-checkout/today" -H "X-Dikas-Api-Key: $PARTNER_SCHLUESSEL" | jq -c '.data[] | {id, orderNumber, status, isPaid}'
Ein falscher, abgelaufener oder widerrufener Schlüssel antwortet mit 401 („Ungültiger Schlüssel“). Der Schlüssel öffnet nur die Bereiche, die Sie ihm gegeben haben.
3. Bestell-Geheimnis. Dritter Zugang ohne Anmeldung: Jede Bestellung bekommt beim Anlegen ein eigenes Geheimnis, siehe Bestellung übergeben.
A. Der Online-Shop von DiKAS¶
Wenn Sie keinen eigenen Shop programmieren müssen: DiKAS bringt einen fertigen Online-Shop mit (Karte, Warenkorb, Abholung und Lieferung, Zahlung, Bestellstatus). Er wird in der Verwaltung eingerichtet, siehe Online-Shop. Für viele Betriebe ist das der schnellste Weg. Die folgenden Möglichkeiten sind für Betriebe, die einen eigenen Shop behalten wollen.
B. Speisekarte und Öffnungsstatus lesen¶
Die Karte ist öffentlich und enthält nur Artikel, die online sichtbar sind (ausgeblendete Gruppen und Artikel fehlen), mit Preisen, Optionen, Allergenen und Bildern. Ein Artikel mit soldOut: true steht auf der Karte, wird aber nicht angenommen.
curl -sS "$API/online-menu/menu" | jq '.data.groups[] | {name, artikel: [.articles[] | {id, name, price, soldOut}]}'
curl -sS "$API/online-menu/status" | jq -c '.data | {isOpen, currentCloseTime}'
curl -sS "$API/online-menu/wait-estimate" | jq -c '.data | {pickupMinutes, deliveryMinutes, load}'
{"name":"Pizza","artikel":[{"id":"art_917c19d4a18a","name":"Pizza Margherita","price":9.5,"soldOut":false}]}
{"isOpen":true,"currentCloseTime":"22:00"}
{"pickupMinutes":15,"deliveryMinutes":60,"load":"low"}
Die Karte darf nie hinter den Preisen der Kasse herlaufen
Beim Bestellen rechnet die Kasse mit ihren Preisen. Zeigt Ihr Shop einen alten Preis, stimmt die Summe im Warenkorb nicht mit der Rechnung überein. Laden Sie die Karte deshalb bei jedem Aufruf der Startseite oder höchstens wenige Minuten zwischengespeichert.
C. Artikel und Preise aus dem Shop pflegen¶
Pflegt der Shop die Karte, übertragen Sie Änderungen per Benutzer-Anmeldung an DiKAS. Legen Sie vorher fest, wer führend ist: Pflegt der Betrieb dieselben Artikel auch in der Kasse, laufen Preise auseinander.
Warengruppen sind hierarchisch nummeriert: eine Hauptgruppe hat 3 Ziffern (100), jede Untergruppe hängt zwei Ziffern an (10001). Artikel erscheinen nur in Untergruppen.
curl -sS -X POST "$API/articles/groups" -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"groupId":"10001","name":"Pizza","sortOrder":1,"isActive":true}'
GRUPPE=$(curl -sS "$API/articles/groups" -H "Authorization: Bearer $TOKEN" \
| jq -r '.data[] | select(.groupId=="10001") | .id') # artgrp_…
curl -sS -X POST "$API/articles" -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' -d "{
\"articleNumber\":\"1001\", \"name\":\"Pizza Margherita\", \"description\":\"Tomate, Mozzarella\",
\"groupId\":\"$GRUPPE\", \"price\":9.5, \"taxRate\":7, \"isActive\":true }" | jq -c '.data | {id, name, price}'
Leere Karte trotz Artikeln?
Das Feld groupId am Artikel muss die Kennung der Gruppe tragen (artgrp_…), nicht die Gruppennummer. Artikel in einer Hauptgruppe erscheinen nie.
Ändern Sie Artikel als JSON Patch (Content-Type: application/json-patch+json), nur die Felder, die sich ändern:
curl -sS -X PATCH "$API/articles/art_917c19d4a18a" -H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json-patch+json' \
-d '[{"op":"replace","path":"/price","value":10.5},{"op":"replace","path":"/manualSoldOut","value":true}]' \
| jq -c '.data | {price, manualSoldOut}'
| Was Sie wollen | Feld | Wirkung im Shop |
|---|---|---|
| Preis ändern | /price |
neuer Preis in der Karte, die Kasse rechnet damit |
| Heute nicht verfügbar | /manualSoldOut = true |
Artikel bleibt als „derzeit aus“ sichtbar, Bestellung wird mit ARTICLE_SOLD_OUT abgewiesen |
| Aus der Karte nehmen, an der Kasse lassen | /hideFromMenu = true |
nicht im Shop, aber an der Kasse buchbar |
| Ganz abschalten | /isActive = false |
weder Shop noch Kasse |
| Name, Beschreibung | /name, /description |
in der Karte |
Senden Sie Änderungen gebündelt und nicht im Sekundentakt. Optionen (Extras, Größen) und Allergene pflegt der Betrieb in der Kasse; der Shop liest sie aus der Karte.
D. Bestellung an die Kasse übergeben¶
POST /api/v1/online-checkout/create braucht keine Anmeldung. Die Antwort enthält das Bestell-Geheimnis (guestSecret), mit dem der Shop später Status lesen, bezahlen oder stornieren darf. Senden Sie bei jeder Bestellung eine Kopfzeile Idempotency-Key mit neuem Wert: Wiederholt der Shop den Aufruf nach einem Netzfehler, bekommt er dieselbe Bestellung zurück statt einer zweiten.
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 '.data | {id, orderNumber, status, grandTotal, isPaid, guestSecret}'
{
"id": "olord_648e7d3cfa87",
"orderNumber": "ON-20261110-001",
"status": 1,
"grandTotal": 9.5,
"isPaid": false,
"guestSecret": "oNaV4kT0pQ7sH2mXz9LwB1cEyD6uRf3J"
}
Das Bestell-Geheimnis (guestSecret) steht nur in dieser Antwort. Speichern Sie es zusammen mit der id bei Ihrer Bestellung. Damit lesen Sie später den Status (Kopfzeile X-Order-Secret); ohne das Geheimnis antwortet die Kasse auf jede Abfrage dieser Bestellung mit 404, genauso wie bei einer unbekannten Bestellung:
curl -sS "$API/online-checkout/olord_648e7d3cfa87" -H "X-Order-Secret: oNaV4kT0pQ7sH2mXz9LwB1cEyD6uRf3J" \
| jq -c '.data | {id, orderNumber, status, isPaid}'
| Feld | Bedeutung |
|---|---|
orderType |
0 Abholung, 1 Lieferung (braucht street, houseNumber, zipCode, city und das Modul Lieferservice) |
items[] |
articleId, quantity, notes, selectedOptions (Name der gewählten Optionen; den Preis bestimmt die Kasse, ein mitgesendeter Preis wird ignoriert) |
paymentMethod |
cash, stripe oder paypal, siehe Bezahlen |
requestedTime, kitchenNotes |
Wunschzeit, Hinweis für die Küche |
externalReference |
Ihre eigene Bestellnummer (höchstens 100 Zeichen), nur mit Benutzer-Anmeldung; dieselbe Nummer mit demselben Inhalt liefert die vorhandene Bestellung zurück |
tipAmount |
Trinkgeld, nur mit Online-Zahlung |
Vorab prüfen Sie online-menu/status und online-menu/wait-estimate und zeigen dem Gast die Wartezeit. Häufige Antworten:
errorCode |
Bedeutung |
|---|---|
SHOP_CLOSED |
außerhalb der Öffnungszeiten |
SHOP_OVERLOADED |
der Betrieb nimmt wegen Küchenlast gerade nicht an |
ARTICLE_SOLD_OUT, ARTICLE_POS_ONLY |
Artikel ist aus bzw. nur an der Kasse verkäuflich |
MIN_ORDER_AMOUNT, DELIVERY_AREA_NOT_COVERED |
Mindestbestellwert nicht erreicht / Adresse außerhalb der Liefergebiete |
PREPAYMENT_REQUIRED |
der Betrieb verlangt Online-Zahlung |
ONLINE_ORDER_DISABLED, ONLINEORDER_MODULE_REQUIRED |
Online-Bestellung ist im Betrieb aus bzw. nicht lizenziert |
E. Den Stand der Bestellung zurückbekommen¶
Ihr Shop soll dem Gast „angenommen“, „in Zubereitung“, „fertig“ anzeigen. Dafür gibt es drei Wege, die Sie kombinieren können.
| Weg | So geht es | Wann sinnvoll |
|---|---|---|
| Abfragen | GET /api/v1/online-checkout/{id} mit Kopfzeile X-Order-Secret (eine Bestellung); GET /api/v1/online-checkout/today mit Partner-Schlüssel (orders:read) für alle heutigen |
Der Gast wartet auf einer Statusseite: alle 10 bis 15 Sekunden abfragen |
| Webhook | Die Kasse ruft eine https-Adresse Ihres Servers auf, signiert und mit Wiederholung über Stunden | Sie wollen den Gast benachrichtigen, ohne ständig zu fragen |
| Ereignis-Feed | GET /api/v1/events?after=<cursor> mit Partner-Schlüssel (events:read) |
Rückfall, wenn Ihr Empfänger ausfiel, oder wenn Sie keine eingehende Adresse betreiben |
Das Feld status der Bestellung:
status |
Bedeutung | status |
Bedeutung |
|---|---|---|---|
| 1 | eingegangen | 6 | bereit |
| 2 | Zahlung läuft | 7 | unterwegs (Lieferung) |
| 3 | bezahlt | 8 | abgeschlossen |
| 4 | angenommen | 9 | storniert |
| 5 | in Zubereitung | 10 | abgelehnt |
Welche Zwischenstufen (5, 6) vorkommen, hängt von den Schritten ab, die der Betrieb im Lieferservice eingeschaltet hat.
Beispiel mit Partner-Schlüssel: Der Betrieb (oder Ihr Server mit orders:manage) nimmt die Bestellung an, danach liefert der Feed die Ereignisse:
curl -sS -X POST "$API/online-checkout/olord_648e7d3cfa87/confirm" -H "X-Dikas-Api-Key: $PARTNER_SCHLUESSEL" | jq -c '.data | {orderNumber, status}'
curl -sS "$API/events?limit=10" -H "X-Dikas-Api-Key: $PARTNER_SCHLUESSEL" | jq -c '.data.events[] | {type, seq, data}'
{"orderNumber":"ON-20261110-001","status":4}
{"type":"order.created","seq":1,"data":{"orderId":"olord_648e7d3cfa87","orderNumber":"ON-20261110-001","orderType":0}}
{"type":"order.status_changed","seq":2,"data":{"orderId":"olord_648e7d3cfa87","orderNumber":"ON-20261110-001","status":4,"previousStatus":1,"isPaid":false}}
Webhook einrichten¶
Ein Administrator des Betriebs legt das Ziel an (https, Port 443, höchstens 3 je Betrieb); die Antwort nennt das Signatur-Geheimnis (whsec_…) einmal:
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}'
Ereignis (type) |
Wann | Inhalt (data) |
|---|---|---|
order.created |
Bestellung angelegt | orderId, orderNumber, orderType, externalRef |
order.status_changed |
Status hat sich geändert | orderId, orderNumber, status, previousStatus, isPaid |
payment.received |
Bestellung ist bezahlt (online oder bar an der Kasse) | orderId, amountPaid, paymentMethod |
order.cancelled |
abgelehnt oder storniert | orderId, orderNumber, reason |
ticket.ready |
Abholnummer fertig | ticketId, number, status |
Jedes Ereignis hat die Hülle id, type, occurredAt (UTC), tenant, seq, apiVersion, data. Die Ereignisse enthalten bewusst keine Namen, Adressen oder Positionen, nur Kennungen und Status; Einzelheiten holen Sie mit Ihrem Schlüssel (orders:read) nach.
Zustellung: mindestens einmal, nicht in strenger Reihenfolge über Ereignisse hinweg. Entdoppeln Sie über id und ordnen Sie über seq (je Bestellung aufsteigend und lückenlos; eine Lücke heißt, dass ein Ereignis fehlt). Antworten Sie mit 2xx, sobald Sie das Ereignis gespeichert haben; bei allem anderen wiederholt die Kasse. 410 schaltet das Ziel ab.
Signatur prüfen: Kopfzeile X-Dikas-Signature: t=<unix>,v1=<hex>. Die signierte Nachricht ist t, ein Punkt und die unveränderten Rohbytes des Rumpfs; Schlüssel ist das Geheimnis als Text (mit whsec_), Verfahren HMAC-SHA256, Hex in Kleinbuchstaben. In Node.js (Express: den Rumpf als Rohbytes lesen, nicht erst parsen):
import crypto from 'node:crypto';
export function signaturGueltig(kopf, rohRumpf, geheimnis, maxAlterSek = 300) {
const t = Number(kopf.match(/t=(\d+)/)?.[1]);
const signaturen = [...kopf.matchAll(/v1=([0-9a-f]+)/g)].map(m => m[1]);
if (!t || Math.abs(Date.now() / 1000 - t) > maxAlterSek) return false; // zu alt: ablehnen
const soll = crypto.createHmac('sha256', geheimnis).update(`${t}.`).update(rohRumpf).digest('hex');
return signaturen.some(s => s.length === soll.length &&
crypto.timingSafeEqual(Buffer.from(s), Buffer.from(soll))); // während einer Rotation mehrere v1
}
Testvektor zum Nachrechnen: Geheimnis whsec_dikas-test-vector-0001, t = 1767312000, Rumpf genau
{"id":"olord_ab12.3","type":"order.status_changed","occurredAt":"2026-01-02T00:00:00Z","tenant":"demo","seq":3,"apiVersion":"2026-11-01","data":{"orderId":"olord_ab12","orderNumber":42,"status":6,"previousStatus":5,"isPaid":false}}
ergibt v1=aa93e991e022bd8dd251f140eb934ae6692cbfa2fb44d8347620c21eb4294649.
Ereignis-Feed¶
Ohne eigene öffentliche Adresse holen Sie dieselben Ereignisse ab:
curl -sS "$API/events?after=$ZEIGER&limit=100" -H "X-Dikas-Api-Key: $PARTNER_SCHLUESSEL" | jq -c '{n:(.data.events|length), nextCursor:.data.nextCursor, hasMore:.data.hasMore}'
Speichern Sie nextCursor und rufen Sie damit erneut auf; ohne after liefert der Feed die letzten 24 Stunden. Aufbewahrt werden die Ereignisse 14 Tage.
F. Bezahlen¶
Die Zahlart legen Sie bei create fest:
paymentMethod |
Ablauf |
|---|---|
cash |
Der Gast zahlt bei Abholung oder Übergabe; kassiert wird in der Kasse mit Beleg |
stripe |
Karte über das Stripe-Konto des Betriebs: init-payment liefert clientSecret und publishableKey für Stripe.js im Browser des Gastes, danach verify-payment |
paypal |
init-payment mit returnUrl liefert eine redirectUrl zu PayPal; nach der Rückkehr verify-payment. PayPal muss im Betrieb eingeschaltet sein |
init-payment und verify-payment rufen Sie mit dem Bestell-Geheimnis (X-Order-Secret) auf. Die Zahlung wird serverseitig bei Stripe bzw. PayPal geprüft, erst dann gilt die Bestellung als bezahlt.
Zahlt Ihr Shop selbst?
Wickelt Ihr Shop die Zahlung über ein eigenes Konto ab, kennt die Kasse sie nicht: Die Bestellung kommt als nicht bezahlt an und erscheint weder im Kassenabschluss noch im DATEV-Export des Betriebs. Lassen Sie die Online-Zahlung deshalb über die Kasse laufen (stripe oder paypal wie oben).
Checkliste vor dem Livegang¶
- Modul und Schalter „Online-Bestellung“ aktiv, Öffnungszeiten und Liefergebiete gepflegt
- Wer führt die Karte (Kasse oder Shop) ist entschieden; Probe-Bestellung mit jedem Artikeltyp
-
Idempotency-Keybei jedemcreate; Fehlercodes im Shop in lesbare Hinweise übersetzt - Partner-Schlüssel mit notiertem Ablaufdatum; technischer Benutzer ohne Administratorrechte
- Status-Rückmeldung gewählt (Abfrage, Webhook oder Feed) und mit einer Probebestellung durchgespielt; Signatur geprüft
- Zahlung über die Kasse getestet
- Probebestellungen im Testsystem storniert
Weiter¶
- API-Referenz zur Webshop-Anbindung: alle Aufrufe, Felder und Fehlercodes zum Nachschlagen
- REST API: Anmeldung, Format, Wiederholsicherheit
- API-Zugänge und Rechte
- Online-Shop von DiKAS
- Lieferservice