Zum Inhalt
v26.3

Gutscheine und Fremdsysteme

Diese Anleitung hilft bei der Übernahme alter Gutscheine und bei der Anbindung einer anderen Software an die vorhandenen Gutscheinzugänge. Entscheidend ist, welches System den verbindlichen Restwert führt. Das ist vor jeder Übernahme und jedem Parallelbetrieb festzulegen.

Zuerst den Gutscheinbestand zuordnen

Bestand Zuständig Was das für die Anbindung bedeutet
Lokale DiKAS-Gutscheine Einzelner DiKAS-Mandant Lokaler Dateiimport und lokale Gutschein-API
Kettengutscheine mit DCH- Zentrale Kettenverwaltung Eigene Aktivierungs-, Reservierungs- und Verrechnungsabläufe; keine lokalen Gutscheinbestände
Gutscheine eines anderen Anbieters Vereinbartes führendes System Export, sichere Buchungsmöglichkeiten und Rückgaben mit dem Anbieter klären

Die lokale Gutschein-API macht einen Gutschein nicht automatisch in mehreren Filialen gültig. Ein gemeinsamer Bestand darf nicht in mehrere Mandanten kopiert und anschließend unabhängig eingelöst werden.

→ Abläufe für Kettengutscheine · Lokale Gutscheine

Offene Gutscheine aus einem Altsystem übernehmen

  1. Ziel und Stichtag festlegen: Soll das alte System danach weiter Gutscheine einlösen? Wer ist Aussteller und wer trägt den offenen Wert? Bei mehreren Filialen zuerst die gemeinsame Zuständigkeit klären.
  2. Daten exportieren: Gutscheinnummer als Text, Ursprungsbetrag, offener Restwert, Gutscheinart, bei Einzweck der bisherige Steuersatz, Ausgabedatum, Gültigkeit und Status bereitstellen. Führende Nullen und Sonderzeichen erhalten. Herkunft und ausgebenden Betrieb für die Abstimmung zusätzlich dokumentieren.
  3. Altannahme abstimmen: Zwischen endgültigem Export und Umschaltung dürfen keine undokumentierten Einlösungen oder Aufladungen entstehen. Andernfalls ist der übernommene Restwert bereits veraltet.
  4. Vorschau prüfen: In Kunden → Gutscheine → Import/Export die Vorlage und Feldzuordnung verwenden. Doppelte Nummern, fehlende Nummern und unplausible Beträge vor der Übernahme klären. Summe der Restwerte und Datensatzanzahl mit dem Export vergleichen.
  5. Einmal übernehmen: Der Import übernimmt offene Verpflichtungen, keinen erneuten Gutscheinverkauf. Alte Karten können mit ihrer übernommenen Nummer verwendet werden; sie müssen vor der Freigabe stichprobenartig gescannt werden.
  6. Nachprüfen: Einen teilweise eingelösten Gutschein und einen geschlossenen beziehungsweise abgelaufenen Gutschein kontrollieren. Restwert und Gültigkeit müssen zum abgestimmten Bestand passen.
  7. Altes System abschließen: Es darf denselben Wert danach nicht unabhängig weiter ausgeben. Alte Einlösehistorie und Exportnachweis aufbewahren.

Beispiel: Im Altsystem wurden 100 € ausgegeben, 60 € sind bereits verbraucht. Übernommen werden 100 € Ursprungsbetrag und 40 € Restwert. Eine Einlösung über 15 € reduziert den neuen Restwert auf 25 €. Ein später erneut eingelesener alter Export mit 40 € darf diesen Verbrauch nicht rückgängig machen.

Die Importoption Aktualisieren ist kein Ersatz für eine laufende Zahlungssynchronisation. Vor jedem erneuten Import klären, ob seit dem Export bereits Einlösungen in DiKAS erfolgt sind.

→ Importfelder, Vorschau und Fehlerregeln

Lokale Gutscheine über die REST API abfragen

Die Version-1-API verwendet die Anmeldung der jeweiligen Instanz und einen Bearer-Token. Die vollständigen, auf Ihrer Instanz verfügbaren Schemas stehen in der API-Referenz.

GET /api/v1/vouchers/search/0004711
Authorization: Bearer <accessToken>

Die Suche liefert bei Erfolg eine Gutscheinantwort innerhalb von success und data. Die zurückgegebene Dokument-ID für weitere Aufrufe verwenden; gedruckte Nummer und Dokument-ID sind unterschiedliche Angaben.

GET /api/v1/vouchers/<voucherId>
Authorization: Bearer <accessToken>

Diese Abfragen beziehen sich auf den lokalen Mandanten. Für einen Verkauf wird ein lokaler Gutschein im normalen Zahlungsaufruf als Gutschein-Zahlanteil eingebunden. Damit bleiben Beleg und Zahlung zusammen. Ein separater Bestandsaufruf erstellt keinen Kassenbeleg.

→ Anmeldung und Zahlungsendpunkte

Bestehende Legacy-Anbindung weiterverwenden

Die Legacy-Schnittstelle bietet drei lokale Gutscheinaktionen:

Methode Pfad Zweck
GET /rest/extern/voucher/-/{nummerOderId} Lokalen Gutschein nach Nummer, ersatzweise Dokument-ID abfragen
POST /rest/extern/voucher/-/create Lokalen Gutschein anlegen
POST /rest/extern/voucher/-/redeem Lokalen Restwert belasten

Der Platzhalter - bleibt Bestandteil des Pfads. Den Schlüssel mit Berechtigung Voucher in der Kopfzeile übergeben:

GET /rest/extern/voucher/-/0004711
X-Api-Key: <voucher-api-key>

Anlage eines lokalen Gutscheins:

POST /rest/extern/voucher/-/create
X-Api-Key: <voucher-api-key>
Content-Type: application/json

{
  "Amount": 50.00,
  "Name": "Geschenkgutschein",
  "Serial": "ALT-0004711",
  "ValidDays": 365,
  "IsTaxOpen": true
}

IsTaxOpen: true führt zum lokalen Mehrzweck-/Wertgutschein. Der technische Beispielzeitraum ist keine Empfehlung für eine rechtlich zulässige Gültigkeitsdauer. Die API-Anlage ist eine Bestandsaktion; sie kassiert kein Geld und erzeugt für sich keinen Verkaufsbeleg. Für die Übernahme teilweise eingelöster Altbestände den Import mit getrenntem Ursprungs- und Restbetrag verwenden, statt einen neuen Verkauf vorzutäuschen.

Einlösung durch eine bestehende externe Anwendung:

POST /rest/extern/voucher/-/redeem
X-Api-Key: <voucher-api-key>
Content-Type: application/json

{
  "VoucherId": "<id-aus-der-abfrage>",
  "Amount": 15.00,
  "BonId": "<eindeutige-belegreferenz>"
}

BonId ordnet die Belastung einem Beleg zu; es ersetzt keine Prüfung, ob ein unklar beantworteter Aufruf schon ausgeführt wurde. Die externe Anwendung muss ihren eigenen Beleg-/Zahlungsablauf abstimmen. Die drei Legacy-Aktionen sind keine allgemeine Schnittstelle zur Reservierung und Erstattung von Kettengutscheinen; dafür gibt es die Integrations-API für Kettengutscheine.

Antworten richtig auswerten

Die Legacy-Antwort verwendet andere Felder als die Version-1-API:

{
  "IsOk": true,
  "Message": "",
  "ErrorId": 0,
  "Data": {
    "VoucherId": "<dokument-id>",
    "OpenAmount": 35.00,
    "SerialDisplay": "ALT-0004711"
  }
}

Zusätzlich können Erstellungs- und Änderungszeitpunkt enthalten sein. Fachliche Fehler können ebenfalls mit HTTP 200 zurückkommen. Deshalb immer IsOk und ErrorId prüfen, nicht allein den HTTP-Status. Bei der Version-1-API dagegen success, errorCode und errorMessage auswerten.

Ein fehlender Gutschein liefert einen fachlichen Fehler, kein Guthaben von null. Einen unbekannten Code nicht automatisch neu anlegen.

Integrations-API für Kettengutscheine

→ Schritt-für-Schritt-Anleitung mit Beispielen und Abnahmetest: Externe Gutscheinsysteme anbinden

Eine Fremdkasse kann Kettengutscheine über dieselbe Geldlogik nutzen wie die DiKAS-Kassen: prüfen, reservieren, den Beleg ankündigen, bestätigen, freigeben, erstatten, ausgeben und Änderungen abholen. Das Gateway bucht nichts selbst; es übersetzt die Aufrufe auf die zentralen Abläufe. DiKAS ist dabei das führende System für den Restwert.

Stand

Die Schnittstelle (Version 1) steht zur Verfügung, sobald der Server auf dem Stand Oktober 2026 läuft. Zugänge richtet der Ketten-Eigentümer über die Portal-API ein (siehe unten).

Zugang einrichten

Den Zugang legt der Ketten-Eigentümer mit seiner Portal-Anmeldung an. Er legt fest, welche Rechte (voucher:lookup, voucher:redeem, voucher:refund …) und welche Filialen der Zugang bekommt:

POST /api/v1/portal/chain/<kettenId>/integration-clients
Content-Type: application/json

{"name":"Fremdkasse","scopes":["voucher:lookup","voucher:redeem","voucher:refund"],"branches":["filiale_b"]}

Die Antwort enthält den Zugangsschlüssel (<clientId>.<geheimnis>) genau einmal; DiKAS speichert nur einen Hash. Erneuern: POST …/integration-clients/<clientId>/rotate-key (der alte Schlüssel gilt sofort nicht mehr, es gibt keine Übergangsfrist). Sperren: PUT …/integration-clients/<clientId>/blocked mit {"blocked":true}. Der Schlüssel gehört in einen Tresor, nie in ein Protokoll oder eine Support-Mail.

Aufrufe der Integrations-API verwenden Authorization: Bearer <schluessel> oder die Kopfzeile X-Api-Key. Pro Zugang sind 600 Aufrufe pro Minute erlaubt (danach 429 mit Retry-After). Der Zugang sieht nur seine freigegebenen Filialen; fremde Filialen, Reservierungen oder Vorgänge antworten wie „unbekannt“ (404), nicht „verboten“. Tritt eine Filiale aus der Kette aus, wirkt das bei der nächsten Anfrage.

Ablauf einer Einlösung

Schritt Aufruf (alle unter /api/v1/integrations/vouchers) Zweck
1 POST /lookup Gutschein prüfen; die Antwort enthält nur eine maskierte Nummer (***001X)
2 POST /reservations Betrag für 15 Minuten binden (amountMinor in kleinster Einheit, currency, branchId)
3 POST /reservations/{id}/prepare Beleg ankündigen (receiptReference); ab jetzt verfällt die Reservierung nicht mehr
4 POST /reservations/{id}/commit Einlösung bestätigen; muss denselben Beleg nennen, sonst 409 RECEIPT_MISMATCH
– POST /reservations/{id}/release Reservierung freigeben, wenn der Beleg nie entsteht
5 POST /refunds Erstatten über originalTransactionId, Teil- oder Vollbetrag, Pflicht-reason
– GET /changes?cursor=… Änderungen abholen; Seiten mit nextCursor

Jeder schreibende Aufruf trägt einen Idempotency-Key und eine clientReference. Derselbe Key mit demselben Inhalt liefert das Ergebnis der ersten Ausführung (zehn Wiederholungen buchen einmal); derselbe Key mit anderem Inhalt wird mit 409 IDEMPOTENCY_CONFLICT abgewiesen, bevor etwas gebucht wird. Wollen Sie ganz oder gar nicht einlösen, setzen Sie allowPartial auf false (sonst wird so viel gebucht, wie verfügbar ist).

Antwort verloren? Endet ein Aufruf ohne Antwort oder mit unklarem Ausgang, antwortet DiKAS mit 202 und dem Zustand unknown samt operationId. Dann nicht neu buchen, sondern den Vorgang abfragen: GET /operations/by-reference/{clientReference} oder GET /operations/{operationId}. Die Abfrage klärt aus dem Buchungsjournal, ob die Buchung durchging, und liefert dieselbe Transaktions-Id wie die Originalantwort.

Kann der Anbieter das nicht? GET /programs meldet die Fähigkeiten. Fehlen Reservierung, idempotentes Schreiben oder Vorgangsabfrage, steht dort paidWriteAllowed=false, und jeder schreibende Aufruf endet vor der Ausführung mit 422 PROVIDER_UNSUPPORTED. Bezahlte Buchungen sind dann bewusst gesperrt.

Änderungen abholen

GET /changes liefert abgeleitete Buchungen in der Reihenfolge, in der DiKAS sie bestätigt hat (nicht nach Uhrzeit), mit einem Cursor. Derselbe Cursor liefert immer dieselben Ereignisse; später abgeleitete Buchungen erscheinen hinter dem schon gelesenen Cursor, gehen also nicht verloren. Ist ein Cursor zu alt, antwortet DiKAS mit 410 CURSOR_EXPIRED und Sie lesen den Bestand neu. Reservierungen erscheinen nicht im Feed, nur bestätigte Buchungen. Einen eigenen Webhook gibt es noch nicht; holen Sie regelmäßig ab.

Wichtige Fehlercodes

Code Bedeutung
INSUFFICIENT_SCOPE (403) Dem Zugang fehlt das Recht für diesen Aufruf
BRANCH_UNKNOWN, PROGRAM_UNKNOWN, RESERVATION_UNKNOWN, TRANSACTION_UNKNOWN, OPERATION_NOT_FOUND (404) Nicht vorhanden oder nicht für diesen Zugang sichtbar
IDEMPOTENCY_CONFLICT (409) Derselbe Key mit anderem Inhalt
RECEIPT_MISMATCH (409) Commit nennt einen anderen Beleg als Prepare
REFUND_LIMIT_EXCEEDED (422) Mehr erstattet, als eingelöst wurde
REDEMPTION_PENDING (409) Einlösung noch offen — erst klären
VOUCHER_VOID, VOUCHER_EXPIRED Gutschein entwertet / abgelaufen (je nach Kettenregel)
VOUCHER_NOT_ACCEPTED_HERE Einzweckgutschein, nicht bei diesem Rechtsträger einlösbar
CURRENCY_MISMATCH Währung weicht ab; es wird nicht umgerechnet
PROVIDER_UNSUPPORTED (422) Der Anbieter kann die Funktion nicht sicher
RATE_LIMITED (429), CLIENT_BLOCKED, INVALID_CREDENTIALS (401) Zugang gedrosselt, gesperrt oder Schlüssel falsch

Die maschinenlesbare Beschreibung steht als OpenAPI-Datei gutschein-gateway-v1.yaml bereit; Sie erhalten sie von Ihrem DiKAS-Ansprechpartner. Die Schnittstelle ist (noch) nicht Teil der allgemeinen API-Referenz.

Mehrere Server-Instanzen

Mengenbegrenzung und Änderungsfeed arbeiten je Server-Prozess. Betreiben Sie die Kette weiterhin mit einem Server; mehrere gleichzeitige Instanzen derselben Datenbank sind nicht unterstützt.

Parallelbetrieb mit einer anderen Software vorbereiten

Für den dauerhaften Betrieb reicht ein gemeinsamer Exportordner nicht aus. Beide Kassen müssen für dieselbe Karte auf denselben verbindlichen Bestand zugreifen. Eine einfache Abfrage „noch 50 €“ mit späterem Zurückschreiben „jetzt 20 €“ verhindert keine gleichzeitige zweite Einlösung.

Vor der Einrichtung mit dem Anbieter klären:

  • Welches System führt den Saldo? Welche Filialen und Rechtsträger dürfen einlösen?
  • Kann der Anbieter Beträge verbindlich reservieren, bestätigen und bei Abbruch freigeben?
  • Wird eine wiederholte Buchung mit derselben Vorgangsreferenz als derselbe Vorgang erkannt?
  • Lässt sich nach einer Verbindungsunterbrechung abfragen, ob genau diese Buchung erfolgreich war?
  • Wie funktionieren vollständige und teilweise Erstattungen einschließlich Verrechnung?
  • Welche Daten können abgeholt werden, und wie sind Währung, Status, alte Nummern und Zeitpunkte definiert?

Kann ein Anbieter nur Dateien exportieren, eignet sich das für eine Übernahme oder einen Bericht. Ein sicherer gleichzeitiger Zahlungsbetrieb lässt sich daraus nicht ableiten. Für die gemeinsame Einrichtung Exportbeispiel und Beschreibung der vorhandenen API dem DiKAS-Support über den vereinbarten Weg bereitstellen.

Fehler oder unklarer Abschluss

  • Noch kein Beleg: Bei fehlender Verbindung einen anderen Zahlweg wählen.
  • Beleg oder Belastung möglicherweise vorhanden: Keine neue Buchung mit neuer Referenz auslösen. Zuerst Beleg und Gutscheinstand anhand des konkreten Vorgangs prüfen lassen; der aktuelle Restwert allein beweist nicht, welche von mehreren Buchungen ausgeführt wurde.
  • Storno: An einer DiKAS-Kasse erstattet der Bonstorno eine bestätigte Kettengutschein-Einlösung automatisch (Gegenbuchung auf denselben Gutschein, siehe Erstattung beim Bonstorno). Bei einem Fremdsystem erfolgt die Erstattung über den Rückgabe-Aufruf der Integrations-API mit der Transaktions-Id der Einlösung; eine Entwertung ersetzt sie nicht.
  • Abgleich: Anzahl, offene Restwerte und Bewegungen getrennt nach Währung und Aussteller vergleichen. Ein CSV-/DATEV-Export ist keine Auszahlung.

Für die Klärung genügen zunächst Filiale, Vorgangs-/Belegreferenz, Betrag, Zeitpunkt und maskierte Gutscheinreferenz. Zugangsschlüssel und vollständige Codes nicht in ungeschützten Protokollen oder öffentlichen Nachrichten versenden.