Design
Verfahrensdokumentation Rechnungswesen (GoBD)
Dokumenttyp: Verfahrensdokumentation gemäß GoBD
Produkt: Run a Campsite – Rechnungswesen-Modul
Geltungsbereich: Campsite-Mgmt-Service, Billing-Modul
Rechtsgrundlage: Grundsätze zur ordnungsmäßigen Führung und Aufbewahrung von Büchern, Aufzeichnungen und Unterlagen in elektronischer Form sowie zum Datenzugriff (GoBD), BMF-Schreiben vom 28.11.2019
Stand: April 2026
1. Einleitung und Zweck
Diese Verfahrensdokumentation beschreibt die technischen und organisatorischen Maßnahmen, die das Rechnungswesen-Modul von Run a Campsite zum Schutz der Ordnungsmäßigkeit, Vollständigkeit, Unveränderlichkeit und Nachvollziehbarkeit elektronischer Belege gemäß GoBD umsetzt.
Die Dokumentation richtet sich an:
- Betreiber von Campingplätzen, die das Modul einsetzen
- Steuerberater und Betriebsprüfer, die den technischen Nachweis der GoBD-Konformität benötigen
- Systemadministratoren, die für den Betrieb der Plattform verantwortlich sind
2. Systemübersicht
2.1 Systemkomponenten
Das Rechnungswesen-Modul ist Bestandteil des Campsite-Mgmt-Service der Run a Campsite-Plattform. Es besteht aus folgenden Komponenten:
| Komponente | Beschreibung |
|---|---|
| Folio-Verwaltung | Gästekonto pro Buchung; verwaltet offene Positionen |
| Rechnungsverwaltung | Erstellung, Finalisierung und Stornierung von Belegen |
| Zahlungserfassung | Manuelle Erfassung von Zahlungseingängen und Erstattungen |
| Nummernkreisverwaltung | Lückenlose, transaktionssichere Nummernvergabe |
| PDF-Archivierung | Einmaliges Erstellen und unveränderliches Speichern von Belegen |
| Audit-Log | INSERT-only-Protokollierung aller rechnungsrelevanten Vorgänge |
2.2 Belegsystematik
Das Modul unterscheidet drei Belegtypen:
| Typ | Bezeichnung | Nummernkreis |
|---|---|---|
deposit | Anzahlungsrechnung | Konfigurierbar (z.B. ANZ-JJJJ-NNNN) |
final | Schlussrechnung | Konfigurierbar (z.B. RE-JJJJ-NNNN) |
cancellation | Stornorechnung | Konfigurierbar (z.B. STO-JJJJ-NNNN) |
2.3 Rechnungsstatus
| Status | Bedeutung | Änderbar? |
|---|---|---|
draft | Entwurf | Ja – Inhalt und Positionen veränderbar |
issued | Finalisiert | Nein – GoBD-geschützt, unveränderlich |
cancelled | Storniert | Nein – unveränderlich; Stornorechnung wurde erstellt |
3. Grundsatz der Unveränderbarkeit (GoBD § 146 AO)
3.1 Schutz auf Datenbankebene
Finalisierte Rechnungen (status = issued) und stornierte Rechnungen (status = cancelled) sind durch technische Maßnahmen auf Anwendungsebene gegen unberechtigte Änderungen geschützt:
- Service-Layer-Guard: Der
InvoiceIssuanceServiceund alle Controller prüfen den Status vor jeder Schreiboperation. Schreibzugriffe aufinvoicesundinvoice_itemsmit Statusissuedodercancelledwerden mit einer Exception abgelehnt. - Getrennte Positionen: Beim Finalisieren werden die zugehörigen
folio_itemsininvoice_itemskopiert. Diese Kopie ist eine eigenständige, unveränderliche Tabelle. Diefolio_itemskönnen weiterhin existieren, aberinvoice_itemssind nach dem Issuen nicht mehr veränderbar.
3.2 API-Schutz
Alle schreibenden API-Operationen auf Rechnungen prüfen den Status:
PUT /billing/invoices/{id}– nur beistatus = draftDELETE /billing/invoices/{id}– nur beistatus = draftPOST /billing/invoices/{id}/issue– nur beistatus = draftPOST /billing/invoices/{id}/cancel– nur beistatus = issued
Anfragen, die einen unzulässigen Statusübergang fordern, werden mit HTTP 403 abgewiesen.
3.3 Stornoverfahren statt Löschung
Eine finalisierte Rechnung kann nicht gelöscht werden. Korrekturen erfolgen ausschließlich durch das Stornoverfahren:
- Die zu korrigierende Rechnung wird storniert (
status → cancelled) - Automatisch wird eine Stornorechnung (
type = cancellation) mit gespiegelten negativen Positionen erstellt und sofort finalisiert - Beide Rechnungen (Original und Storno) verbleiben dauerhaft im System
Dieses Verfahren entspricht dem kaufmännischen Stornoprinzip und sichert die lückenlose Nachvollziehbarkeit des Buchungsgeschehens.
4. Lückenlose Rechnungsnummernvergabe (GoBD Rn. 36)
4.1 Nummernkreismechanismus
Die Rechnungsnummernvergabe erfolgt ausschließlich in einer Datenbanktransaktion mit Zeilensperrung (SELECT ... FOR UPDATE):
- Tabelle
invoice_number_sequencesenthält pro Tenant, Belegtyp und Jahr einen Zähler - Vor der Nummernerstellung wird die entsprechende Zeile gesperrt
- Der Zähler wird inkrementiert und die neue Nummer berechnet
- Bei Rollback der Transaktion wird der Zähler nicht inkrementiert – es entstehen keine Nummernlücken durch abgebrochene Vorgänge
4.2 Nummernformat
Betreiber konfigurieren das Nummernformat als Sprintf-Template. Beispiel:
| Template | Jahr | Zähler | Ergebnis |
|---|---|---|---|
RE-%d-%04d | 2026 | 1 | RE-2026-0001 |
RE-%d-%04d | 2026 | 42 | RE-2026-0042 |
Der Platzhalter %d wird durch das Ausstellungsjahr ersetzt, %04d durch den vierstelligen, mit führenden Nullen aufgefüllten Zähler.
4.3 Jährlicher Reset
Pro Belegtyp kann ein jährlicher Reset des Zählers konfiguriert werden. Bei aktiviertem Reset beginnt der Zähler am 1. Januar eines neuen Jahres bei 1. Der Zähler des Vorjahres bleibt gespeichert und ist jederzeit nachvollziehbar.
4.4 Konsistenzprüfung
Ein geplanter Hintergrundjob prüft regelmäßig, ob Nummernlücken vorhanden sind, und protokolliert Abweichungen im System-Log. Die Prüfung ist nicht-destruktiv und dient der Erkennung von Systemanomalien.
5. PDF-Persistenz und Manipulationsschutz (GoBD Rn. 106)
5.1 Einmaliges Erstellen und Archivieren
Ein Rechnungs-PDF wird genau einmal erzeugt: im Moment der Finalisierung. Das PDF wird sofort im persistenten Storage des Tenant-Verzeichnisses gespeichert. Nach der Speicherung wird der SHA-256-Hashwert berechnet und in der Datenbank (invoices.pdf_hash) gespeichert.
5.2 Manipulationserkennung
Der gespeicherte pdf_hash ermöglicht die Erkennung nachträglicher Manipulation des archivierten PDFs. Bei jedem Abruf kann der Hash des gespeicherten Dokuments mit dem gespeicherten Wert verglichen werden.
5.3 Inhalt des archivierten PDFs
Das archivierte PDF enthält zum Zeitpunkt der Ausstellung eingefrorene Daten:
recipient_snapshot– Empfängeranschrift (eingefroren beim Finalisieren)tenant_settings_snapshot– Absenderangaben, Bankdaten, Logo-Pfad (eingefroren beim Finalisieren)invoice_items– alle Rechnungspositionen mit eingefrorenem Steuersatz (tax_rate_value)
Änderungen an Stammdaten (z.B. neue Firmenadresse) berühren archivierte Rechnungen nicht.
5.4 Steuersatz-Snapshot
Der auf einer Position angewendete Mehrwertsteuersatz wird in invoice_items.tax_rate_value als Dezimalzahl eingefroren. Selbst wenn der Betreiber den Steuersatz in den Stammdaten ändert, zeigt die historische Rechnung immer den zum Ausstellungszeitpunkt gültigen Satz.
6. Audit-Log (GoBD Rn. 120)
6.1 Umfang der Protokollierung
Alle rechnungsrelevanten Vorgänge werden in der Tabelle invoice_audit_log protokolliert. Protokolliert werden mindestens:
- Erstellung einer Rechnung (Statusübergang
→ draft) - Finalisierung einer Rechnung (Statusübergang
draft → issued) - Stornierung einer Rechnung (Statusübergang
issued → cancelled) - Erstellung einer Stornorechnung
- Erstellung, Änderung und Löschung von Zahlungen und Zahlungsallokationen
Jeder Log-Eintrag enthält Zeitstempel (UTC), auslösenden Benutzer (UUID) und den Grund der Aktion.
6.2 Schutz des Audit-Logs
Das Audit-Log ist INSERT-only. Auf Datenbankebene blockiert ein Trigger UPDATE- und DELETE-Operationen auf invoice_audit_log. Damit ist das Protokoll nachträglich nicht veränderbar.
6.3 Aufbewahrung
Einträge im Audit-Log unterliegen der gesetzlichen Mindestaufbewahrungspflicht von 10 Jahren (§ 147 AO). Das System setzt keinen TTL (Time-to-Live) für Audit-Log-Einträge. Eine Löschung von Audit-Log-Einträgen ist systemseitig nicht vorgesehen.
7. Aufbewahrungspflicht und Archivierung (§ 147 AO)
7.1 Aufbewahrungsfristen
| Dokumenttyp | Aufbewahrungspflicht |
|---|---|
| Rechnungen (issued) | 10 Jahre |
| Stornorechnungen (cancellation) | 10 Jahre |
| Audit-Log-Einträge | 10 Jahre |
| Archivierte PDFs | 10 Jahre |
7.2 Technische Maßnahmen gegen vorzeitige Löschung
- Datenbankmigrationen: Die
down()-Methode von Billing-Migrationen darf bestehende Rechnungs-Daten nicht vernichten - Soft-Delete für Buchungen: Wenn eine Buchung gelöscht wird, bleiben das zugehörige Folio und alle Rechnungen im System sichtbar und abrufbar
- Systembefehle (z.B.
php artisan tenant:drop) prüfen vor der Ausführung, ob Billing-Daten vorhanden sind, und verweigern ggf. die Ausführung ohne vorherigen Export
7.3 Verantwortlichkeit des Betreibers
Die gesetzliche Aufbewahrungspflicht liegt beim Betreiber des Campingplatzes als Unternehmer im Sinne des Steuerrechts. Run a Campsite stellt die technischen Mittel zur Verfügung; die kaufmännische und steuerrechtliche Verantwortung verbleibt beim Betreiber.
Der Betreiber ist verantwortlich für:
- Regelmäßige Datensicherungen (zusätzlich zur plattformseitigen Datenhaltung)
- Einhaltung der Aufbewahrungsfristen auch bei Vertragsende (Export vor Kündigung)
- Vollständige und korrekte Ersteinrichtung der Billing-Stammdaten (Firmenadresse, USt-ID, Nummernformat)
8. Stornoverfahren im Detail (GoBD Rn. 118)
8.1 Manuelle Stornierung
Anlass: Fehler in einer ausgestellten Rechnung (falscher Betrag, falscher Empfänger, falsche Positionen).
- Betreiber wählt die fehlerhafte Rechnung im System aus
- Betreiber löst die Stornierung aus und wählt den Stornierungsgrund (
manual_correctionodererror) - Das System setzt die Original-Rechnung auf
cancelledund erstellt automatisch eine Stornorechnung (type = cancellation,reason = manual_correctionbzw.error) - Die Stornorechnung enthält gespiegelte negative Positionen der Original-Rechnung
- Die Stornorechnung wird sofort finalisiert (erhält Rechnungsnummer, PDF wird erstellt)
- Betreiber erstellt anschließend eine neue, korrigierte Rechnung
8.2 Stornierung bei Buchungsänderung
Anlass: Eine Buchung mit bereits finalisierter Rechnung muss inhaltlich geändert werden (z.B. Verlängerung, Parzellenänderung, Preiskorrektur).
- Betreiber bearbeitet die Buchung im Dashboard
- Das System prüft (
GET /billing/bookings/{id}/invoice-guard), ob finalisierte Rechnungen vorliegen - Bei vorhandenen finalisierten Rechnungen: System zeigt GoBD-Hinweis-Dialog mit den betroffenen Rechnungsnummern
- Betreiber bestätigt die Stornierung
- System storniert alle ISSUED-Rechnungen mit
reason = booking_changeund erstellt Stornorechnungen - System führt die Buchungsänderung durch
- Betreiber erstellt eine neue Rechnung auf Basis der aktualisierten Buchungsdaten
Dieser Schritt ist nicht überspringbar. Eine Buchungsänderung bei vorhandenen finalisierten Rechnungen ohne vorherige Stornierung ist technisch nicht möglich.
Hinweis-Banner bei nachträglicher Abweichung:
Wenn eine Buchung nach dem Ausstellen der Rechnung preisrelevant geändert wurde (z.B. über API oder Nachkorrektur), erscheint im Rechnungen-Tab ein gelber Hinweis-Banner:
⚠️ „Buchung weicht von der ausgestellten Rechnung ab — Die Buchung wurde nach Ausstellung der Schlussrechnung preisrelevant geändert."
Der Betreiber kann dann über den Knopf „Aus Buchung neu erstellen" an der ausgestellten Rechnung manuell eine GoBD-konforme Stornierung + Neuanlage auslösen (kein vollautomatischer Storno – das liegt in der Betreiber-Verantwortung). Das ist die bewusste Entscheidung: Automatische GoBD-Stornos ohne Betreiber-Bestätigung sind nicht vorgesehen.
Notiere Buchungsänderungen nach Rechnungsausstellung in deiner Verfahrensdokumentation.
8.3 Automatische Stornierung bei Online-Storno
Anlass: Ein Gast storniert seine Buchung selbst über das Buchungsportal.
- Gast initiiert den Storno über das Gästebuchungsportal
- Das System berechnet die Stornogebühr anhand der konfigurierten Stornierungsrichtlinie
IssueCancellationInvoicesListenererstellt automatisch:- Eine Stornorechnung zur ursprünglichen Schlussrechnung (falls bereits ausgestellt)
- Eine Gebührenrechnung für die Stornogebühr (sofern eine Gebühr anfällt)
- Beide Rechnungen werden sofort finalisiert (ISSUED) und per E-Mail an den Gast versendet (bei aktiviertem Auto-Send)
Der Stornierungsgrund ist in diesem Fall online_cancel.
9. Belegerstellung und Beleginhalt (GoBD Rn. 39 ff.)
9.1 Pflichtangaben auf Rechnungen (§ 14 UStG)
Das System stellt sicher, dass beim Finalisieren folgende Angaben auf der Rechnung vorhanden sind:
| Pflichtangabe | Quelle im System |
|---|---|
| Vollständiger Name und Anschrift des leistenden Unternehmers | billing_settings.company_name + Adressfelder |
| USt-ID oder Steuernummer | billing_settings.vat_id / billing_settings.tax_number |
| Name und Anschrift des Leistungsempfängers | recipient_snapshot (eingefroren beim Finalisieren) |
| Menge und Art der Leistung | invoice_items.description, invoice_items.quantity |
| Zeitpunkt der Leistung | Buchungszeitraum (check_in bis check_out) |
| Entgelt und Steuerbetrag | invoice_items.unit_price_cents, invoice_items.total_cents, tax_rate_value |
| Angewendeter Steuersatz | invoice_items.tax_rate_value (eingefroren) |
| Ausstellungsdatum | invoices.issued_at |
| Rechnungsnummer | invoices.number (lückenlos vergeben) |
Hinweis für Betreiber: Wenn
vat_idundtax_numberbeide leer sind, kann das System die Rechnung zwar technisch finalisieren, aber die steuerrechtlichen Pflichtangaben nach § 14 UStG fehlen. Der Betreiber ist verantwortlich dafür, seine Billing-Stammdaten vollständig zu pflegen.
9.2 Belegarten
Das System unterscheidet drei Belegarten entsprechend GoBD und UStG:
| Belegart | Anlass | GoBD-Relevanz |
|---|---|---|
Anzahlungsrechnung (deposit) | Vorauszahlung vor dem Aufenthalt | Beleg über anzahlungspflichtige Leistung |
Schlussrechnung (final) | Abrechnung nach dem Aufenthalt | Hauptbeleg; enthält ggf. Anzahlungsabzug |
Stornorechnung (cancellation) | Korrektur oder Stornierung | Gegenbuchung zur Original-Rechnung; muss auf Original verweisen |
10. Technische Sicherungsmaßnahmen – Zusammenfassung
| Maßnahme | Technische Umsetzung |
|---|---|
| Unveränderlichkeit ausgestellter Rechnungen | Service-Layer-Guard; HTTP 403 bei unzulässigen Schreiboperationen |
| Unveränderlichkeit der Rechnungspositionen | invoice_items werden beim Issuen als separate Kopie angelegt; keine UPDATE/DELETE nach dem Issuen |
| Lückenlose Nummernvergabe | DB-Transaktion mit SELECT ... FOR UPDATE auf invoice_number_sequences |
| Steuersatz-Snapshot | invoice_items.tax_rate_value wird beim Issuen eingefroren |
| Empfänger- und Absender-Snapshot | recipient_snapshot und tenant_settings_snapshot werden beim Issuen eingefroren |
| PDF-Archivierung | PDF wird genau einmal beim Issuen erstellt und persistiert gespeichert |
| Manipulationsschutz PDF | SHA-256-Hash des PDFs in invoices.pdf_hash gespeichert |
| Audit-Log | INSERT-only; DB-Trigger blockiert UPDATE/DELETE auf invoice_audit_log |
| Aufbewahrung | Kein TTL auf Rechnungen und Audit-Log; Soft-Delete schützt Rechnungen bei Buchungslöschung |
| Storno statt Löschung | Finalisierte Rechnungen können nicht gelöscht werden; Korrektur nur durch Stornoverfahren |
| GoBD-Guard | Buchungsänderungen mit bestehenden ISSUED-Rechnungen sind ohne vorherige Stornierung technisch blockiert |
11. Verantwortlichkeiten
| Aufgabe | Verantwortung |
|---|---|
| Technischer Betrieb der Plattform | Run a Campsite (Plattformbetreiber) |
| Korrekte Ersteinrichtung der Billing-Stammdaten | Campingplatzbetreiber |
| Pflege und Korrektheit der Rechnungsinhalte | Campingplatzbetreiber |
| Einhaltung der Aufbewahrungsfristen | Campingplatzbetreiber |
| Datensicherung und Export vor Vertragsende | Campingplatzbetreiber |
| Steuerliche Beratung | Steuerberater des Campingplatzbetreibers |
12. Änderungshistorie
| Version | Datum | Änderung |
|---|---|---|
| 1.0 | April 2026 | Erstfassung nach Implementierung des Billing-Moduls |
| 1.1 | Mai 2026 | Abschnitt 8.2: Hinweis-Banner bei nachträglicher Buchungsabweichung + manueller „Aus Buchung neu erstellen"-Weg ergänzt |