E-Rechnung

XRechnung implementieren: Schritt-für-Schritt Anleitung für Entwickler

15. Juli 202612 Min.

Warum XRechnung implementieren — und wer muss ab wann?

Empfangen müssen deutsche Unternehmen E-Rechnungen bereits seit dem 1. Januar 2025. Beim Versand läuft die Übergangsregelung des § 27 Abs. 38 UStG gestaffelt aus: Ab dem 1. Januar 2027 entfällt sie für Unternehmen mit mehr als 800.000 Euro Gesamtumsatz im Vorjahr, ab dem 1. Januar 2028 für alle übrigen. Maßgeblich ist der Umsatz des Rechnungsstellers, nicht des Empfängers. Details zu den Fristen klärt XRechnung-Pflicht 2027.

XRechnung ist der deutsche Standard nach EN 16931 — und das Pflichtformat für Rechnungen an öffentliche Auftraggeber. Wer Software für Rechnungsstellung entwickelt, kommt an XRechnung nicht vorbei.

Dieser Artikel zeigt Ihnen als Entwickler den direkten Weg: XML-Struktur verstehen, Pflichtfelder korrekt befüllen, gegen EN 16931 validieren und per API automatisieren. Stand: Juli 2026, geprüft gegen die gültige Spezifikation XRechnung 3.0.2. Den organisatorischen Rahmen zeigt der Leitfaden dazu, wie Steuerberater ihre Mandanten auf die E-Rechnung umstellen.

1. UBL oder CII: Welche XML-Syntax soll ich wählen?

XRechnung unterstützt zwei XML-Syntaxen. Beide sind gleichwertig gültig — die Wahl hängt von Ihrem Anwendungsfall ab.

UBL 2.1 (Universal Business Language)

UBL ist der international verbreitetere Standard. Die Rechnungsdaten liegen im Namespace urn:oasis:names:specification:ubl:schema:xsd:Invoice-2. Das Root-Element ist <Invoice>.

<?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
         xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
         xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
  <cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0</cbc:CustomizationID>
  <cbc:ID>RE-2026-001</cbc:ID>
  <cbc:IssueDate>2026-03-22</cbc:IssueDate>
  <cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
  <cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>
  <cac:AccountingSupplierParty>
    <!-- Rechnungssteller -->
  </cac:AccountingSupplierParty>
  <cac:AccountingCustomerParty>
    <!-- Rechnungsempfänger -->
  </cac:AccountingCustomerParty>
  <cac:LegalMonetaryTotal>
    <!-- Summen -->
  </cac:LegalMonetaryTotal>
  <cac:InvoiceLine>
    <!-- Rechnungspositionen -->
  </cac:InvoiceLine>
</Invoice>

UN/CEFACT CII (Cross-Industry Invoice)

CII ist die UN-Syntax, die auch ZUGFeRD verwendet. Das Root-Element ist <CrossIndustryInvoice>. Die Daten sind hierarchisch in Trade-Blöcke gegliedert.

<?xml version="1.0" encoding="UTF-8"?>
<rsm:CrossIndustryInvoice
    xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
    xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
    xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
  <rsm:ExchangedDocumentContext>
    <ram:GuidelineSpecifiedDocumentContextParameter>
      <ram:ID>urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0</ram:ID>
    </ram:GuidelineSpecifiedDocumentContextParameter>
  </rsm:ExchangedDocumentContext>
  <rsm:ExchangedDocument>
    <ram:ID>RE-2026-001</ram:ID>
    <ram:TypeCode>380</ram:TypeCode>
    <ram:IssueDateTime>
      <udt:DateTimeString format="102">20260322</udt:DateTimeString>
    </ram:IssueDateTime>
  </rsm:ExchangedDocument>
  <rsm:SupplyChainTradeTransaction>
    <!-- Handelspartner, Lieferung, Zahlung -->
  </rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>

UBL oder CII?

UBL eignet sich, wenn Sie international agieren oder PEPPOL nutzen. CII ist die Wahl, wenn Sie auch ZUGFeRD unterstützen wollen — ZUGFeRD verwendet ausschließlich CII.

2. Welche Pflichtfelder braucht eine XRechnung?

EN 16931 definiert rund 160 semantische Datenfelder (BT) in gut 30 Gruppen (BG). Nicht alle sind Pflicht. Die folgende Tabelle zeigt die Mindestanforderungen für eine gültige XRechnung:

BT-Nr.FeldBeschreibungBeispielwert
BT-1RechnungsnummerEindeutige Kennung der RechnungRE-2026-001
BT-2RechnungsdatumAusstellungsdatum2026-03-22
BT-3RechnungsartUNTDID 1001 Code380 (Rechnung)
BT-5WährungISO 4217 WährungscodeEUR
BT-27VerkäufernameName des RechnungsstellersMuster GmbH
BT-44KäufernameName des RechnungsempfängersKunde AG
BT-109Rechnungsbetrag ohne MwSt.Gesamtbetrag exkl. MwSt.1000.00
BT-110MwSt.-BetragSumme der Umsatzsteuer190.00
BT-112Rechnungsbetrag mit MwSt.Gesamtbetrag inkl. MwSt.1190.00
BT-115Fälliger BetragZu zahlender Betrag1190.00

Welche Felder verlangt XRechnung zusätzlich (BR-DE)?

Die deutschen Geschäftsregeln (BR-DE) verschärfen EN 16931. Die wichtigsten:

  • Buyer reference (BT-10): BR-DE-15 macht dieses Feld in jeder XRechnung zur Pflicht — auch im B2B.
  • Zahlungsdaten (BG-16): BR-DE-1 verlangt Angaben zu „PAYMENT INSTRUCTIONS", etwa die IBAN des Verkäufers bei Überweisung.
  • E-Mail-Adresse (BT-43): BR-DE-7 verlangt die Kontakt-E-Mail des Verkäufers.
  • Zahlungsbedingungen (BT-20): Freitext für Zahlungskonditionen.

Leitweg-ID: nur bei Behörden, nicht im B2B

Hier verwechseln viele Implementierungen zwei Dinge. BT-10 ist ein generisches Käufer-Referenzfeld. Die Leitweg-ID ist kein eigenes Feld, sondern ein Inhalt, den Bund, Länder und Kommunen in BT-10 erwarten (B2G und G2G). Format: 04011000-12345-67.

Im B2B gibt es in der Regel keine Leitweg-ID. BT-10 bleibt trotzdem Pflicht — dort steht dann die Referenz, die Ihr Kunde vorgibt, etwa eine Bestellnummer. Einzelne Länder und Kommunen geben abweichende Zuordnungsmuster vor; auch die gehören in BT-10.

3. Wie erzeuge ich eine XRechnung per API?

Statt XML manuell zu bauen, können Sie die E-Invoice API nutzen. Sie senden Rechnungsdaten als JSON — die API erzeugt valides XRechnung-XML.

API starten (Docker)

docker run -p 8000:8000 ghcr.io/jenslaufer/e-invoice:latest

XRechnung generieren (Python)

Dieses Beispiel erstellt eine vollständige XRechnung im UBL-Format:

import requests

invoice_data = {
    "invoice_number": "RE-2026-001",
    "issue_date": "2026-03-22",
    "due_date": "2026-04-21",
    "currency_code": "EUR",
    "invoice_type_code": "380",
    "buyer_reference": "04011000-12345-67",  # Leitweg-ID
    "seller": {
        "name": "Muster GmbH",
        "street": "Musterstraße 1",
        "city": "Berlin",
        "postal_code": "10115",
        "country_code": "DE",
        "tax_id": "DE123456789",
        "contact": {
            "email": "rechnung@muster.de"
        },
        "bank_account": {
            "iban": "DE89370400440532013000"
        }
    },
    "buyer": {
        "name": "Bundesministerium für Beispiele",
        "street": "Regierungsstraße 10",
        "city": "Berlin",
        "postal_code": "10117",
        "country_code": "DE"
    },
    "lines": [
        {
            "description": "Softwareentwicklung",
            "quantity": 10,
            "unit_code": "HUR",
            "unit_price": 100.00,
            "tax_category": "S",
            "tax_percent": 19.0
        }
    ],
    "payment_terms": "Zahlbar innerhalb von 30 Tagen"
}

# XRechnung als UBL generieren
response = requests.post(
    "http://localhost:8000/api/v1/invoices/xml",
    json=invoice_data,
    params={"syntax": "ubl"}
)

if response.status_code == 200:
    with open("rechnung.xml", "wb") as f:
        f.write(response.content)
    print("XRechnung erstellt: rechnung.xml")
else:
    print(f"Fehler: {response.json()}")

CII-Syntax verwenden

Für CII-Output ändern Sie nur den Parameter:

response = requests.post(
    "http://localhost:8000/api/v1/invoices/xml",
    json=invoice_data,
    params={"syntax": "cii"}
)

4. Wie validiere ich eine XRechnung gegen EN 16931?

Eine XRechnung muss fünf Validierungsschichten bestehen. Referenz ist der KoSIT-Validator mit der offiziellen Validator-Konfiguration — was der ablehnt, lehnt auch der Empfänger ab. Jede Schicht prüft unterschiedliche Aspekte:

SchichtPrüfungWerkzeug
1. SchemaXML-Struktur und DatentypenXSD-Validierung
2. EN 16931Europäische Geschäftsregeln (BR-*)Schematron
3. XRechnung CIUSDeutsche Geschäftsregeln (BR-DE-*)Schematron
4. BerechnungSummen, Steuern, RundungArithmetische Prüfung
5. SemantikCodelisten, Referenzen, KonsistenzGeschäftslogik

Validierung per API

# XRechnung validieren
with open("rechnung.xml", "rb") as f:
    xml_content = f.read()

response = requests.post(
    "http://localhost:8000/api/v1/invoices/validate",
    files={"file": ("rechnung.xml", xml_content, "application/xml")}
)

result = response.json()
print(f"Gültig: {result['valid']}")

if not result["valid"]:
    for error in result["errors"]:
        print(f"  [{error['rule']}] {error['message']}")

Eine typische Validierungsantwort bei Fehlern:

{
  "valid": false,
  "errors": [
    {
      "rule": "BR-DE-15",
      "message": "Das Element \"Buyer reference\" (BT-10) muss übermittelt werden.",
      "severity": "error",
      "location": "/Invoice"
    }
  ],
  "warnings": []
}

Validierung in die CI/CD-Pipeline integrieren

Validieren Sie generierte Rechnungen automatisch in Ihrer Pipeline:

# validate_invoices.py
import sys
import requests
import glob

api_url = "http://localhost:8000/api/v1/invoices/validate"
errors_found = False

for xml_file in glob.glob("output/*.xml"):
    with open(xml_file, "rb") as f:
        resp = requests.post(
            api_url,
            files={"file": (xml_file, f, "application/xml")}
        )
    result = resp.json()
    if not result["valid"]:
        errors_found = True
        print(f"FEHLER in {xml_file}:")
        for err in result["errors"]:
            print(f"  [{err['rule']}] {err['message']}")
    else:
        print(f"OK: {xml_file}")

sys.exit(1 if errors_found else 0)

5. Welche Fehler treten am häufigsten auf?

Diese Fehler treten bei der EN 16931 Implementierung am häufigsten auf. Welche Fehler im laufenden Betrieb zu Ablehnungen führen, zeigt Die häufigsten Fehler bei der E-Rechnung.

Fehler 1: Falsche CustomizationID

Die CustomizationID muss exakt stimmen. Die Regel BR-DE-21 prüft den Wert zeichengenau — eine Abweichung führt zur Ablehnung.

Zwei Stolperfallen: Seit XRechnung 3.0 lautet der Namensraum xeinkauf.de:kosit:xrechnung_. Ältere Anleitungen zeigen noch die 2.x-Form xoev-de:kosit:standard:xrechnung_ — die ist für 3.x ungültig. Und der Wert trägt nur Major- und Minor-Version: Auch bei Spezifikation 3.0.2 steht dort _3.0, nicht _3.0.2.

<!-- Falsch: ohne CIUS-Kennung -->
<cbc:CustomizationID>urn:cen.eu:en16931:2017</cbc:CustomizationID>

<!-- Falsch: 2.x-Namensraum in einer 3.x-Rechnung -->
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_3.0</cbc:CustomizationID>

<!-- Richtig (XRechnung 3.0.2) -->
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0</cbc:CustomizationID>

In CII steht derselbe String in rsm:ExchangedDocumentContext/ram:GuidelineSpecifiedDocumentContextParameter/ram:ID. Semantisch ist es BT-24 (Specification identifier).

Fehler 2: Steuerberechnung mit Rundungsfehlern

EN 16931 verlangt kaufmännische Rundung auf 2 Dezimalstellen. Fließkomma-Arithmetik führt zu Abweichungen.

# Falsch: Fließkomma-Fehler
tax = 100.05 * 0.19  # 19.0095000000000027...

# Richtig: Decimal verwenden
from decimal import Decimal, ROUND_HALF_UP
tax = (Decimal("100.05") * Decimal("0.19")).quantize(
    Decimal("0.01"), rounding=ROUND_HALF_UP
)  # Decimal('19.01')

Fehler 3: BT-10 nur bei Behördenrechnungen befüllen

Die Geschäftsregel BR-DE-15 verlangt BT-10 (Buyer reference) in jeder XRechnung — nicht nur bei B2G. Wer das Feld im B2B wegoptimiert, weil dort keine Leitweg-ID existiert, produziert eine ungültige Rechnung. Bei öffentlichen Auftraggebern muss zusätzlich der Inhalt stimmen: eine gültige Leitweg-ID.

Fehler 4: Datumsformat in CII

CII verwendet ein anderes Datumsformat als UBL. Häufiger Fehler: ISO-8601 statt CCYYMMDD.

<!-- Falsch in CII -->
<udt:DateTimeString format="102">2026-03-22</udt:DateTimeString>

<!-- Richtig in CII -->
<udt:DateTimeString format="102">20260322</udt:DateTimeString>

Fehler 5: Summen stimmen nicht überein

EN 16931 enthält arithmetische Regeln (BR-CO-*). Die Summen müssen exakt passen:

  • BR-CO-10: BT-106 (Summe Nettobeträge der Positionen) = Summe aller BT-131
  • BR-CO-13: BT-109 (Rechnungsbetrag ohne MwSt.) = Summe aller BT-131 − BT-107 + BT-108
  • BR-CO-15: BT-112 (Rechnungsbetrag mit MwSt.) = BT-109 + BT-110 (MwSt.-Betrag)
  • BR-CO-16: BT-115 (Fälliger Betrag) = BT-112 − BT-113 (bereits gezahlt) + BT-114 (Rundungsbetrag)

Zwei Details, die oft danebengehen: BT-107 und BT-108 sind bereits Summen auf Dokumentebene — die einzelnen Nachlässe stehen in BT-92, die einzelnen Zuschläge in BT-99. Und wer BT-114 in BR-CO-16 vergisst, bekommt genau dann einen Fehler, wenn gerundet wird.

Fehler 6: Falsche Unit-Codes

Mengeneinheiten stammen aus UN/ECE Recommendation 20 und Recommendation 21 — ausgewählt nach der in Rec 20, Intro 2.a) beschriebenen Methode. Codes aus Rec 21 tragen ein vorangestelltes X, etwa XPP (Packung). Wer nur in Rec 20 nachschlägt, findet die Verpackungscodes nicht. Häufige Codes:

CodeBedeutung
HURStunde
DAYTag
C62Stück (Einheit)
MONMonat
KWHKilowattstunde
TNETonne (metrisch)

Tipp: Validieren Sie jede generierte Rechnung vor dem Versand. Die E-Invoice API prüft alle 5 Schichten in einem Aufruf — Schema, EN 16931, BR-DE, Berechnung und Semantik.

6. Wie sieht eine vollständige Implementierung aus?

Das folgende Beispiel zeigt den vollständigen Workflow — Rechnung erstellen, validieren und speichern:

import requests
from pathlib import Path

API_BASE = "http://localhost:8000/api/v1"

def create_xrechnung():
    """Erstellt eine XRechnung und validiert sie."""
    invoice = {
        "invoice_number": "RE-2026-042",
        "issue_date": "2026-03-22",
        "due_date": "2026-04-21",
        "currency_code": "EUR",
        "invoice_type_code": "380",
        "buyer_reference": "04011000-12345-67",
        "seller": {
            "name": "DevCorp GmbH",
            "street": "Entwicklerweg 42",
            "city": "München",
            "postal_code": "80331",
            "country_code": "DE",
            "tax_id": "DE987654321",
            "contact": {"email": "billing@devcorp.de"},
            "bank_account": {"iban": "DE89370400440532013000"}
        },
        "buyer": {
            "name": "Stadt München",
            "street": "Marienplatz 8",
            "city": "München",
            "postal_code": "80331",
            "country_code": "DE"
        },
        "lines": [
            {
                "description": "API-Entwicklung",
                "quantity": 80,
                "unit_code": "HUR",
                "unit_price": 120.00,
                "tax_category": "S",
                "tax_percent": 19.0
            },
            {
                "description": "Code Review",
                "quantity": 20,
                "unit_code": "HUR",
                "unit_price": 95.00,
                "tax_category": "S",
                "tax_percent": 19.0
            }
        ],
        "payment_terms": "Zahlbar innerhalb von 30 Tagen netto"
    }

    # 1. XML generieren
    resp = requests.post(
        f"{API_BASE}/invoices/xml",
        json=invoice,
        params={"syntax": "ubl"}
    )
    resp.raise_for_status()
    xml_bytes = resp.content

    # 2. Validieren
    val = requests.post(
        f"{API_BASE}/invoices/validate",
        files={"file": ("invoice.xml", xml_bytes, "application/xml")}
    )
    result = val.json()

    if not result["valid"]:
        for err in result["errors"]:
            print(f"Fehler: [{err['rule']}] {err['message']}")
        return False

    # 3. Speichern
    output = Path("output/RE-2026-042.xml")
    output.parent.mkdir(exist_ok=True)
    output.write_bytes(xml_bytes)
    print(f"Valide XRechnung gespeichert: {output}")
    return True

if __name__ == "__main__":
    create_xrechnung()

7. Was kommt als Nächstes: XRechnung 4.0, Peppol, Fristen

Sie haben die Grundlagen der XRechnung-Implementierung kennengelernt. Drei Punkte für den produktiven Einsatz:

  • Beispieldatei zum Abgleich: Eine vollständige, Block für Block erklärte XRechnung zum Download — UBL und CII — finden Sie in XRechnung-Beispiel. Ideal, um Ihre eigene Ausgabe Feld für Feld dagegenzuhalten.
  • Branchenerweiterungen prüfen: Bau, Gesundheit, Logistik und Automotive haben zusätzliche Anforderungen — siehe EN 16931 Branchenerweiterungen.
  • ZUGFeRD parallel einrichten: Viele B2B-Empfänger bevorzugen das Hybridformat. Die Unterschiede klärt XRechnung vs. ZUGFeRD.
  • Fristen beachten: Versandpflicht ab 2027 über 800.000 Euro Vorjahresumsatz, ab 2028 für alle.

Muss ich Peppol nutzen?

Nein. Der Gesetzgeber schreibt keinen Übermittlungsweg vor. Das BMF nennt E-Mail, Portal-Download, EDI, Schnittstelle oder gemeinsamen Speicherort als zulässige Wege — welchen Weg und welches zulässige Format die Parteien wählen, ist eine zivilrechtliche Frage zwischen ihnen. Für den Inlandsversand reicht XRechnung per E-Mail.

Peppol bleibt trotzdem relevant: Die KoSIT ist deutsche Peppol Authority, und XRechnung ist ab Version 3.0 inhaltlich deckungsgleich mit Peppol BIS Billing. Wer grenzüberschreitend fakturiert, kommt an einem Access Point praktisch kaum vorbei. Einordnung in Peppol im deutschen B2B.

Kommt XRechnung 4.0?

Die KoSIT bereitet XRechnung 4.0 als deutsche Umsetzung der neuen EU-Norm EN 16931-1:2026 vor; angekündigt ist ein Release Mitte bis Ende 2026, zunächst als Vorabversion ohne Produktionsfreigabe. Ein verbindliches Gültigkeitsdatum ist noch nicht veröffentlicht — die Bundle-Erstellung wartet auf die CEN-Syntaxbindings und Validierungsartefakte.

Für heutige Implementierungen ändert das nichts: Gültig ist XRechnung 3.0.2 auf Basis der EN-16931-Linie von 2017. Planen Sie die CustomizationID und die Schematron-Artefakte aber als konfigurierbar ein, nicht als Konstante im Code — mit 4.0 werden beide wechseln.

Nächster Schritt

Sind Sie ab 2027 zur E-Rechnung verpflichtet?

Der kostenlose E-Rechnung-Pflichtcheck klärt Ihren Status in wenigen Minuten — unverbindlich und ohne Anmeldung.

Zum E-Rechnung-Pflichtcheck

Oder die Checkliste direkt per E-Mail

15 Punkte mit Fristen — von der Empfangspflicht bis zur GoBD-Archivierung.

Wir respektieren Ihre Privatsphäre. Abmeldung jederzeit möglich.

Das könnte Sie auch interessieren

E-Rechnung-Pflicht ab 2027. Sind Sie bereit?

1.500 EUR Compliance-Check. Eine Woche. Konkreter Maßnahmenplan — oder Sie zahlen nichts.

Compliance-Check anfragen