ComplianceE-InvoiceXRechnung

E-Invoicing Mandate 2025: Complete Guide for Developers

E-invoicing becomes mandatory for B2B in 2025. Technical guide with code examples for XRechnung, ZUGFeRD, and Peppol. Implementation checklist included.

Patrick Jerominek

Patrick Jerominek

Cofounder

January 20, 202615 min reading time
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.


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

DateRequirementAffected
01.01.2025Ability to receive e-invoicesAll B2B companies
01.01.2027Sending e-invoicesCompanies with > 800,000 EUR prior-year revenue
01.01.2028Sending e-invoicesAll 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:

  1. Receiving: You must be able to accept e-invoices in XRechnung or ZUGFeRD format
  2. Processing: The structured data must be correctly parsed and imported into your system
  3. 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

text
1Invoice recipient?
2 Public administration (federal/state/municipal)
3 XRechnung (mandatory!)
4 International business partner (EU)
5 Peppol BIS Billing
6 German B2B companies
7 Recipient wants PDF view?
8 ZUGFeRD
9 Only structured data needed?
10 XRechnung

Technical Differences

FeatureXRechnungZUGFeRD 2.xPeppol BIS
Base standardEN 16931EN 16931EN 16931
XML syntaxUBL 2.1 or CIICII (Cross Industry Invoice)UBL 2.1
PDF includedNoYes (PDF/A-3)No
ValidationKoSIT validation toolKoSIT validation toolPeppol Validation
Use caseB2G, B2BB2B with PDF needsInternational B2B
File sizeSmall (~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:

typescript
1// TypeScript/Node.js - Parse XRechnung
2async function processIncomingInvoice(xmlContent: string) {
3 const response = await fetch("https://service.invoice-api.xhub.io/api/v1/invoice/de/xrechnung/parse", {
4 method: "POST",
5 headers: {
6 "Authorization": `Bearer ${process.env.XHUB_API_KEY}`,
7 "Content-Type": "application/xml"
8 },
9 body: xmlContent
10 });
11 
12 const result = await response.json();
13 // result: { success, invoice, format, hash, errors, warnings }
14 console.log("Invoice number:", result.invoice.invoiceNumber);
15 console.log("Total amount:", result.invoice.total);
16 
17 return result.invoice;
18}
python
1# Python - Parse XRechnung
2import requests
3 
4def process_incoming_invoice(xml_content: str):
5 response = requests.post(
6 "https://service.invoice-api.xhub.io/api/v1/invoice/de/xrechnung/parse",
7 headers={
8 "Authorization": f"Bearer {API_KEY}",
9 "Content-Type": "application/xml"
10 },
11 data=xml_content
12 )
13 
14 result = response.json()
15 # result: {success, invoice, format, hash, errors, warnings}
16 print(f"Invoice number: {result['invoice']['invoiceNumber']}")
17 print(f"Total amount: {result['invoice']['total']}")
18 
19 return result['invoice']

2. Validating E-Invoices

Before processing an e-invoice, you should validate it. KoSIT (Coordination Office for IT Standards) provides Schematron rules.

bash
1# cURL - Validate e-invoice
2curl -X POST https://service.invoice-api.xhub.io/api/v1/invoice/de/xrechnung/validate \
3 -H "Authorization: Bearer $XHUB_API_KEY" \
4 -H "Content-Type: application/xml" \
5 --data-binary @rechnung.xml
6 
7# Response
8{
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.

typescript
1// TypeScript/Node.js - Create e-invoice
2const 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 invoice: {
10 type: "invoice",
11 invoiceNumber: "RE-2025-001",
12 issueDate: "2025-01-15",
13 dueDate: "2025-02-15",
14 currency: "EUR",
15 seller: {
16 name: "Meine Firma GmbH",
17 vatId: "DE123456789",
18 street: "Musterstraße 1",
19 city: "Berlin",
20 postalCode: "10115",
21 countryCode: "DE",
22 bankAccount: {
23 iban: "DE89370400440532013000",
24 bic: "COBADEFFXXX"
25 }
26 },
27 buyer: {
28 name: "Kunde AG",
29 vatId: "DE987654321",
30 street: "Kundenweg 42",
31 city: "München",
32 postalCode: "80331",
33 countryCode: "DE"
34 },
35 countrySpecific: {
36 countryCode: "DE", // required discriminator
37 leitwegId: "991-12345-67" // For public contracting authorities (B2G)
38 },
39 items: [
40 {
41 position: 1,
42 description: "Software development",
43 quantity: 40,
44 unit: "HUR",
45 unitPrice: 120.00,
46 taxRate: 19,
47 netAmount: 4800.00,
48 taxAmount: 912.00,
49 grossAmount: 5712.00
50 },
51 {
52 position: 2,
53 description: "Server hosting (January 2025)",
54 quantity: 1,
55 unit: "MON",
56 unitPrice: 299.00,
57 taxRate: 19,
58 netAmount: 299.00,
59 taxAmount: 56.81,
60 grossAmount: 355.81
61 }
62 ],
63 subtotal: 5099.00,
64 total: 6067.81,
65 taxSummary: [
66 { taxRate: 19, netAmount: 5099.00, taxAmount: 968.81 }
67 ],
68 paymentTerms: {
69 dueDays: 30,
70 description: "Payable within 30 days, net"
71 }
72 }
73 })
74});
75 
76const result = await response.json();
77// Response: { success, format, filename, mimeType, hash, data (base64), errors, warnings }
78console.log("Format:", result.format, "File:", result.filename);
python
1# Python - Create e-invoice
2import requests
3import os
4 
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 "invoice": {
13 "type": "invoice",
14 "invoiceNumber": "RE-2025-001",
15 "issueDate": "2025-01-15",
16 "dueDate": "2025-02-15",
17 "currency": "EUR",
18 "seller": {
19 "name": "Meine Firma GmbH",
20 "vatId": "DE123456789",
21 "street": "Musterstraße 1",
22 "city": "Berlin",
23 "postalCode": "10115",
24 "countryCode": "DE"
25 },
26 "buyer": {
27 "name": "Kunde AG",
28 "vatId": "DE987654321",
29 "street": "Kundenweg 42",
30 "city": "München",
31 "postalCode": "80331",
32 "countryCode": "DE"
33 },
34 "items": [
35 {
36 "position": 1,
37 "description": "Software development",
38 "quantity": 40,
39 "unit": "HUR",
40 "unitPrice": 120.00,
41 "taxRate": 19,
42 "netAmount": 4800.00,
43 "taxAmount": 912.00,
44 "grossAmount": 5712.00
45 }
46 ],
47 "subtotal": 4800.00,
48 "total": 5712.00,
49 "taxSummary": [
50 { "taxRate": 19, "netAmount": 4800.00, "taxAmount": 912.00 }
51 ],
52 "paymentTerms": { "dueDays": 30 }
53 }
54 }
55)
56 
57result = response.json()
58# Response: {success, format, filename, mimeType, hash, data (base64), errors, warnings}
59print(f"Format: {result['format']}, File: {result['filename']}")

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:

json
1{
2 "buyer": {
3 "name": "Bundesministerium für Digitales"
4 },
5 "countrySpecific": {
6 "countryCode": "DE",
7 "leitwegId": "991-12345-67"
8 }
9}

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:

json
1{
2 "seller": {
3 "bankAccount": {
4 "iban": "DE89370400440532013000",
5 "bic": "COBADEFFXXX"
6 }
7 },
8 "paymentTerms": {
9 "dueDays": 30,
10 "description": "Payable within 30 days to the account shown"
11 }
12}

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:

typescript
1// ❌ Wrong - Float imprecision
2const total = 0.1 + 0.2; // = 0.30000000000000004
3 
4// ✅ Correct - Integer cent calculation
5const totalCents = 10 + 20; // = 30
6const total = totalCents / 100; // = 0.30

A 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. For a step-by-step guide, see our n8n e-invoice integration with ready-made workflow templates.

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:

  1. Test the Playground: Experiment with the API in the Playground -- no sign-up, no cost.

  2. Get an API key: Register for free and get your API key for the sandbox environment.

  3. Start integrating: Use our quickstart guide or the SDKs for Node.js, Python, or the REST API directly.

  4. 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.

Share article

Ready to master e-invoicing?

Get started in under 5 minutes with Invoice-api.xhub. No credit card required.