Skip to content

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:

KomponenteBeschreibung
Folio-VerwaltungGästekonto pro Buchung; verwaltet offene Positionen
RechnungsverwaltungErstellung, Finalisierung und Stornierung von Belegen
ZahlungserfassungManuelle Erfassung von Zahlungseingängen und Erstattungen
NummernkreisverwaltungLückenlose, transaktionssichere Nummernvergabe
PDF-ArchivierungEinmaliges Erstellen und unveränderliches Speichern von Belegen
Audit-LogINSERT-only-Protokollierung aller rechnungsrelevanten Vorgänge

2.2 Belegsystematik

Das Modul unterscheidet drei Belegtypen:

TypBezeichnungNummernkreis
depositAnzahlungsrechnungKonfigurierbar (z.B. ANZ-JJJJ-NNNN)
finalSchlussrechnungKonfigurierbar (z.B. RE-JJJJ-NNNN)
cancellationStornorechnungKonfigurierbar (z.B. STO-JJJJ-NNNN)

2.3 Rechnungsstatus

StatusBedeutungÄnderbar?
draftEntwurfJa – Inhalt und Positionen veränderbar
issuedFinalisiertNein – GoBD-geschützt, unveränderlich
cancelledStorniertNein – 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 InvoiceIssuanceService und alle Controller prüfen den Status vor jeder Schreiboperation. Schreibzugriffe auf invoices und invoice_items mit Status issued oder cancelled werden mit einer Exception abgelehnt.
  • Getrennte Positionen: Beim Finalisieren werden die zugehörigen folio_items in invoice_items kopiert. Diese Kopie ist eine eigenständige, unveränderliche Tabelle. Die folio_items können weiterhin existieren, aber invoice_items sind 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 bei status = draft
  • DELETE /billing/invoices/{id} – nur bei status = draft
  • POST /billing/invoices/{id}/issue – nur bei status = draft
  • POST /billing/invoices/{id}/cancel – nur bei status = 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:

  1. Die zu korrigierende Rechnung wird storniert (status → cancelled)
  2. Automatisch wird eine Stornorechnung (type = cancellation) mit gespiegelten negativen Positionen erstellt und sofort finalisiert
  3. 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):

  1. Tabelle invoice_number_sequences enthält pro Tenant, Belegtyp und Jahr einen Zähler
  2. Vor der Nummernerstellung wird die entsprechende Zeile gesperrt
  3. Der Zähler wird inkrementiert und die neue Nummer berechnet
  4. 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:

TemplateJahrZählerErgebnis
RE-%d-%04d20261RE-2026-0001
RE-%d-%04d202642RE-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

DokumenttypAufbewahrungspflicht
Rechnungen (issued)10 Jahre
Stornorechnungen (cancellation)10 Jahre
Audit-Log-Einträge10 Jahre
Archivierte PDFs10 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).

  1. Betreiber wählt die fehlerhafte Rechnung im System aus
  2. Betreiber löst die Stornierung aus und wählt den Stornierungsgrund (manual_correction oder error)
  3. Das System setzt die Original-Rechnung auf cancelled und erstellt automatisch eine Stornorechnung (type = cancellation, reason = manual_correction bzw. error)
  4. Die Stornorechnung enthält gespiegelte negative Positionen der Original-Rechnung
  5. Die Stornorechnung wird sofort finalisiert (erhält Rechnungsnummer, PDF wird erstellt)
  6. 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).

  1. Betreiber bearbeitet die Buchung im Dashboard
  2. Das System prüft (GET /billing/bookings/{id}/invoice-guard), ob finalisierte Rechnungen vorliegen
  3. Bei vorhandenen finalisierten Rechnungen: System zeigt GoBD-Hinweis-Dialog mit den betroffenen Rechnungsnummern
  4. Betreiber bestätigt die Stornierung
  5. System storniert alle ISSUED-Rechnungen mit reason = booking_change und erstellt Stornorechnungen
  6. System führt die Buchungsänderung durch
  7. 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.

  1. Gast initiiert den Storno über das Gästebuchungsportal
  2. Das System berechnet die Stornogebühr anhand der konfigurierten Stornierungsrichtlinie
  3. IssueCancellationInvoicesListener erstellt automatisch:
    • Eine Stornorechnung zur ursprünglichen Schlussrechnung (falls bereits ausgestellt)
    • Eine Gebührenrechnung für die Stornogebühr (sofern eine Gebühr anfällt)
  4. 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:

PflichtangabeQuelle im System
Vollständiger Name und Anschrift des leistenden Unternehmersbilling_settings.company_name + Adressfelder
USt-ID oder Steuernummerbilling_settings.vat_id / billing_settings.tax_number
Name und Anschrift des Leistungsempfängersrecipient_snapshot (eingefroren beim Finalisieren)
Menge und Art der Leistunginvoice_items.description, invoice_items.quantity
Zeitpunkt der LeistungBuchungszeitraum (check_in bis check_out)
Entgelt und Steuerbetraginvoice_items.unit_price_cents, invoice_items.total_cents, tax_rate_value
Angewendeter Steuersatzinvoice_items.tax_rate_value (eingefroren)
Ausstellungsdatuminvoices.issued_at
Rechnungsnummerinvoices.number (lückenlos vergeben)

Hinweis für Betreiber: Wenn vat_id und tax_number beide 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:

BelegartAnlassGoBD-Relevanz
Anzahlungsrechnung (deposit)Vorauszahlung vor dem AufenthaltBeleg über anzahlungspflichtige Leistung
Schlussrechnung (final)Abrechnung nach dem AufenthaltHauptbeleg; enthält ggf. Anzahlungsabzug
Stornorechnung (cancellation)Korrektur oder StornierungGegenbuchung zur Original-Rechnung; muss auf Original verweisen

10. Technische Sicherungsmaßnahmen – Zusammenfassung

MaßnahmeTechnische Umsetzung
Unveränderlichkeit ausgestellter RechnungenService-Layer-Guard; HTTP 403 bei unzulässigen Schreiboperationen
Unveränderlichkeit der Rechnungspositioneninvoice_items werden beim Issuen als separate Kopie angelegt; keine UPDATE/DELETE nach dem Issuen
Lückenlose NummernvergabeDB-Transaktion mit SELECT ... FOR UPDATE auf invoice_number_sequences
Steuersatz-Snapshotinvoice_items.tax_rate_value wird beim Issuen eingefroren
Empfänger- und Absender-Snapshotrecipient_snapshot und tenant_settings_snapshot werden beim Issuen eingefroren
PDF-ArchivierungPDF wird genau einmal beim Issuen erstellt und persistiert gespeichert
Manipulationsschutz PDFSHA-256-Hash des PDFs in invoices.pdf_hash gespeichert
Audit-LogINSERT-only; DB-Trigger blockiert UPDATE/DELETE auf invoice_audit_log
AufbewahrungKein TTL auf Rechnungen und Audit-Log; Soft-Delete schützt Rechnungen bei Buchungslöschung
Storno statt LöschungFinalisierte Rechnungen können nicht gelöscht werden; Korrektur nur durch Stornoverfahren
GoBD-GuardBuchungsänderungen mit bestehenden ISSUED-Rechnungen sind ohne vorherige Stornierung technisch blockiert

11. Verantwortlichkeiten

AufgabeVerantwortung
Technischer Betrieb der PlattformRun a Campsite (Plattformbetreiber)
Korrekte Ersteinrichtung der Billing-StammdatenCampingplatzbetreiber
Pflege und Korrektheit der RechnungsinhalteCampingplatzbetreiber
Einhaltung der AufbewahrungsfristenCampingplatzbetreiber
Datensicherung und Export vor VertragsendeCampingplatzbetreiber
Steuerliche BeratungSteuerberater des Campingplatzbetreibers

12. Änderungshistorie

VersionDatumÄnderung
1.0April 2026Erstfassung nach Implementierung des Billing-Moduls
1.1Mai 2026Abschnitt 8.2: Hinweis-Banner bei nachträglicher Buchungsabweichung + manueller „Aus Buchung neu erstellen"-Weg ergänzt