Billing API für europäisches B2B: was das Datenmodell abbilden muss
Eine österreichische GmbH kauft 50 Seats, die Rechnung geht korrekt mit Reverse-Charge-Hinweis raus. Im Mai reduziert der Kunde rückwirkend auf 40 Seats, und Ihr System erzeugt die Korrektur mit dem Steuerstatus von heute. Die USt-IdNr. ist seit April ungültig, also landet auf dem Korrekturbeleg plötzlich österreichische Umsatzsteuer, obwohl die Originalrechnung keine enthielt. Solche Fehler entstehen nicht im Code einer einzelnen Funktion. Sie entstehen, weil das Datenmodell der Billing API den Steuerstatus am Kunden speichert statt am Beleg.
Dieser Artikel beschreibt, welche Objekte und Felder eine Billing API für europäisches B2B abbilden muss, bevor über Endpunkte, SDKs oder Sandbox gesprochen wird. Wie Sie eine Plattform im Trial prüfen, behandelt der Beitrag zur API-basierten Abrechnungsplattform.
Kunde, Rechnungsempfänger und Steuerprofil sind drei Objekte
Viele Billing-APIs kennen genau ein customer-Objekt mit Name, E-Mail, Adresse und optional einer Steuernummer. Für B2C reicht das. Im B2B-Geschäft stecken in diesem einen Objekt mindestens drei Dinge mit unterschiedlicher Lebensdauer:
- die juristische Person, mit der der Vertrag besteht (Firmenname, Sitz, Registerangaben),
- der Rechnungsempfänger, also Adresse, Kostenstelle, Bestellnummer und Zustellweg (E-Mail, Portal, Peppol),
- das Steuerprofil: USt-IdNr., Prüfstatus, Land der Ansässigkeit, Steuerbehandlung.
Die Rechnungsadresse ändert sich, wenn die Buchhaltung des Kunden umzieht. Das Steuerprofil ändert sich, wenn eine Gesellschaft verschmolzen wird oder ihre USt-IdNr. verliert. Liegen beide im selben Feld-Set, überschreibt eine Adressänderung im Kundenportal womöglich Daten, die für bereits gestellte Rechnungen relevant sind.
Prüfen Sie deshalb, ob die API Rechnungskontakte und Steuerprofile als eigene Ressourcen mit Historie führt. Ein PATCH /customers/{id} darf keine bereits finalisierte Rechnung verändern, auch nicht indirekt über eine Referenz.
Die USt-IdNr. braucht ein Prüfprotokoll, kein Textfeld
Für eine grenzüberschreitende B2B-Leistung verlangt § 14a UStG auf der Rechnung die Angabe „Steuerschuldnerschaft des Leistungsempfängers“ sowie die USt-IdNr. von Leistendem und Empfänger. Ob Reverse Charge überhaupt greift, hängt davon ab, ob der Kunde als Unternehmer gilt, und dafür ist die gültige USt-IdNr. Ihr wichtigster Nachweis.
Die Nummer selbst ist dabei der unwichtigste Teil des Datensatzes. Wichtig ist, was Sie über die Prüfung wissen:
- Ergebnis der Abfrage im EU-System VIES (gültig, ungültig, Dienst nicht erreichbar),
- Zeitpunkt der Prüfung und, falls vorhanden, die Anfragekennung,
- zurückgemeldeter Name und Adresse, sofern der Mitgliedstaat sie liefert,
- Gültigkeitszeitraum, ab dem dieses Ergebnis für Rechnungen verwendet wird.
Der Status „Dienst nicht erreichbar“ ist kein Randfall. Wenn VIES für einen Mitgliedstaat zeitweise keine Antwort gibt, muss die API entscheiden können, ob die Rechnung als Entwurf wartet oder mit dem letzten gültigen Ergebnis finalisiert wird. Diese Regel gehört in die Konfiguration, nicht in einen Retry irgendwo im Worker. Details zur Automatisierung stehen im Beitrag VIES-Prüfung automatisieren.
Die Rechnung friert ihren Kontext ein
Eine finalisierte Rechnung ist ein Beleg. Sie muss bis zum Ende der Aufbewahrungsfrist genau so aussehen wie am Tag der Ausstellung, und die beträgt nach § 14b UStG acht Jahre, gerechnet ab Ende des Ausstellungsjahres. Deshalb sollte die Rechnung keine Live-Referenzen auf Kunde, Preis oder Steuerprofil enthalten, sondern Kopien davon.
Konkret heißt das: Beim Übergang von draft zu finalized kopiert die API Name und Adresse beider Parteien, die verwendeten USt-IdNrn., die Steuerbehandlung je Zeile, den Steuersatz und die Preisversion in die Rechnung. Ab diesem Moment ist das Objekt schreibgeschützt. Ein Endpunkt wie PATCH /invoices/{id} sollte nach der Finalisierung mit einem Fehler antworten, nicht stillschweigend speichern.
Dazu kommt die Rechnungsnummer. § 14 UStG verlangt eine fortlaufende Nummer, die einmalig vergeben wird. Für die API bedeutet das: Die Nummer entsteht erst bei der Finalisierung, nicht beim Anlegen des Entwurfs. Sonst erzeugen verworfene Entwürfe Lücken, die Ihr Steuerberater später erklären muss.
Korrekturbelege referenzieren das Original
Zurück zum Beispiel vom Anfang, mit erfundenen Beträgen:
| Beleg | Nummer | Positionen | Netto | Steuerbehandlung |
|---|---|---|---|---|
| Rechnung (März) | RE-2026-0412 | 50 Seats zu 40 € | 2.000,00 € | Reverse Charge, USt-IdNr. ATU… |
| Korrektur (Mai) | RE-2026-0587 | −10 Seats zu 40 € | −400,00 € | Reverse Charge, aus RE-2026-0412 übernommen |
Die Korrektur bekommt eine eigene Nummer aus demselben Nummernkreis, verweist auf RE-2026-0412 und übernimmt deren Steuerbehandlung, Steuersatz und USt-IdNrn. aus dem Snapshot. Sie fragt nicht das aktuelle Steuerprofil des Kunden ab. Der neue VIES-Status gilt erst für Rechnungen über Leistungen nach der Statusänderung. Weil es sich um eine innergemeinschaftliche B2B-Leistung handelt, muss die Korrektur auch in der Zusammenfassenden Meldung nach § 18a UStG berücksichtigt werden. Die API sollte Korrekturen daher mit Bezug auf das Original und dessen Leistungszeitraum exportieren.
Ein Hinweis zur Benennung: Im deutschen Umsatzsteuerrecht ist eine „Gutschrift“ die Abrechnung durch den Leistungsempfänger (§ 14 Abs. 2 UStG), also Self-Billing. Viele deutsche Teams nennen den Korrekturbeleg deshalb „Rechnungskorrektur“ oder „Stornorechnung“, um Verwechslungen zu vermeiden. Eine Billing API sollte den Dokumenttyp als Feld führen (invoice, credit_note, cancellation) und die Beschriftung pro Sprache und Land konfigurierbar machen.
Mehrere eigene Gesellschaften ändern die Steuerfrage
Sobald Sie neben der deutschen GmbH eine niederländische B.V. oder eine österreichische Tochter betreiben, hängt die Steuerbehandlung nicht mehr allein vom Kunden ab. Ein niederländischer Unternehmerkunde der deutschen GmbH erhält eine Reverse-Charge-Rechnung. Derselbe Kunde, beliefert von der niederländischen B.V., erhält eine Rechnung mit niederländischer Umsatzsteuer. Die Steuerlogik ist eine Funktion aus dem Paar leistende Gesellschaft und Kunde.
Für das Datenmodell folgen daraus vier Anforderungen:
- Jede Rechnung, jede Korrektur und jedes Abonnement verweist auf genau eine leistende Gesellschaft (
seller_entity_id). - Jede Gesellschaft hat eigene Nummernkreise, eigene USt-IdNr. und eigene Bankverbindung, bei SEPA-Lastschrift auch eine eigene Gläubiger-ID.
- Ein Abonnement kann die Gesellschaft nicht stillschweigend wechseln. Ein Wechsel beendet den Vertrag bei der einen und beginnt ihn bei der anderen.
- Exporte für die Buchhaltung laufen pro Gesellschaft, weil jede ihre eigenen Bücher führt.
Fehlt die Gesellschaft als Dimension, landet die Rechnung der B.V. im Nummernkreis der GmbH. Das fällt meist erst auf, wenn der erste Jahresabschluss der Tochter vorbereitet wird.
Ein Datenmodell zum Abgleichen
Die folgende Skizze ist kein Schema zum Kopieren, sondern eine Prüfliste in Code-Form. Legen Sie sie neben die API-Referenz eines Anbieters oder neben Ihr eigenes Schema und markieren Sie, was fehlt.
SellerEntity id, legal_name, country, vat_id, number_series[], bank_account, creditor_id
Customer id, legal_name, registered_address, seller_entity_id
BillingContact id, customer_id, address, po_number, delivery_channel, valid_from
TaxProfile id, customer_id, vat_id, vies_result, checked_at, request_id, valid_from
Invoice id, number (null bis finalized), seller_entity_id, status,
parties_snapshot, tax_treatment, service_period, price_version_id
InvoiceLine invoice_id, description, quantity, unit_price, net, tax_rate, tax_category
CorrectionDoc id, number, type, corrects_invoice_id, lines[], reason, snapshot_from_original
Drei Felder fehlen in generischen APIs am häufigsten: seller_entity_id, service_period auf der Rechnung und die Referenz corrects_invoice_id. Ohne Leistungszeitraum lässt sich eine Korrektur dem richtigen Meldezeitraum nicht zuordnen, ohne Referenz ist sie für die Prüfung nur eine negative Rechnung ohne Herkunft.
Fünf Aufrufe, die Sie vor der Integration testen sollten
Bevor Sie eine Billing API anbinden oder ein eigenes Modell bauen, spielen Sie diese Fälle durch. Jeder lässt sich mit Testdaten in einer Testumgebung prüfen:
- Kunde mit gültiger USt-IdNr. anlegen, Rechnung finalisieren, danach die USt-IdNr. auf ungültig setzen. Ändert sich die finalisierte Rechnung? Sie darf es nicht.
- Rechnung korrigieren, nachdem sich der Steuerstatus geändert hat. Übernimmt der Korrekturbeleg die Steuerbehandlung des Originals?
- Drei Entwürfe anlegen, zwei verwerfen, einen finalisieren. Ist die Nummernfolge lückenlos?
- Denselben Kunden über zwei leistende Gesellschaften abrechnen. Getrennte Nummernkreise, korrekte Steuerbehandlung je Gesellschaft?
- Rechnungsadresse ändern und eine alte Rechnung als PDF neu erzeugen. Steht dort die alte Adresse?
Fällt einer dieser Tests durch, verschiebt sich die Arbeit in Ihre Buchhaltung. Kontier behandelt Reverse Charge, SEPA und E-Rechnung als Teil des Kernprozesses, nicht als Erweiterung; gegen die fünf Fälle können Sie die Kontier-API selbst prüfen.
Kein Steuer- oder Rechtsrat. Dieser Beitrag beschreibt die Rechtslage und Praxis allgemein. Für Ihren Einzelfall fragen Sie Ihre Steuerberatung. Stand: