Zum Hauptinhalt springen
Neu E-Rechnungspflicht ab 2027: Kontier stellt XRechnung und ZUGFeRD nativ aus E-Rechnungspflicht 2027: XRechnung nativ

Billing API für europäisches B2B: was das Datenmodell abbilden muss

6 Min. Lesezeit Kontier-Redaktion

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:

  1. Jede Rechnung, jede Korrektur und jedes Abonnement verweist auf genau eine leistende Gesellschaft (seller_entity_id).
  2. Jede Gesellschaft hat eigene Nummernkreise, eigene USt-IdNr. und eigene Bankverbindung, bei SEPA-Lastschrift auch eine eigene Gläubiger-ID.
  3. Ein Abonnement kann die Gesellschaft nicht stillschweigend wechseln. Ein Wechsel beendet den Vertrag bei der einen und beginnt ihn bei der anderen.
  4. 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:

  1. 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.
  2. Rechnung korrigieren, nachdem sich der Steuerstatus geändert hat. Übernimmt der Korrekturbeleg die Steuerbehandlung des Originals?
  3. Drei Entwürfe anlegen, zwei verwerfen, einen finalisieren. Ist die Nummernfolge lückenlos?
  4. Denselben Kunden über zwei leistende Gesellschaften abrechnen. Getrennte Nummernkreise, korrekte Steuerbehandlung je Gesellschaft?
  5. 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:

Demo vereinbaren

Technische Demo, 15 Minuten mit einem Engineer: zu Ihrem Preismodell und Ihren Steueranforderungen.

Wie wir Ihre Angaben verarbeiten: Datenschutzerklärung.

Lieber per E-Mail? contact@frontieralgorithmics.com

Nachricht an Kontier

Schreiben Sie uns direkt hier. Wir antworten per E-Mail, in der Regel innerhalb eines Werktags.

Wie wir Ihre Angaben verarbeiten: Datenschutzerklärung.

Persönliche Einladung · 30 Tage

Kontier 30 Tage testen, mit persönlicher Einladung

Wir richten Ihnen einen Testzugang ein und senden die Einladung persönlich. Ohne Kreditkarte, der Test endet automatisch.

Ihre Einladung kommt innerhalb von 48 Stunden an die angegebene Adresse, von einem Menschen, nicht automatisch.

Getrennt vom öffentlichen 14-Tage-Test, der auf der Preisseite mit Karte startet.