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:
V0;{SerNr};{Start};{End};{Zähler};{AnzTrans};{Sig})| Unit | Beschreibung |
|---|---|
| kassensichv.types | BelegDaten, SigErgebnis, Prozesstyp-Konstanten (PROZESSTYP_KASSENBELEG, …) |
| kassensichv.manager | TseManager: Einstiegspunkt — TseProcessBeleg, TseOpenBeleg, TseCloseBeleg, Export |
| kassensichv.mock | TseMockNew: Vollständiger Mock-Provider ohne TSE-Hardware für Tests und CI/CD |
| kassensichv.rest | TseRestNew: Cloud-TSE via HTTPS/REST (Fiskaly, Deutsche Fiskal); Bearer-Auth, Retry |
| kassensichv.file | TseFileNew: USB-TSE via Dateisystem (Swissbit, Epson); Poll-basiertes Request/Response |
| kassensichv.exceptions | Strukturierte Fehler-Hierarchie: TseError mit Code + Provider-Info |
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.
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);
| 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 |
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);
}
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).
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...==
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: kassensichv.exceptions
| Konstante | Wert | Verwendung |
|---|---|---|
PROZESSTYP_KASSENBELEG | „Kassenbeleg-V1“ | Normaler Kassenbon (Verkauf) |
PROZESSTYP_STORNO | „Kassenbeleg-V1-Storno“ | Stornierter Vorgang |
PROZESSTYP_TRAINING | „Training“ | Trainings-/Testvorgang (kein Steuerbezug) |
| Seite | Inhalt |
|---|---|
| kassensichv.types | Alle Typen und Konstanten mit Feldbeschreibungen |
| kassensichv.manager | Vollständige Manager-API (alle 7 Funktionen) |
| kassensichv.mock | Mock-Provider — Fehlersimulation, Testzugriff |
| kassensichv.rest | Cloud-TSE REST-Provider — Konfiguration, Retry-Logik |
| kassensichv.file | USB-TSE-Provider — Dateiprotokoll, Poll-Mechanismus |
| kassensichv.exceptions | Fehler-Hierarchie und Behandlungsstrategien |
Letzte Aktualisierung: 2026-06-12