E-Invoicing Mandate 2025: Complete Guide for Developers
Starting January 1, 2025, electronic invoicing (e-invoicing) is mandatory for B2B transactions in Germany. This fundamental change affects every piece of software that creates or processes invoices -- from ERP systems to accounting software to e-commerce platforms.
In this comprehensive guide, you'll learn everything you need to know as a developer: legal foundations, technical requirements, code examples, and a practical implementation checklist.
Legal Background
EU Directive 2014/55/EU
The European Directive 2014/55/EU has required public contracting authorities to receive and process electronic invoices since 2020. Germany implements this directive through the E-Invoice Regulation (ERechV).
The Growth Opportunities Act (Wachstumschancengesetz)
The Wachstumschancengesetz (Growth Opportunities Act), passed on March 27, 2024, extends the e-invoicing mandate to the entire B2B sector. Key changes at a glance:
- Section 14 UStG (German VAT Act) has been updated and now defines binding requirements for electronic invoices
- An e-invoice must be issued, transmitted, and received in a structured electronic format
- The format must enable automated processing
- PDF files are no longer considered e-invoices (except ZUGFeRD with embedded XML)
Phased Rollout
| Date | Requirement | Affected |
|---|---|---|
| 01.01.2025 | Ability to receive e-invoices | All B2B companies |
| 01.01.2027 | Sending e-invoices | Companies with > 800,000 EUR prior-year revenue |
| 01.01.2028 | Sending e-invoices | All companies |
Important: The obligation to receive e-invoices applies from 2025 to all companies -- regardless of size.
What Changes Concretely?
Until now, companies could exchange invoices in any format: PDF, paper, or proprietary formats. Starting in 2025, B2B invoices must be in a structured electronic format that is machine-processable.
This means for your software:
- Receiving: You must be able to accept e-invoices in XRechnung or ZUGFeRD format
- Processing: The structured data must be correctly parsed and imported into your system
- Archiving: E-invoices must be stored in compliance with GoBD regulations (10 years, immutable). The Archive API supports you with this.
Try the Playground now to see how e-invoices look and how the API works.
XRechnung vs. ZUGFeRD vs. Peppol
As a developer, you face the question: Which format should I implement? Here's a decision tree:
Decision Tree
1Invoice recipient?2├─ Public administration (federal/state/municipal)3│ └─ → XRechnung (mandatory!)4├─ International business partner (EU)5│ └─ → Peppol BIS Billing6└─ German B2B companies7 ├─ Recipient wants PDF view?8 │ └─ → ZUGFeRD9 └─ Only structured data needed?10 └─ → XRechnungTechnical Differences
| Feature | XRechnung | ZUGFeRD 2.x | Peppol BIS |
|---|---|---|---|
| Base standard | EN 16931 | EN 16931 | EN 16931 |
| XML syntax | UBL 2.1 or CII | CII (Cross Industry Invoice) | UBL 2.1 |
| PDF included | No | Yes (PDF/A-3) | No |
| Validation | KoSIT validation tool | KoSIT validation tool | Peppol Validation |
| Use case | B2G, B2B | B2B with PDF needs | International B2B |
| File size | Small (~20 KB) | Larger (~500 KB+) | Small (~20 KB) |
UBL vs. CII -- What's the Difference?
UBL (Universal Business Language) and CII (Cross Industry Invoice) are two XML syntaxes for the same semantic standard EN 16931:
- UBL 2.1: Used by XRechnung (Germany), Peppol, FatturaPA (Italy)
- CII: Used by ZUGFeRD, Factur-X (France)
Both contain the same business information; only the XML structure differs. With the Converter API, you can switch between formats.
Technical Requirements
1. Receiving E-Invoices (XML Parsing)
The first step is parsing incoming e-invoices. The Parser API makes this simple. Here's an example of reading an XRechnung:
1// TypeScript/Node.js - Parse XRechnung2async function processIncomingInvoice(xmlContent: string) {3 const response = await fetch("https://service.Invoice-api.xhub.io/api/v1/invoice/de/xrechnung/generate/parse", {4 method: "POST",5 headers: {6 "Authorization": `Bearer ${process.env.XHUB_API_KEY}`,7 "Content-Type": "application/xml"8 },9 body: xmlContent10 });11 12 const invoice = await response.json();13 console.log("Invoice number:", invoice.invoiceNumber);14 console.log("Total amount:", invoice.totalAmount);15 16 return invoice;17}1# Python - Parse XRechnung2import requests3 4def process_incoming_invoice(xml_content: str):5 response = requests.post(6 "https://service.Invoice-api.xhub.io/api/v1/invoice/de/xrechnung/generate/parse",7 headers={8 "Authorization": f"Bearer {API_KEY}",9 "Content-Type": "application/xml"10 },11 data=xml_content12 )13 14 invoice = response.json()15 print(f"Invoice number: {invoice['invoiceNumber']}")16 print(f"Total amount: {invoice['totalAmount']}")17 18 return invoice2. Validating E-Invoices
Before processing an e-invoice, you should validate it. KoSIT (Coordination Office for IT Standards) provides Schematron rules.
1# cURL - Validate e-invoice2curl -X POST https://service.Invoice-api.xhub.io/api/v1/invoice/de/xrechnung/generate/validate \3 -H "Authorization: Bearer $XHUB_API_KEY" \4 -H "Content-Type: application/xml" \5 --data-binary @rechnung.xml6 7# Response8{9 "valid": true,10 "format": "XRechnung 3.0.2",11 "schematronPassed": true,12 "warnings": [],13 "errors": []14}You can find the complete API documentation at /docs/api/validator.
3. Creating and Sending E-Invoices
Creating compliant e-invoices is the most complex part. You need to correctly populate all mandatory fields and comply with the Schematron rules.
1// TypeScript/Node.js - Create e-invoice2const response = await fetch("https://service.Invoice-api.xhub.io/api/v1/invoice/de/xrechnung/generate", {3 method: "POST",4 headers: {5 "Authorization": `Bearer ${process.env.XHUB_API_KEY}`,6 "Content-Type": "application/json"7 },8 body: JSON.stringify({9 type: "xrechnung-3.0",10 invoiceNumber: "RE-2025-001",11 issueDate: "2025-01-15",12 seller: {13 name: "Meine Firma GmbH",14 vatId: "DE123456789",15 address: {16 street: "Musterstraße 1",17 city: "Berlin",18 postalCode: "10115",19 country: "DE"20 }21 },22 buyer: {23 name: "Kunde AG",24 vatId: "DE987654321",25 leitweg: "991-12345-67", // For public contracting authorities26 address: {27 street: "Kundenweg 42",28 city: "München",29 postalCode: "80331",30 country: "DE"31 }32 },33 items: [34 {35 description: "Softwareentwicklung",36 quantity: 40,37 unit: "Stunden",38 unitPrice: 120.00,39 vatRate: 1940 },41 {42 description: "Server-Hosting (Januar 2025)",43 quantity: 1,44 unit: "Monat",45 unitPrice: 299.00,46 vatRate: 1947 }48 ],49 paymentTerms: {50 dueDate: "2025-02-15",51 iban: "DE89370400440532013000",52 bic: "COBADEFFXXX"53 }54 })55});56 57const invoice = await response.json();58console.log("E-invoice created:", invoice.id);59console.log("Download XML:", invoice.downloadUrl);1# Python - Create e-invoice2import requests3import os4 5response = requests.post(6 "https://service.Invoice-api.xhub.io/api/v1/invoice/de/xrechnung/generate",7 headers={8 "Authorization": f"Bearer {os.environ['XHUB_API_KEY']}",9 "Content-Type": "application/json"10 },11 json={12 "type": "xrechnung-3.0",13 "invoiceNumber": "RE-2025-001",14 "issueDate": "2025-01-15",15 "seller": {16 "name": "Meine Firma GmbH",17 "vatId": "DE123456789",18 "address": {19 "street": "Musterstraße 1",20 "city": "Berlin",21 "postalCode": "10115",22 "country": "DE"23 }24 },25 "buyer": {26 "name": "Kunde AG",27 "vatId": "DE987654321",28 "address": {29 "street": "Kundenweg 42",30 "city": "München",31 "postalCode": "80331",32 "country": "DE"33 }34 },35 "items": [36 {37 "description": "Softwareentwicklung",38 "quantity": 40,39 "unit": "Stunden",40 "unitPrice": 120.00,41 "vatRate": 1942 }43 ]44 }45)46 47invoice = response.json()48print(f"E-invoice created: {invoice['id']}")You can find the complete API documentation for creating e-invoices at /docs/api/creator.
Implementation Checklist
Use this checklist to ensure your software is ready for the e-invoicing mandate:
Receiving (Mandatory from 01.01.2025)
- Able to parse XRechnung (UBL)
- Able to parse XRechnung (CII)
- Able to parse ZUGFeRD 2.x (PDF with embedded XML)
- Validation of incoming invoices implemented
- Error messages for invalid invoices displayed
- GoBD-compliant archiving implemented
Sending (Mandatory from 01.01.2027/2028)
- XRechnung export implemented
- ZUGFeRD export implemented (if PDF is desired)
- Leitweg-ID supported for public contracting authorities
- Validation before sending implemented
- All mandatory fields per EN 16931 populated
- Unit tests for e-invoice generation
General
- API integration tested (sandbox environment)
- Error handling for API outages implemented
- Retry logic for failed requests
- Logging and monitoring set up -- use Webhooks for real-time notifications
Common Errors and Solutions
Certain validation errors occur particularly frequently when implementing e-invoices:
BR-DE-01: Missing Leitweg-ID
Error: BR-DE-01: An invoice to public contracting authorities must contain a Leitweg-ID.
Solution: If the invoice recipient is a public administration, you must provide the Leitweg-ID:
1{2 "buyer": {3 "name": "Bundesministerium für Digitales",4 "leitweg": "991-12345-67"5 }6}The Leitweg-ID consists of three parts: coarse addressing (3 digits), fine addressing (up to 8 digits), and check digit (2 digits).
BR-DE-15: Missing Bank Details
Error: BR-DE-15: An invoice must contain payment information.
Solution: Payment information is mandatory in Germany:
1{2 "paymentTerms": {3 "dueDate": "2025-02-15",4 "iban": "DE89370400440532013000",5 "bic": "COBADEFFXXX"6 }7}BR-CO-10: Totals Don't Match
Error: BR-CO-10: The sum of line item amounts does not equal the total amount.
Solution: Make sure your calculations are exact. Use decimal types instead of float:
1// ❌ Wrong - Float imprecision2const total = 0.1 + 0.2; // = 0.300000000000000043 4// ✅ Correct - Integer cent calculation5const totalCents = 10 + 20; // = 306const total = totalCents / 100; // = 0.30A complete list of all error codes can be found in the documentation.
FAQ -- Frequently Asked Questions
Do I need to be able to receive e-invoices even if I don't have to send them yet?
Yes. Starting January 1, 2025, every B2B company in Germany must be able to receive e-invoices -- regardless of revenue. The sending obligation takes effect later (2027/2028), but you must be able to receive immediately.
Are PDF invoices banned starting in 2025?
Not exactly. PDF invoices without structured data are no longer considered e-invoices. However, you can still accept them as "other invoices" until the transition period ends (2027/2028), if your business partner cannot send an e-invoice. The ZUGFeRD format contains a PDF but counts as an e-invoice because the XML data is embedded.
What happens if I ignore the mandate?
Legally, violations of the invoicing obligations under Section 14 UStG can result in fines. More practically relevant: Without e-invoicing capability, you cannot issue invoices to public contracting authorities and may lose business partners who only accept e-invoices.
Do I have to implement e-invoicing myself or can I use an API?
You can do both. Self-implementation requires processing the 247-page KoSIT specification, Schematron validation, and regular updates when formats change. With an API like Invoice-api.xhub, you save this complexity and can go live in just a few hours. No API experience? Use our no-code integrations with Zapier, Make, or n8n.
How do I archive e-invoices in compliance with GoBD?
E-invoices must be stored immutably for 10 years. This means:
- Store the original XML (not just the processed data)
- Document the timestamp of receipt
- Ensure tamper protection (e.g., through hash values)
- Guarantee readability throughout the entire retention period
Next Steps
You now have a comprehensive overview of the e-invoicing mandate 2025. Here are your next steps:
-
Test the Playground: Experiment with the API in the Playground -- no sign-up, no cost.
-
Get an API key: Register for free and get your API key for the sandbox environment.
-
Start integrating: Use our quickstart guide or the SDKs for Node.js, Python, or the REST API directly.
-
Read the documentation: Find deeper technical details in the Validator documentation and Creator documentation.
Conclusion
The e-invoicing mandate 2025 is not optional -- it's reality. But with the right tools, you don't have to spend weeks on implementation.
Invoice-api.xhub takes the complexity off your hands:
- All formats (XRechnung, ZUGFeRD, Peppol) from a single API
- Automatic validation against current KoSIT schemas
- Simple JSON API instead of XML handling
- SDKs for all popular languages
Questions? Contact us.
Get started now -- the first 100 e-invoices per month are free.

