Skip to content
Back to Blog
Editorial-Stillleben: Papierrechnung mit pixeliger Kante, Uebergang von analog zu strukturiertem XML, Wachs-Siegel als Echtheits-Symbol
|3 min read|1

B2B e-invoicing in 2026: XRechnung vs. ZUGFeRD and how to implement it technically

AI-generatedclaude-opus-4-7compliancee-rechnungxrechnungzugferdgobdrechtwachstumschancengesetz

Since 1 January 2025 all domestic German companies must be able to receive e-invoices. Sending is staggered: from 01.01.2027 for revenues above EUR 800,000, from 01.01.2028 for all B2B. PDF alone is no longer enough — structured XML is required. Even so, in 2026 many bookkeeping departments still operate as before: generate PDF, send by email, done. That gets expensive. This article explains what a real e-invoice is and how to generate and archive it cleanly.

What is an e-invoice in legal terms?

An e-invoice under the German Wachstumschancengesetz (Art. 23) is an invoice in a structured electronic format that allows machine processing. PDF files are not e-invoices — even when sent electronically. Two formats apply in Germany:

  • XRechnung: pure XML, standard in B2G (authorities), works for B2B too.
  • ZUGFeRD from profile EN 16931: hybrid format — a PDF with embedded XML. Humans see the PDF, software reads the XML.

Both must satisfy the EN 16931 mandatory fields and pass the KoSIT validator. Without a correct e-invoice no input VAT deduction — that becomes a sharp sword in the audits of 2027.

XRechnung or ZUGFeRD?

The question comes up in every compliance audit. My answer: ZUGFeRD from profile EN 16931, unless there is a good reason against it.

Why: ZUGFeRD is a PDF with embedded XML. That has two advantages:

  1. Readable for humans: if the recipient doesn't yet have fully automated processing, they can simply open the invoice as a PDF.
  2. Readable for machines: modern bookkeeping (DATEV, lexware, sevDesk) extracts the XML automatically.

XRechnung is purist better — no human sees the XML, everything is processed automatically. But that assumes the recipient has software that understands XRechnung. In B2B practice in 2026 this isn't universal yet. ZUGFeRD bridges the transition phase.

Mandatory fields and validation

EN 16931 prescribes a set of mandatory fields. Excerpt:

  • Invoice number (unique, sequential)
  • Invoice date
  • Service/delivery date
  • VAT ID of seller (DE12345...)
  • VAT rates per line (0%, 7%, 19%)
  • Order number/order reference (mandatory in B2G, strongly recommended B2B)
  • Seller bank details (IBAN, BIC)
  • Discount terms in structured fields (NOT as free text!)

Validation happens with the KoSIT validator — the official German federal tool. I integrate the Schematron check into the send path: no invoice leaves the system without being validated.

from kosit_validator import validate_xrechnung

def send_invoice(xml: bytes, recipient_email: str):
    result = validate_xrechnung(xml, profile="EN16931")
    if not result.is_valid:
        raise ValueError(f"E-invoice invalid: {result.errors}")
    # Only send after successful validation
    send_email_with_attachment(recipient_email, xml, "invoice.xml")
    archive_invoice(xml, hash=hashlib.sha256(xml).hexdigest())

GoBD-compliant archive

E-invoices must be retained for 8 years unchanged — under the GoBD principles (German principles for proper computer-aided accounting). The original is the XML file, not a PDF print. Anyone throwing away the XML and only keeping the PDF has lost the original.

My standard setup: Supabase Storage bucket with write protection after first upload, plus a hash lock in a separate table:

CREATE TABLE invoice_archive (
  id           UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  invoice_no   TEXT UNIQUE NOT NULL,
  storage_path TEXT NOT NULL,         -- Supabase Storage URL
  sha256       TEXT NOT NULL,          -- hash of original XML
  format       TEXT NOT NULL CHECK (format IN ('xrechnung', 'zugferd')),
  archived_at  TIMESTAMPTZ DEFAULT NOW(),
  retention_until DATE NOT NULL        -- archived_at + 8 years
);

For changes, a cancellation invoice must be created, followed by a new invoice — no editing of the original. The hash proves the archived version was not modified.

Receive workflow

Incoming e-invoices land in a dedicated email inbox (e.g. `invoices@yourdomain.com`). A cron job pulls the attachments regularly, validates them, and stores them in the archive. On errors (XML invalid, mandatory fields missing) the bookkeeper gets a notification with the specific issue.

What I do concretely

For an e-invoice setup on your project I deliver: an e-invoice generator (XRechnung 3.0.x or ZUGFeRD 2.3+), validation against KoSIT before every send, GoBD-compliant archive with hash lock in Supabase Storage, a receive path via email inbox plus XML parsing, integration with DATEV export or existing ERP, and a status dashboard for received/sent/rejected invoices.

More at /compliance/e-rechnung.

AI-Generated Article

This article was created with AI assistance based on external sources and reviewed by Harald Schwankl. All phrasing is original.

AI Model: claude-opus-4-7 · Confidence: 85%

Share with friends & colleagues
Topics:
COMPLIANCEE-RECHNUNGXRECHNUNGZUGFERDGOBDRECHTWACHSTUMSCHANCENGESETZ
Be the first

How helpful did you find this page?

Harald Schwankl

Dipl.-Ing. Electrical Engineering · Fullstack Developer · AI Specialist

Fullstack developer with over 20 years of experience in software engineering. Specializing in AI integration, RAG systems and AI agents. I build industry solutions that are performant, scalable and smart.

Related Articles

New articles by email

Once a week in digest form: new articles on AI, fullstack and web. Double-opt-in, unsubscribe anytime.

Newsletter

Monthly tips on AI, web development, and RAG.

We respect your privacy. Unsubscribe at any time.

Made in Germany100% DSGVO-konformEU AI Act ReadySicheres HostingBarrierefreiCookie ConsentDaten-Anonymisierung
B2B e-invoicing in 2026: XRechnung vs. ZUGFeRD and how to implement it technically