====== KassenSichV-Guide — Kassensicherungsverordnung mit Lyx ======
Dieser Guide erklärt den praktischen Einsatz der ''kassensichv''-Bibliothek für die gesetzeskonforme TSE-Anbindung nach **KassenSichV**, **BSI TR-03153** und **DSFinV-K 2.3**.
→ [[lyx_-_programmiersprache:units:kassensichv|kassensichv (Unit-Referenz)]] · [[lyx_-_programmiersprache:units:kassensichv:manager|kassensichv.manager]] · [[lyx_-_programmiersprache:units:kassensichv:mock|Mock]] · [[lyx_-_programmiersprache:units:kassensichv:rest|REST]] · [[lyx_-_programmiersprache:units:kassensichv:file|USB]]
----
===== Rechtliche Grundlagen =====
Die **Kassensicherungsverordnung (KassenSichV)** verpflichtet alle Kassensysteme in Deutschland seit dem 1. Januar 2020, jeden Kassenvorgang mit einer zertifizierten TSE (Technische Sicherheitseinrichtung) zu signieren. Jeder Bon muss diese **Pflichtangaben** enthalten:
* Seriennummer der zertifizierten TSE
* Fortlaufender Signaturzähler
* Start- und Endzeitpunkt laut TSE (UTC)
* Kryptografischer Signaturwert (ECDSA/SHA-256, Base64)
* QR-Code-String nach BSI TR-03153 Anhang A
Der **QR-Code-String** hat exakt dieses Format:
V0;{TSE-Seriennummer};{StartUTC};{EndUTC};{Signaturzähler};{AnzahlTransaktionen};{Signaturwert}
Die ''kassensichv''-Bibliothek erzeugt diesen String automatisch in ''SigErgebnis.qrCode'' — kein manuelles Formatieren nötig.
----
===== Provider wählen =====
Das zentrale Konzept der Bibliothek: Die **gesamte Kassensoftware** interagiert nur mit dem ''TseManager''. Welche TSE physisch angebunden ist, bestimmt ausschließlich der Provider beim Start:
^ Provider ^ Unit ^ Typischer Einsatz ^
| ''TseMockNew()'' | ''kassensichv.mock'' | Tests, CI/CD, Bondruckvorschau — keine Hardware nötig |
| ''TseRestNew(cfg)'' | ''kassensichv.rest'' | Cloud-TSE: Fiskaly, Deutsche Fiskal — billiger Einstieg |
| ''TseFileNew(cfg)'' | ''kassensichv.file'' | USB-TSE: Swissbit, Epson — stationäre Kasse mit eigener Hardware |
**Wechsel zwischen Providern:** Nur die ''TseXxxNew''-Zeile ändern. Der gesamte Beleg-Code bleibt identisch — das ist der Hauptvorteil der Dependency-Inversion-Architektur.
----
===== Entwicklung: Mock-Provider =====
Während der Entwicklung und in CI/CD-Pipelines immer den Mock-Provider verwenden. Er benötigt keine Hardware, keine Netzwerkverbindung und keine API-Keys.
import kassensichv.types;
import kassensichv.mock;
import kassensichv.manager;
fn main(): int64 {
var mgr: int64 := TseMockNew();
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 := 250; // Eurocent (kein float — Rundungsfehler!)
var sig: int64 := TseProcessBeleg(mgr, addr beleg);
var s: SigErgebnis := (sig as *SigErgebnis)^;
// Mock-Ausgabe:
// V0;MOCK-TSE-0000000000000001;2026-06-12T09:30:00Z;2026-06-12T09:30:01Z;1;1;base64...
PrintLn(s.qrCode as pchar);
SigErgebnisFree(sig);
TseManagerFree(mgr);
return 0;
}
==== Fehlersimulation ====
Der Mock kann alle Fehlerzustände simulieren — ohne echte TSE-Hardware:
// Verbindungsabbruch simulieren (code=503)
TseMockSetSimulateError(mgr, 1);
var sig: int64 := TseProcessBeleg(mgr, addr beleg);
var s: SigErgebnis := (sig as *SigErgebnis)^;
// s.success == 0, s.errorMsg enthält "Simulierter Verbindungsfehler"
SigErgebnisFree(sig);
TseMockSetSimulateError(mgr, 0);
// Timeout simulieren (code=408)
TseMockSetSimulateTimeout(mgr, 1);
// ... gleiche Struktur ...
TseMockSetSimulateTimeout(mgr, 0);
----
===== Produktion: Cloud-TSE (REST) =====
Für Cloud-TSE-Anbieter (Fiskaly, Deutsche Fiskal). Vorteil: Keine Hardware, zentrale Verwaltung, für mobile Kassen und Online-Shops geeignet.
import kassensichv.types;
import kassensichv.rest;
import kassensichv.manager;
fn ManagerFuerFiskaly(): int64 {
// Konfiguration als JSON-String (in Produktion aus env/config laden)
var cfg: pchar := concat(
"{\"api_url\":\"https://kassensichv.io/api/v1\","c,
"\"api_key\":\""c, EnvGet("FISKALY_API_KEY"c), "\","c,
"\"client_id\":\""c, EnvGet("KASSEN_ID"c), "\"}"c
);
return TseRestNew(cfg as int64);
}
**Empfohlene Umgebungsvariablen:**
^ Variable ^ Bedeutung ^
| ''FISKALY_API_KEY'' | Bearer-Token (nie im Code hardcoden!) |
| ''KASSEN_ID'' | Kassen-ID beim Cloud-Anbieter |
Der REST-Provider wiederholt Requests automatisch bei HTTP 503/504 (bis zu 3 Versuche, exponentielles Backoff: 1s → 2s → 4s). TLS 1.2 wird erzwungen.
----
===== Produktion: USB-TSE (Dateiprotokoll) =====
Für stationäre Kassen mit USB-TSE-Stick (Swissbit, Epson). Der Stick muss als Dateisystem gemountet sein.
import kassensichv.types;
import kassensichv.file;
import kassensichv.manager;
fn ManagerFuerSwissbit(mountPunkt: pchar): int64 {
// "{\"base_path\":\"/mnt/tse\",\"timeout_ms\":5000}"
var cfg: pchar := concat(
"{\"base_path\":\""c, mountPunkt, "\","c,
"\"timeout_ms\":5000}"c
);
return TseFileNew(cfg as int64);
}
Vorbereitung unter Linux:
sudo mount /dev/sdb1 /mnt/tse
Oder dauerhaft via ''/etc/fstab'':
UUID=xxxx-yyyy /mnt/tse vfat auto,user,rw 0 0
----
===== Workflow 1: Einfacher Kassenbon =====
Der Standardfall für eine einzelne Transaktion (Bezahlung an der Kasse):
import kassensichv.types;
import kassensichv.mock;
import kassensichv.manager;
fn EinfacherKassenbon(mgr: int64): void {
var beleg: BelegDaten;
beleg.prozessTyp := PROZESSTYP_KASSENBELEG;
beleg.kassenNr := "KASSE-001"c;
beleg.prozessDaten := "Laptop;999.00_0.00_0.00_0.00_0.00"c;
beleg.umsatz := 99900; // 999,00 EUR in Cent
var sig: int64 := TseProcessBeleg(mgr, addr beleg);
var s: SigErgebnis := (sig as *SigErgebnis)^;
if s.success == 0 then {
Print("[FEHLER] "c); PrintLn(s.errorMsg as pchar);
SigErgebnisFree(sig);
return;
}
// Pflichtfelder auf Bon ausgeben
Print("TSE-Seriennummer: "c); PrintLn(s.tseSerial as pchar);
Print("Signaturzähler: "c); PrintLn(IntToStr(s.sigZaehler)c);
Print("Signaturwert: "c); PrintLn(s.sigWert as pchar);
Print("QR-Code: "c); PrintLn(s.qrCode as pchar);
SigErgebnisFree(sig);
}
===== Workflow 2: Mehrstufige Transaktion (Tischbewirtung) =====
Für Restaurants, Servicebetriebe und andere Vorgänge mit Zwischenständen:
fn Tischbestellung(mgr: int64, tischNr: int64): void {
var beleg: BelegDaten;
beleg.prozessTyp := PROZESSTYP_KASSENBELEG;
beleg.kassenNr := "KASSE-001"c;
// Transaktion öffnen — TSE vergiBt Zähler + Startzeitpunkt
var transId: int64 := TseOpenBeleg(mgr, addr beleg);
// Vorspeise geliefert (Zwischenstand, optional)
beleg.prozessDaten := "Suppe;5.50_0.00_0.00_0.00_0.00"c;
beleg.umsatz := 550;
var zwi: int64 := TseUpdateBeleg(mgr, transId, addr beleg);
SigErgebnisFree(zwi);
// Hauptgang hinzu
beleg.prozessDaten := "Suppe+Schnitzel;22.50_0.00_0.00_0.00_0.00"c;
beleg.umsatz := 2250;
var zwi2: int64 := TseUpdateBeleg(mgr, transId, addr beleg);
SigErgebnisFree(zwi2);
// Rechnung — Transaktion abschließen
beleg.prozessDaten := "Suppe+Schnitzel+Dessert;30.00_0.00_0.00_0.00_0.00"c;
beleg.umsatz := 3000;
var sig: int64 := TseCloseBeleg(mgr, transId, addr beleg);
var s: SigErgebnis := (sig as *SigErgebnis)^;
if s.success == 1 then {
PrintLn(s.qrCode as pchar); // QR-Code auf Bon
} else {
// COMPLIANCE-WARNUNG: Transaktion möglicherweise offen!
Print("[COMPLIANCE] "c); PrintLn(s.errorMsg as pchar);
}
SigErgebnisFree(sig);
free(transId);
}
===== Workflow 3: Stornierung =====
Ein Stornobon ist ein eigenständiger Kassenbon mit dem Prozesstyp ''PROZESSTYP_STORNO''. Er wird genauso signiert wie ein normaler Bon — nur der Prozesstyp und die Belegdaten unterscheiden sich:
fn Stornierung(mgr: int64, originalBetrag: int64): void {
var beleg: BelegDaten;
beleg.prozessTyp := PROZESSTYP_STORNO;
beleg.kassenNr := "KASSE-001"c;
beleg.prozessDaten := "Storno Laptop;-999.00_0.00_0.00_0.00_0.00"c;
beleg.umsatz := -99900; // negativer Betrag
var sig: int64 := TseProcessBeleg(mgr, addr beleg);
var s: SigErgebnis := (sig as *SigErgebnis)^;
if s.success == 1 then {
PrintLn(s.qrCode as pchar);
}
SigErgebnisFree(sig);
}
===== Workflow 4: Trainingsbetrieb =====
Testkäufe und Mitarbeiterschulungen müssen mit dem Prozesstyp ''PROZESSTYP_TRAINING'' signiert werden. Diese Vorgänge sind steuerlich nicht relevant, aber trotzdem TSE-pflichtig:
var beleg: BelegDaten;
beleg.prozessTyp := PROZESSTYP_TRAINING;
beleg.kassenNr := "KASSE-001"c;
beleg.prozessDaten := "Training;0.00_0.00_0.00_0.00_0.00"c;
beleg.umsatz := 0;
var sig: int64 := TseProcessBeleg(mgr, addr beleg);
// ... Bon als "TRAINING" markieren, nicht als echter Kassenbon
===== Workflow 5: DSFinV-K-Export (Finanzamt-Prüfung) =====
Finanzämter können den Export der TSE-Audit-Logs anfordern. Die Bibliothek erzeugt:
* ''{path}/tse_export.tar'' — TSE-intern signiertes Archiv (nicht verändern!)
* ''{path}/index.json'' — Exportmetadaten nach DSFinV-K 2.3
fn FinanzamtExport(mgr: int64): int64 {
var exportPfad: pchar := "/var/kassensichv/export"c;
var ok: int64 := TseExportAuditData(mgr, exportPfad as int64, "KASSE-001"c);
if ok == 0 then {
PrintLn("Export fehlgeschlagen — Verzeichnis nicht beschreibbar?"c);
return 0;
}
// Ergebnis: /var/kassensichv/export/tse_export.tar + index.json
PrintLn("DSFinV-K-Export erfolgreich"c);
return 1;
}
**index.json Inhalt:**
{
"dsfinvk_version": "2.3",
"tse_serial": "SWB-0123456789ABCDEF",
"kasse_id": "KASSE-001",
"export_timestamp": "2026-06-12T09:00:00Z"
}
----
===== Fehlerbehandlung =====
==== Normale Fehler ====
Alle Fehler werden über ''SigErgebnis.success'' und ''SigErgebnis.errorMsg'' zurückgegeben:
var sig: int64 := TseProcessBeleg(mgr, addr beleg);
var s: SigErgebnis := (sig as *SigErgebnis)^;
if s.success == 0 then {
Print("TSE-Fehler: "c);
PrintLn(s.errorMsg as pchar);
SigErgebnisFree(sig);
return 0;
}
// Bon drucken ...
SigErgebnisFree(sig);
==== Compliance-kritisch: Offene Transaktionen ====
Wenn ''TseCloseBeleg'' mit ''success=0'' zurückkommt, ist die TSE-Transaktion **möglicherweise noch offen**. Das ist ein Compliance-Problem — die Kassensoftware muss reagieren:
var sig: int64 := TseCloseBeleg(mgr, transId, addr beleg);
var s: SigErgebnis := (sig as *SigErgebnis)^;
if s.success == 0 then {
// PFLICHT: Vorfall protokollieren
Print("[COMPLIANCE] Offene TSE-Transaktion — TransId: "c);
PrintLn(transId as pchar);
Print("[COMPLIANCE] Fehler: "c);
PrintLn(s.errorMsg as pchar);
// TSE-Status prüfen
var status: int64 := TseGetStatus(mgr);
Print("[COMPLIANCE] TSE-Status: "c);
PrintLn(status as pchar);
free(status);
// Bon NICHT drucken bis Situation geklärt
SigErgebnisFree(sig);
free(transId);
return 0;
}
**Faustregel:** Nie einen Kassenbon ausgeben, wenn ''success=0''. Die Kassensoftware muss die offene Transaktion manuell abschließen oder beim TSE-Anbieter melden.
==== Fehlercode-Tabelle ====
^ Code ^ Bedeutung ^ Empfohlene Reaktion ^
| 400 | Konfigurationsfehler | Programm nicht starten, Konfiguration prüfen |
| 403 | Exportpfad nicht schreibbar | Verzeichnis anlegen, Rechte prüfen |
| 408 | Timeout | Verbindung zur TSE prüfen, USB-Stick eingesteckt? |
| 409 | Offene Transaktion | Vorfall protokollieren, Support kontaktieren |
| 500 | TSE-interner Signierfehler | TSE-Hardware defekt? TSE-Anbieter kontaktieren |
| 503 | Verbindungsfehler | Netzwerk (REST) oder USB-Mount (File) prüfen |
----
===== Initialisierung beim Programmstart =====
Konfigurationsfehler möglichst früh erkennen — nicht erst beim ersten Bon:
import kassensichv.rest;
import kassensichv.manager;
fn TseInitPruefen(mgr: int64): int64 {
// Status als erstes abfragen — erkennt Konfigurationsfehler sofort
var status: int64 := TseGetStatus(mgr);
if status == 0 then {
PrintLn("[FEHLER] TSE konnte nicht initialisiert werden"c);
return 0;
}
// Seriennummer prüfen — bei REST: wird von API geladen
var serial: int64 := TseGetSerial(mgr);
if serial == 0 then {
PrintLn("[FEHLER] TSE-Seriennummer nicht abrufbar"c);
free(status);
return 0;
}
Print("TSE bereit: "c); PrintLn(serial as pchar);
free(serial);
free(status);
return 1;
}
fn main(): int64 {
var mgr: int64 := TseRestNew(cfg as int64);
if TseInitPruefen(mgr) == 0 then {
TseManagerFree(mgr);
return 1; // Programm abbrechen
}
// Kassensoftware starten ...
return 0;
}
----
===== Umsatz-Berechnung: Eurocent, kein Float =====
**Niemals** ''f64'' für Geldbeträge verwenden. IEEE-754-Gleitkommazahlen haben Rundungsfehler (0.1 + 0.2 ≠ 0.3). Das ''umsatz''-Feld in ''BelegDaten'' ist ''int64'' in **Eurocent**:
// FALSCH — Rundungsfehler bei 0.1 + 0.2
var betrag: f64 := 9.99;
beleg.umsatz := betrag as int64; // kann 998 oder 999 ergeben!
// RICHTIG — integer Eurocent
beleg.umsatz := 999; // 9,99 EUR = 999 Cent
// RICHTIG — Addition
var teilbetrag1: int64 := 550; // 5,50 EUR
var teilbetrag2: int64 := 800; // 8,00 EUR
beleg.umsatz := teilbetrag1 + teilbetrag2; // exakt 1350 Cent = 13,50 EUR
Das DSFinV-K-Format erwartet Beträge mit Punkt als Dezimaltrennzeichen (''9.99'') im ''prozessDaten''-String — das ist reines Textformat und unabhängig von der internen Cent-Rechnung.
----
===== Prozessdaten-Format (DSFinV-K) =====
Das ''prozessDaten''-Feld folgt dem **DSFinV-K 2.3-Schema**. Für einfache Kassenbons:
{Artikel};{Betrag_19%}_{Betrag_7%}_{Betrag_0%}_{Betrag_special}_{Betrag_sonstig}
Mehrwertsteuer-Zuordnung nach Steuersatz:
^ Spalte ^ Steuersatz ^ Typischer Einsatz ^
| Feld 1 (19%) | Normaler MwSt.-Satz | Elektronik, Kleidung, Haushaltsware |
| Feld 2 (7%) | Ermäßigter MwSt.-Satz | Lebensmittel, Bücher, ÖPNV-Tickets |
| Feld 3 (0%) | Steuerfreie Umsätze | Exportlieferungen, Versicherungen |
| Feld 4 | Besonderer Steuersatz | Spezialfälle |
| Feld 5 | Sonstige | Trinkgelder, Gutscheineinlösung |
// Laptop (19% MwSt.): 999,00 EUR
beleg.prozessDaten := "Laptop;999.00_0.00_0.00_0.00_0.00"c;
// Buch (7% MwSt.): 15,90 EUR
beleg.prozessDaten := "Buch;0.00_15.90_0.00_0.00_0.00"c;
// Gemischter Einkauf
beleg.prozessDaten := "Laptop+Buch;999.00_15.90_0.00_0.00_0.00"c;
// Restaurant-Bestellung (Speisen 7%, Getränke 19%)
beleg.prozessDaten := "Getränke+Speisen;8.50_12.00_0.00_0.00_0.00"c;
Für vollständige DSFinV-K-Anforderungen (komplexe Bonpflicht-Details, Kassenabschlüsse) die offizielle **DSFinV-K 2.3-Spezifikation** des BMF (Bundesministerium der Finanzen) konsultieren.
----
===== Testen =====
==== Einheitstests mit Mock ====
import kassensichv.types;
import kassensichv.mock;
import kassensichv.manager;
fn TestEinfacherBon(): int64 {
var mgr: int64 := TseMockNew();
var beleg: BelegDaten;
beleg.prozessTyp := PROZESSTYP_KASSENBELEG;
beleg.kassenNr := "TEST-001"c;
beleg.prozessDaten := "Test-Artikel;1.00_0.00_0.00_0.00_0.00"c;
beleg.umsatz := 100;
var sig: int64 := TseProcessBeleg(mgr, addr beleg);
var s: SigErgebnis := (sig as *SigErgebnis)^;
var ok: int64 := 1;
// success muss 1 sein
if s.success == 0 then { PrintLn("FAIL: success=0"c); ok := 0; }
// Zähler muss 1 sein (erster Bon)
if s.sigZaehler != 1 then { PrintLn("FAIL: sigZaehler != 1"c); ok := 0; }
// QR-Code muss mit V0;MOCK beginnen
// (Vergleich mit StringStartsWith aus std.string)
SigErgebnisFree(sig);
TseManagerFree(mgr);
return ok;
}
fn TestSignaturZaehlerMonoton(): int64 {
var mgr: int64 := TseMockNew();
var prevZaehler: int64 := 0;
var i: int64 := 1;
while i <= 5 do {
var b: BelegDaten;
b.prozessTyp := PROZESSTYP_KASSENBELEG;
var sig: int64 := TseProcessBeleg(mgr, addr b);
var s: SigErgebnis := (sig as *SigErgebnis)^;
if s.sigZaehler <= prevZaehler then {
PrintLn("FAIL: Zähler nicht monoton steigend"c);
SigErgebnisFree(sig);
TseManagerFree(mgr);
return 0;
}
prevZaehler := s.sigZaehler;
SigErgebnisFree(sig);
i := i + 1;
}
TseManagerFree(mgr);
return 1;
}
fn TestTimeout(): int64 {
var mgr: int64 := TseMockNew();
TseMockSetSimulateTimeout(mgr, 1);
var b: BelegDaten; b.prozessTyp := PROZESSTYP_KASSENBELEG;
var sig: int64 := TseProcessBeleg(mgr, addr b);
var s: SigErgebnis := (sig as *SigErgebnis)^;
var ok: int64 := 1;
if s.success != 0 then { PrintLn("FAIL: Timeout nicht erkannt"c); ok := 0; }
SigErgebnisFree(sig);
TseManagerFree(mgr);
return ok;
}
==== BSI TR-03153 QR-Code-Validierung ====
Die BSI TR-03153 (Anhang A) enthält offizielle Testvektoren für das QR-Code-Format. Beim Mock lässt sich das Format-Muster prüfen:
Format: V0;{7 Felder, semikolon-getrennt}
Feld 1: "V0" (fest)
Feld 2: TSE-Seriennummer (nicht leer)
Feld 3: Startzeitpunkt UTC (ISO 8601, endet auf "Z")
Feld 4: Endzeitpunkt UTC (ISO 8601, endet auf "Z")
Feld 5: Signaturzähler (positive ganze Zahl)
Feld 6: Anzahl Transaktionen (positive ganze Zahl)
Feld 7: Signaturwert (Base64, nicht leer)
----
===== Provider-Entscheidungsguide =====
Welche Art TSE brauche ich?
│
├── Entwicklung / Tests / CI? ──────────────────► TseMockNew()
│ (kassensichv.mock)
│
├── Stationäre Kasse, eigene Hardware gewünscht?
│ │
│ ├── USB-TSE vorhanden (Swissbit / Epson)?
│ │ └── Ja ─────────────────────────► TseFileNew(cfg)
│ │ (kassensichv.file)
│ └── Nein → weiter zu Cloud
│
└── Mobile Kasse / Online-Shop / kein Sticks-Management?
└──────────────────────────────────────────► TseRestNew(cfg)
(kassensichv.rest)
Fiskaly / Deutsche Fiskal
^ Kriterium ^ Mock ^ REST (Cloud) ^ File (USB) ^
| Hardware nötig | nein | nein | USB-TSE-Stick |
| Netzwerk nötig | nein | ja | nein |
| Monatliche Kosten | nein | ja (Anbietergebühr) | nein (nach Einmalkauf) |
| Geeignet für Tests | ja | Sandbox | nein (Hardware) |
| Offline-Betrieb | ja | nein | ja |
| Mobile Kasse | — | empfohlen | möglich (USB-Hub) |
| Zentrales Management | — | ja | nein |
----
===== Checkliste vor der Inbetriebnahme =====
* [ ] TSE beim BSI-zertifizierten Anbieter angemeldet (Fiskaly, Swissbit, ...)
* [ ] TSE innerhalb von **4 Wochen nach Inbetriebnahme** beim Finanzamt gemeldet (§ 146a AO)
* [ ] Alle Bonds enthalten die 7 Pflichtfelder nach KassenSichV / BSI TR-03153
* [ ] ''SigErgebnis.success'' wird vor Bonausgabe geprüft
* [ ] Offene Transaktionen (''success=0'' bei ''TseCloseBeleg'') werden protokolliert und behandelt
* [ ] ''TseExportAuditData'' wurde getestet und ist einsatzbereit
* [ ] Exportverzeichnis hat die richtigen Schreibrechte
* [ ] Konfiguration (API-Key, Kassen-ID) kommt aus Umgebungsvariablen oder verschlüsseltem Config — **nie im Quellcode hardcoden**
* [ ] CI/CD-Tests laufen mit Mock-Provider
* [ ] BSI-Testvektoren für QR-Code-Format wurden geprüft
> **Haftungshinweis:** Diese Bibliothek ist ein technisches Hilfsmittel. Kassenbetreiber sind für die gesetzeskonforme Integration und den ordnungsgemäßen Betrieb verantwortlich. Bei Unklarheiten zur rechtlichen Einordnung steuerlichen oder rechtlichen Rat einholen.
----
===== Weiterführend =====
* [[lyx_-_programmiersprache:units:kassensichv|kassensichv — Unit-Referenz (alle 6 Units)]]
* [[lyx_-_programmiersprache:units:kassensichv:manager|kassensichv.manager — vollständige API]]
* [[lyx_-_programmiersprache:units:kassensichv:exceptions|kassensichv.exceptions — Fehlerbehandlung]]
* [[lyx_-_programmiersprache:guides:welche-unit|Welche Unit? — Entscheidungsguide]]
Letzte Aktualisierung: 2026-06-12