====== std.kassensichv — KassenSichV / TSE-Anbindung ======
→ [[lyx_-_programmiersprache:units|Zurück zur Unit-Übersicht]]
Rechtskonforme Kassensicherungsverordnung-Bibliothek für die gesetzlich vorgeschriebene TSE-Anbindung (Technische Sicherheitseinrichtung). Grundlage: **KassenSichV** (Kassensicherungsverordnung), **BSI TR-03153** und **DSFinV-K 2.3**.
Die Bibliothek nimmt Kassenbonrohdaten (''BelegDaten'') entgegen, kommuniziert mit der TSE und liefert alle Pflichtangaben für den Bondruck (''SigErgebnis'') — einschließlich des QR-Code-Strings nach BSI TR-03153 Anhang A.
**Rechtliche Pflichtangaben auf dem Kassenbon:**
* TSE-Seriennummer
* Fortlaufender Signaturzähler
* Start- und Endzeitpunkt laut TSE (UTC)
* ECDSA/SHA-256-Signaturwert (Base64)
* QR-Code-String (Format ''V0;{SerNr};{Start};{End};{Zähler};{AnzTrans};{Sig}'')
===== Units =====
^ Unit ^ Beschreibung ^
| [[lyx_-_programmiersprache:units:kassensichv:types|kassensichv.types]] | ''BelegDaten'', ''SigErgebnis'', Prozesstyp-Konstanten (''PROZESSTYP_KASSENBELEG'', …) |
| [[lyx_-_programmiersprache:units:kassensichv:manager|kassensichv.manager]] | ''TseManager'': Einstiegspunkt — ''TseProcessBeleg'', ''TseOpenBeleg'', ''TseCloseBeleg'', Export |
| [[lyx_-_programmiersprache:units:kassensichv:mock|kassensichv.mock]] | ''TseMockNew'': Vollständiger Mock-Provider ohne TSE-Hardware für Tests und CI/CD |
| [[lyx_-_programmiersprache:units:kassensichv:rest|kassensichv.rest]] | ''TseRestNew'': Cloud-TSE via HTTPS/REST (Fiskaly, Deutsche Fiskal); Bearer-Auth, Retry |
| [[lyx_-_programmiersprache:units:kassensichv:file|kassensichv.file]] | ''TseFileNew'': USB-TSE via Dateisystem (Swissbit, Epson); Poll-basiertes Request/Response |
| [[lyx_-_programmiersprache:units:kassensichv:exceptions|kassensichv.exceptions]] | Strukturierte Fehler-Hierarchie: ''TseError'' mit Code + Provider-Info |
===== Provider-Konzept =====
Das zentrale Designprinzip ist die **Dependency Inversion**: Die gesamte Kassensoftware nutzt ausschließlich den ''TseManager''. Welche TSE physisch angebunden ist (Cloud, USB, Mock), wird einmalig bei der Initialisierung festgelegt — der übrige Code ist identisch.
Kassensoftware
│
│ TseProcessBeleg(mgr, beleg)
▼
TseManager
│ StartTransaction()
├──────────────────────────────► TSE-Provider
│ │
│ (Cloud REST / USB / Mock)
│ FinishTransaction() │ ECDSA-Signatur
│◄────────────────────────────────────┘
│
│ QR-Code generieren (BSI TR-03153)
│
▼
SigErgebnis → Kassenbon drucken
**Wechsel des Providers** erfordert nur eine Änderung beim ''TseManager''-Create — der Beleg-Code bleibt unverändert.
===== Schnellstart =====
import kassensichv.types;
import kassensichv.mock;
import kassensichv.manager;
fn DruckKassenbon(): void {
// 1. Provider wählen (hier: Mock für Tests)
var mgr: int64 := TseMockNew();
// 2. Beleg befüllen
var beleg: BelegDaten;
beleg.prozessTyp := PROZESSTYP_KASSENBELEG;
beleg.kassenNr := "KASSE-001"c;
beleg.prozessDaten := "Kaffee;2.50_0.00_0.00_0.00_0.00"c;
beleg.umsatz := 2500; // Eurocent
// 3. Beleg signieren lassen (Start + Finish + QR-Code in einem Schritt)
var sig: int64 := TseProcessBeleg(mgr, addr beleg);
// 4. Pflichtangaben drucken
var s: SigErgebnis := (sig as *SigErgebnis)^;
Print("TSE-Seriennummer: "c); PrintLn(s.tseSerial as pchar);
Print("Signaturzähler: "c); PrintLn(IntToStr(s.sigZaehler)c);
Print("QR-Code: "c); PrintLn(s.qrCode as pchar);
SigErgebnisFree(sig);
TseManagerFree(mgr);
}
Für echte TSEs nur den Provider tauschen:
// Cloud-TSE (Fiskaly)
var cfg: int64 := '{"api_url":"https://kassensichv.io/api/v1","api_key":"...","client_id":"KASSE-001"}'c;
var mgr: int64 := TseRestNew(cfg);
// USB-TSE (Swissbit-Stick unter /mnt/tse)
var cfg: int64 := '{"base_path":"/mnt/tse","timeout_ms":5000}'c;
var mgr: int64 := TseFileNew(cfg);
===== Typen-Übersicht =====
^ Typ ^ Felder (wichtigste) ^ Zweck ^
| ''BelegDaten'' | ''prozessTyp'', ''prozessDaten'', ''kassenNr'', ''umsatz'' | Eingabe: Rohdaten des Kassenbons |
| ''SigErgebnis'' | ''tseSerial'', ''sigZaehler'', ''sigWert'', ''qrCode'', ''success'' | Ausgabe: Pflichtangaben für Bondruck |
Alle String-Felder (''pchar'') in ''SigErgebnis'' sind allokiert — Aufrufer muss ''SigErgebnisFree()'' aufrufen.
^ Feld ^ Typ ^ Bedeutung ^
| ''qrCode'' | ''int64'' (pchar) | Vorformatierter QR-Code-String nach BSI TR-03153 Anhang A |
| ''sigZaehler'' | ''int64'' | Fortlaufender TSE-Vorgangszähler (Pflichtfeld auf Bon) |
| ''sigWert'' | ''int64'' (pchar) | ECDSA/SHA-256, Base64-kodiert |
| ''success'' | ''int64'' | 1 = signiert, 0 = Fehler → ''errorMsg'' auswerten |
===== Mehrstufige Vorgänge =====
Für Tischbewirtung, Bestellungen mit Zwischenständen oder Zeiterfassung gibt es den dreistufigen Workflow:
import kassensichv.manager;
fn TischBestellung(mgr: int64): void {
var beleg: BelegDaten;
beleg.prozessTyp := PROZESSTYP_KASSENBELEG;
beleg.kassenNr := "KASSE-001"c;
// Transaktion öffnen (TSE vergibt Zähler + Zeitstempel)
var transId: int64 := TseOpenBeleg(mgr, addr beleg);
// Zwischenstand nach Vorspeise
beleg.prozessDaten := "Vorspeise;12.00_0.00_0.00_0.00_0.00"c;
beleg.umsatz := 1200;
TseUpdateBeleg(mgr, transId, addr beleg);
// Abschluss nach Hauptgang
beleg.prozessDaten := "Vorspeise+Hauptgang;32.00_0.00_0.00_0.00_0.00"c;
beleg.umsatz := 3200;
var sig: int64 := TseCloseBeleg(mgr, transId, addr beleg);
var s: SigErgebnis := (sig as *SigErgebnis)^;
PrintLn(s.qrCode as pchar);
SigErgebnisFree(sig);
free(transId);
}
===== DSFinV-K-Export =====
Finanzämter können jederzeit den Export des TSE-Audit-Logs anfordern. Die Bibliothek erzeugt eine TAR-Datei (TSE-intern signiert, darf nicht verändert werden) und eine ''index.json'' mit Metadaten:
// Export nach /tmp/tse_export/ (Verzeichnis muss existieren)
var ok: int64 := TseExportAuditData(mgr, "/tmp/tse_export"c, "KASSE-001"c);
// Erzeugt: /tmp/tse_export/tse_export.tar + index.json
''index.json'' enthält: DSFinV-K-Version (2.3), TSE-Seriennummer, Kassen-ID, Export-Zeitpunkt (ISO 8601 UTC).
===== QR-Code-Format =====
Der QR-Code-String nach **BSI TR-03153 Anhang A** hat exakt folgendes Format:
V0;{TSE-Seriennummer};{StartUTC};{EndUTC};{Signaturzähler};{AnzahlTransaktionen};{SignaturBase64}
Beispiel:
V0;MOCK-TSE-0000000000000001;2026-06-12T09:30:00Z;2026-06-12T09:30:01Z;1;1;abc123XYZ...==
===== Fehlerbehandlung =====
Alle Fehler der Bibliothek werden als ''TseError''-Struktur mit Code und Provider-Info zurückgegeben. Offene Transaktionen nach einem ''TseCloseBeleg''-Fehler sind ein **Compliance-Problem** und müssen sofort behandelt werden.
^ Fehlercode ^ Bedeutung ^ Beispiel ^
| 400 | Konfigurationsfehler | ''api_key'' fehlt in ConfigJSON |
| 403 | Exportpfad nicht schreibbar | Verzeichnis nicht beschreibbar |
| 408 | Timeout | TSE antwortet nicht innerhalb ''timeout_ms'' |
| 409 | Transaktionsfehler | Offene Transaktion, doppelte TransId |
| 500 | Signierfehler | ECDSA-Schlüssel ungültig |
| 503 | Verbindungsfehler | USB-TSE nicht verbunden, Cloud nicht erreichbar |
→ Details: [[lyx_-_programmiersprache:units:kassensichv:exceptions|kassensichv.exceptions]]
===== Prozesstypen (BSI TR-03153) =====
^ Konstante ^ Wert ^ Verwendung ^
| ''PROZESSTYP_KASSENBELEG'' | ''"Kassenbeleg-V1"'' | Normaler Kassenbon (Verkauf) |
| ''PROZESSTYP_STORNO'' | ''"Kassenbeleg-V1-Storno"'' | Stornierter Vorgang |
| ''PROZESSTYP_TRAINING'' | ''"Training"'' | Trainings-/Testvorgang (kein Steuerbezug) |
===== Detailseiten =====
^ Seite ^ Inhalt ^
| [[lyx_-_programmiersprache:units:kassensichv:types|kassensichv.types]] | Alle Typen und Konstanten mit Feldbeschreibungen |
| [[lyx_-_programmiersprache:units:kassensichv:manager|kassensichv.manager]] | Vollständige Manager-API (alle 7 Funktionen) |
| [[lyx_-_programmiersprache:units:kassensichv:mock|kassensichv.mock]] | Mock-Provider — Fehlersimulation, Testzugriff |
| [[lyx_-_programmiersprache:units:kassensichv:rest|kassensichv.rest]] | Cloud-TSE REST-Provider — Konfiguration, Retry-Logik |
| [[lyx_-_programmiersprache:units:kassensichv:file|kassensichv.file]] | USB-TSE-Provider — Dateiprotokoll, Poll-Mechanismus |
| [[lyx_-_programmiersprache:units:kassensichv:exceptions|kassensichv.exceptions]] | Fehler-Hierarchie und Behandlungsstrategien |
-----
Letzte Aktualisierung: 2026-06-12