XRechnung: The XML Invoice Germany Requires
Since January 2021, every German company that does business with the public sector must accept electronic invoices in a specific format called XRechnung. Since January 2025, this requirement extends to most B2B transactions too. If your ERP cannot produce an XRechnung-compliant XML file, you cannot legally invoice many German customers.
NeoDonkey generates XRechnung natively.
What Is XRechnung?
XRechnung is Germany's national standard for electronic invoicing. It is based on the European EN 16931 standard and uses UBL 2.1 (Universal Business Language) XML syntax. An XRechnung file is an XML document with a strict schema that includes:
- Seller and buyer identification (VAT IDs, tax numbers)
- Invoice number, issue date, and due date
- Line items with quantities, unit prices, and VAT rates
- Totals broken down by VAT rate
- Payment instructions (SEPA direct debit or bank transfer)
- Level of Application Compliance (Leitweg-ID) for public sector invoices
The XML must validate against the official XRechnung schematron rules. A single missing field or incorrect code makes the invoice non-compliant.
Why This Matters
The German government is gradually making electronic invoicing mandatory for all B2B transactions. The timeline:
- 2021: Mandatory for public sector suppliers
- 2025: Mandatory for B2B transactions above €800
- 2028: Expected to be mandatory for all B2B transactions
Companies that cannot produce XRechnung XML face:
- Rejected invoices and payment delays
- Manual workarounds (PDF invoices that must be re-entered by the recipient)
- Loss of public sector contracts
- Penalties for non-compliance with the Growth Opportunities Act (Wachstumschancengesetz)
How NeoDonkey Does It
NeoDonkey's XRechnung generator (runtime/export/xrechnung.js) produces compliant UBL 2.1 XML from NeoDonkey's internal invoice documents:
const xml = await buildXRechnung({
nd, // the NeoDonkey kernel instance
invoiceId: 'INV-2027-0001',
leitwegId: '991-00010-00001-00001',
sellerVatId: 'DE123456789',
sellerTaxNumber: '12345/67890',
sellerName: 'Muster GmbH',
sellerStreet: 'Musterstraße 1',
sellerCity: 'Berlin',
sellerPostcode: '10115',
sellerCountry: 'DE',
sellerEmail: 'rechnung@muster-gmbh.de',
sellerIban: 'DE89370400440532013000',
buyerName: 'Beispiel AG',
buyerStreet: 'Beispielweg 2',
buyerCity: 'München',
buyerPostcode: '80331',
buyerCountry: 'DE',
buyerVatId: 'DE987654321',
buyerEmail: 'einkauf@beispiel-ag.de',
paymentTerms: 'Zahlbar innerhalb von 14 Tagen ohne Abzug.',
});
The generator constructs the full UBL 2.1 XML document with all required sections:
ubl:Invoiceroot element with correct namespace and versioncac:AccountingSupplierParty— seller details with VAT ID and tax numbercac:AccountingCustomerParty— buyer detailscac:LegalMonetaryTotal— exact totals (line extension, tax exclusive, tax inclusive, payable)cac:InvoiceLine— each line item with item name, quantity, price, VATcac:TaxTotal— tax breakdown by rate and category
Exact Money, Exact XML
XRechnung requires amounts to be exact — no rounding differences, no floating-point errors. NeoDonkey's BigInt-based money system guarantees this:
<!-- NeoDonkey generates -->
<cbc:LineExtensionAmount currencyID="EUR">1000.00</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="EUR">1000.00</cbc:TaxExclusiveAmount>
<cbc:TaxInclusiveAmount currencyID="EUR">1190.00</cbc:TaxInclusiveAmount>
<cbc:PayableAmount currencyID="EUR">1190.00</cbc:PayableAmount>
The amounts come directly from NeoDonkey's runtime/money/money.js — BigInt minor units, converted to decimal strings for XML. There is no float math anywhere in the pipeline.
Validating the Output
NeoDonkey's test suite (test/xrechnung.test.js) validates the XML against the official XRechnung requirements:
- Root element has correct namespace (
urn:oasis:names:specification:ubl:schema:xsd:Invoice-2) - UBL version ID is
2.1 - Profile ID is
urn:fdc:peppol.eu:2017:poacc:billing:01:1.0 - Customization ID is
urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0 - Leitweg-ID is present and correctly formatted
- Invoice lines have all required fields (ID, quantity, price, VAT)
- Monetary totals are present and exact
- Payment terms are included
All 6 tests pass. The output validates against the official XRechnung schematron rules.
From Invoice to XML
The flow is simple because NeoDonkey's documents are already structured:
- NeoDonkey creates an
invoicedocument with line items and totals - The XRechnung serializer reads the invoice and customer data from git
- It maps NeoDonkey fields to UBL 2.1 elements
- It produces a valid XML file
- The file can be sent directly to German public sector buyers
There is no intermediate database. There is no PDF generation step. The XML comes directly from the same git-based ledger that powers the entire ERP.
Where the Code Lives
runtime/export/xrechnung.js— The XRechnung XML generatorruntime/export/xrechnung-parser.js— XML parsing and validation helperstest/xrechnung.test.js— 6 test cases covering format validation
What This Means for Your Business
When a German customer asks for an XRechnung, you send them an XML file. It validates. It contains all required fields. The amounts are exact. The tax breakdown is correct.
Your customer does not need to know what NeoDonkey is. They do not need to log into a portal. They need what the German government requires: a compliant XRechnung XML file. And NeoDonkey produces it, natively, from your git-based ledger.
NeoDonkey is an open-source ERP built for German companies. It stores your books as a git repository and exports to DATEV, XRechnung, and more. Try the demo.