Germany flips the issue side of B2B e-invoicing on January 1, 2027 for businesses with prior-year turnover above 800,000 euros. The receive obligation has been in force since January 1, 2025; the 2027 date is when the same VAT-registered seller has to send structured invoices, not just accept them. Three formats are compliant under the Wachstumschancengesetz: XRechnung (pure CII or UBL XML, machine only), ZUGFeRD 2.1 or later (PDF/A-3 with embedded EN 16931 XML, human plus machine), and Peppol BIS Billing 3.0 (network-delivered EN 16931 UBL). Most German SaaS teams pick ZUGFeRD 2.1 because it keeps the customer-facing PDF intact while satisfying the legal requirement through the embedded XML.
This is the developer playbook at T-6 months: what the law actually says, which format to choose, how the migration breaks down month by month, and the five PDF/A-3 traps that cause silent compliance failures in production.
What the Wachstumschancengesetz actually requires
The legal basis is the Wachstumschancengesetz (Growth Opportunities Act), passed by the Bundestag in March 2024 and signed into law shortly after. The act amends the German VAT code (Umsatzsteuergesetz, UStG) to redefine what counts as an invoice for domestic B2B transactions. Under the amended UStG section 14, a domestic B2B invoice is only a legal invoice if it is issued in a structured electronic format conforming to the European standard EN 16931, or in another structured format mutually agreed by the trading partners that can be processed without media break.
The official Bundesministerium der Finanzen (BMF) circular dated October 15, 2024 sets out the implementation details, and the e-invoicing FAQ at bundesfinanzministerium.de is the authoritative reference for edge cases. Two consequences matter for developers.
First, a PDF that contains an invoice in human-readable form but no machine-readable structured data is not a legal invoice from the dates above. It is treated as "another invoice" in the BMF circular, which means the buyer cannot rely on it for input-VAT deduction if the supplier was obliged to issue a structured invoice.
Second, the receive obligation has no threshold and applies since January 1, 2025. Every VAT-registered German business has to be able to accept an EN 16931 XML invoice today. The 2027 and 2028 dates only concern the issue side. Any SaaS that bills German B2B customers therefore already deals with buyers that can ingest XRechnung or ZUGFeRD, and the question for 2027 is what you send back.
The Wachstumschancengesetz timeline:
| Date | Obligation | Who |
|---|---|---|
| January 1, 2025 | Receive structured EN 16931 invoices | Every VAT-registered B2B business in Germany |
| January 1, 2027 | Issue structured EN 16931 invoices | Businesses with prior-year turnover above 800,000 euros |
| January 1, 2028 | Issue structured EN 16931 invoices | Every remaining B2B business, regardless of turnover |
The 800,000 euro threshold is calendar-year turnover for the prior tax year. A business that closes 2026 at 850,000 euros has to issue structured invoices from January 1, 2027. A business that closes 2026 at 750,000 euros gets one more year of grace and flips on January 1, 2028.
The three accepted formats
EN 16931 is a semantic standard, not a syntax. The German mandate accepts any syntax that carries the EN 16931 data model, and three options dominate in practice.
| Format | Human-readable | Machine-readable | Transport | Archival | Developer effort |
|---|---|---|---|---|---|
| XRechnung | No (XML only) | Yes (UBL or CII) | Email, sFTP, Peppol, any | PDF/A-3 not applicable | Low (XML serializer + KoSIT validator) |
| ZUGFeRD 2.1+ | Yes (PDF) | Yes (CII XML embedded) | Email, sFTP, Peppol, any | PDF/A-3 native | Medium (XML + PDF/A-3 + attach step) |
| Peppol BIS Billing 3.0 | No (UBL XML) | Yes (UBL) | Peppol network only | PDF/A-3 not applicable | High (Access Point registration + API integration) |
XRechnung is the German national CIUS (core invoice usage specification) of EN 16931. It exists in two syntax variants, UBL and CII, and is administered by KoSIT (Koordinierungsstelle für IT-Standards). XRechnung has been mandatory for public-sector procurement (B2G) in Germany since November 2020 and is now equally valid for B2B under the new rules. The current version is XRechnung 3.0.2, published by KoSIT. Pure XML means there is no PDF; the buyer's accounts payable system reads the XML directly and renders its own visualization if a human ever needs to look at it.
ZUGFeRD (Zentraler User Guide des Forums elektronische Rechnung Deutschland) is the hybrid format administered by FeRD (Forum elektronische Rechnung Deutschland). A ZUGFeRD file is a PDF/A-3 document with one CII XML attachment named exactly factur-x.xml (the canonical name today; older readers also accept zugferd-invoice.xml). The PDF carries the visual invoice for humans, the XML carries the EN 16931 data for machines, and both travel as a single file. The current version is ZUGFeRD 2.3.3, byte-compatible with Factur-X 1.07.3, jointly released on May 7, 2025 by FeRD and FNFE-MPE. The ZUGFeRD 2.1 floor matters because that version was the first to align profiles with EN 16931; pre-2.1 ZUGFeRD invoices are not compliant under the mandate. See the FeRD specification page for the canonical reference.
Peppol BIS Billing 3.0 is the EU-wide interoperability profile. It constrains the EN 16931 semantic model into UBL XML and adds the routing rules to deliver invoices over the Peppol four-corner network. Germany accepts Peppol BIS as a valid issuing format under the mandate, but using it requires registering with a Peppol Access Point, which is a paid service (Storecove, Pagero, Tradeshift, and similar). For a domestic German SaaS issuing fewer than a thousand B2B invoices a month, the Access Point fee exceeds the cost of building a ZUGFeRD pipeline. See peppol.org for the network specification.
Why ZUGFeRD 2.1+ is the practical choice for most SaaS
ZUGFeRD wins for most German B2B SaaS for one operational reason: it preserves the PDF layer that your customer's accounts payable team expects. The receive-side flip in 2025 means buyers can ingest XML, but it does not mean every buyer's AP workflow has migrated to a fully automated XML pipeline. A lot of mid-market German companies still have humans matching invoices to purchase orders in a folder of PDF attachments. A ZUGFeRD file looks like a PDF to that human reviewer, opens in Acrobat with the familiar layout, and prints the same way the legacy invoice did. The XML half is invisible until an automated AP system pulls it out.
The structural composition of a ZUGFeRD file:
invoice.pdf (PDF/A-3 container)
├── visual rendering (human-readable PDF page content)
├── XMP metadata (declares PDF/A-3 conformance)
└── /AF (document catalog associated files array)
└── Filespec
├── F = "factur-x.xml"
├── UF = "factur-x.xml"
├── AFRelationship = /Alternative
└── EF.F → EmbeddedFile stream (the CII XML bytes)
The visual rendering is whatever your current invoice PDF looks like. The XMP metadata block declares PDF/A-3 conformance (PDF/A-3a, PDF/A-3b, or PDF/A-3u, with 3b being the common choice for invoices because it does not require Unicode mapping). The associated files (AF) entry in the document catalog points to a Filespec that wraps the XML attachment with the right metadata. The AFRelationship key must be /Alternative because the XML is the same invoice in a different syntax, not a separate supporting document.
If you already render PDF invoices today, the migration is incremental rather than radical. You keep the HTML template, you keep the rendering engine, you add a PDF/A-3 conversion step at the end, and you build the XML half in parallel. The visual side of your invoice never changes for the end customer.
A PDF that contains an invoice in human-readable form but no embedded EN 16931 XML is not a legal invoice from January 1, 2027 onward for businesses above the 800,000 euro threshold (and from January 1, 2028 for everyone else). The buyer's tax office may refuse input-VAT deduction on it, which exposes both parties to penalties. Email PDF on its own stops being compliant on the cutover dates.
The developer migration playbook (6 months)
The mandate is not a feature, it is a regulatory deadline. The migration breaks down cleanly into six monthly milestones, where T-0 is January 1, 2027.
| Month | Goal | Concrete deliverable |
|---|---|---|
| T-6 (Jul 2026) | Decision and audit | Format chosen (default: ZUGFeRD 2.1+). Pipeline audit: every EN 16931 mandatory field mapped to a DB column. Gaps listed. |
| T-5 (Aug 2026) | XML generator | CII XML serializer that produces a valid EN 16931 invoice from any in-DB invoice record. Validated against KoSIT and FeRD Schematron in CI. |
| T-4 (Sep 2026) | PDF/A-3 embedding | Render to PDF, convert to PDF/A-3, attach XML with AFRelationship Alternative. The output passes VeraPDF validation. |
| T-3 (Oct 2026) | Regression and accounting sign-off | Real customer subset replayed through the new pipeline in a dry-run mode. Output files reviewed by the accounting team. Mapping errors fixed. |
| T-2 (Nov 2026) | Feature-flagged rollout | Hybrid invoice path live for 5 to 10 friendly B2B customers above the 800,000 euro threshold. Rejection logs from their AP systems collected. |
| T-1 (Dec 2026) | Full rollout above threshold | All B2B customers above 800,000 euros switched to the hybrid path. PDF-only fallback retained for sub-threshold customers until January 2028. |
| T-0 (Jan 2027) | Legacy path disabled | The PDF-only branch is removed for above-threshold customers. Logging confirms 100% of qualifying invoices ship as ZUGFeRD. |
The T-3 month is where most projects underestimate the effort. EN 16931 has 167 semantic data elements, and the German CIUS adds further constraints on which are mandatory. A real invoice pipeline at a mid-stage SaaS typically has three or four field mapping bugs that only surface when an actual customer's AP system rejects the XML for reasons like a missing buyer reference, an unsupported tax category, or a payment term outside the allowed code list. Plan four weeks for that loop, not two.
Generating a ZUGFeRD-compliant PDF in code
A ZUGFeRD pipeline has three independent steps that can be parallelized:
- Compute the invoice data once, as a structured object in your accounting model.
- Serialize the data to a CII XML file matching the EN 16931 profile.
- Render the human-readable invoice from HTML and convert to PDF/A-3.
- Attach the XML with
AFRelationship = /Alternativeand finalize. - Validate the result with Mustangproject (XML side) and VeraPDF (PDF/A-3 side).
PDF4.dev produces the human-readable PDF in step 3. The CII XML generator and the embedding step in step 4 sit outside the PDF4.dev API surface today; Mustangproject (Java) and node-zugferd (Node) are the most common libraries for them. The architectural split is clean: the PDF rendering service does not need to know about EN 16931, and the XML library does not need to know about HTML templates.
A minimal Handlebars invoice template that doubles as the human-readable side of a ZUGFeRD file:
<style>
body { font-family: 'Inter', sans-serif; padding: 20mm; color: #111827; }
h1 { font-size: 28px; margin-bottom: 4px; }
.meta { color: #6b7280; font-size: 12px; }
table { width: 100%; border-collapse: collapse; margin-top: 24px; }
th, td { padding: 8px 12px; text-align: left; border-bottom: 1px solid #e5e7eb; }
th { background: #f9fafb; font-size: 11px; text-transform: uppercase; }
.totals { margin-top: 16px; width: 50%; margin-left: auto; }
.grand { font-weight: 700; font-size: 18px; }
</style>
<h1>Rechnung {{invoice_number}}</h1>
<div class="meta">
Ausgestellt {{formatDate issue_date "dd MMM yyyy"}} ·
Fällig {{formatDate due_date "dd MMM yyyy"}}
</div>
<div style="display: flex; gap: 40px; margin-top: 24px;">
<div>
<div class="meta">Verkäufer</div>
<strong>{{seller.name}}</strong><br />
{{seller.address}}<br />
USt-IdNr. {{seller.vat}}
</div>
<div>
<div class="meta">Käufer</div>
<strong>{{buyer.name}}</strong><br />
{{buyer.address}}<br />
USt-IdNr. {{buyer.vat}}
</div>
</div>
<table>
<thead>
<tr><th>Bezeichnung</th><th>Menge</th><th>Einzelpreis</th><th>USt.</th><th>Summe</th></tr>
</thead>
<tbody>
{{#each lines}}
<tr>
<td>{{description}}</td>
<td>{{quantity}}</td>
<td>{{formatCurrency unit_price "EUR" "de-DE"}}</td>
<td>{{vat_rate}}%</td>
<td>{{formatCurrency line_total "EUR" "de-DE"}}</td>
</tr>
{{/each}}
</tbody>
</table>
<table class="totals">
<tr><td>Zwischensumme</td><td>{{formatCurrency subtotal "EUR" "de-DE"}}</td></tr>
<tr><td>USt. (19%)</td><td>{{formatCurrency vat_total "EUR" "de-DE"}}</td></tr>
<tr class="grand"><td>Gesamtbetrag</td><td>{{formatCurrency grand_total "EUR" "de-DE"}}</td></tr>
</table>The matching XML half, generated from the same invoice record with Mustangproject:
import org.mustangproject.*;
import org.mustangproject.ZUGFeRD.*;
Invoice invoice = new Invoice()
.setNumber("INV-2027-0001")
.setIssueDate(new SimpleDateFormat("yyyy-MM-dd").parse("2027-01-15"))
.setDueDate(new SimpleDateFormat("yyyy-MM-dd").parse("2027-02-14"))
.setSender(new TradeParty("PDF4 GmbH", "Berlin", "10115", "Berlin", "DE")
.addVATID("DE123456789"))
.setRecipient(new TradeParty("Beispiel GmbH", "München", "80331", "München", "DE")
.addVATID("DE987654321"))
.addItem(new Item(
new Product("API Rendering Credits, 10000er Pack", "", "C62", new BigDecimal("19.00")),
new BigDecimal("0.0090"),
new BigDecimal("10000")))
.addItem(new Item(
new Product("Priority Support, monatlich", "", "C62", new BigDecimal("19.00")),
new BigDecimal("50.00"),
new BigDecimal("1")));
ZUGFeRDExporterFromA3 exporter = new ZUGFeRDExporterFromA3()
.setProducer("PDF4.dev")
.setCreator("Mustangproject")
.setZUGFeRDVersion(2)
.setProfile(Profiles.getByName("EN16931"));
exporter.load("invoice-human-pdfa3.pdf");
exporter.setTransaction(invoice);
exporter.export("invoice-zugferd.pdf");Mustangproject reads the human-readable PDF/A-3 file (invoice-human-pdfa3.pdf), embeds the CII XML built from the Invoice object, sets AFRelationship = Alternative, and writes the final ZUGFeRD file. The library handles the AF array, the Filespec dictionary, and the XMP declaration end-to-end.
For Node.js teams that do not want to run a Java process, node-zugferd covers the XML generation, and the embedding step uses pdf-lib with the same Filespec + AFRelationship Alternative recipe documented in the Factur-X September 2026 article.
XRechnung path (when ZUGFeRD is not enough)
XRechnung makes sense in two cases. First, when the buyer is a large enterprise whose accounts payable system fully automates intake and explicitly asks for pure XML (often the case for Bundesbehörden inheriting their B2G workflow, but also some large industrial buyers). Second, when the supplier itself does not have a PDF rendering pipeline and treats the visual layer as redundant.
The XRechnung XML structure is the same UN/CEFACT CII (or UBL) schema as the XML half of a ZUGFeRD file, with a different GuidelineSpecifiedDocumentContextParameter URN identifying the XRechnung CIUS. For XRechnung 3.0 in CII syntax, the URN is urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_3.0. Mustangproject can target XRechnung directly via Profiles.getByName("XRECHNUNG"). The output is a .xml file (no PDF), typically delivered by email attachment, sFTP drop, or Peppol if the buyer is on the network.
Validation for pure XRechnung uses the KoSIT XRechnung Validator, a Java tool that checks both the EN 16931 Schematron rules and the German national CIUS rules. The validator is open source and is the authoritative compliance gate; passing it is the practical definition of XRechnung compliance.
Peppol BIS: when to invest
Peppol BIS Billing 3.0 is the EU-wide network protocol for invoice exchange. Joining Peppol means registering a Peppol Access Point (AP), which is typically not done in-house but via a paid certified provider. Once on the network, your AP exchanges invoices with every other AP using a standard four-corner model, and the receiver's AP delivers the invoice to its customer.
Peppol adds value when:
- You issue invoices cross-border across multiple EU jurisdictions (Belgium, Norway, the Netherlands, Denmark, Sweden, and others have national mandates that either require Peppol or accept it as a default).
- Your invoice volume per partner is high enough that email or sFTP becomes operationally annoying.
- Your buyers explicitly request Peppol delivery.
Peppol is not worth it when:
- You issue fewer than a thousand B2B invoices a month, all to German buyers, where email + ZUGFeRD covers every recipient.
- Your invoice exchange volume is low enough that the AP subscription fee (typically a few hundred euros a month minimum) exceeds the savings.
For the typical SaaS in the 800,000 euro to 10 million euro revenue band issuing invoices to German B2B customers, the choice is ZUGFeRD over email, not Peppol.
What does NOT work in 2027
A precise list of patterns that fail under the mandate from the dates above:
- PDF without embedded XML. Generating a beautiful invoice PDF with no
factur-x.xmlattachment ships a file that is not a legal invoice. The buyer's tax office can refuse input-VAT deduction on it. - PDF/A but no XML. Converting to PDF/A-2 or PDF/A-3 alone is not enough; the EN 16931 XML attachment is the compliance gate, not the PDF/A flavor.
- Scanned PDF of a paper invoice. A PDF whose content is a rasterized image of paper has no structured data and cannot carry an EN 16931 XML in any meaningful way. The BMF circular treats this as a paper invoice, which is not compliant for above-threshold issuers.
- Email-attached document without EN 16931 compliance. A custom XML format (your in-house schema, a JSON-to-XML export, a proprietary EDI format) is not a legal invoice unless both parties explicitly agree to it AND the format is "processable without media break", which the BMF interprets as carrying every EN 16931 mandatory field.
- ZUGFeRD 1.0 or ZUGFeRD 2.0 (pre-2.1). Only ZUGFeRD 2.1 and later align with EN 16931. Earlier ZUGFeRD versions had their own profile system that does not map cleanly to the European standard.
- MINIMUM or BASIC WL profiles of ZUGFeRD 2.1+. These are explicitly marked in the FeRD specification as "not suitable as a legal invoice" because they omit line-level detail. Use the EN16931 profile or the EXTENDED profile.
- AFRelationship set to Unspecified, Data, Source, or Supplement. The PDF spec allows all of these values, but Factur-X and ZUGFeRD require
Alternative. A wrong relationship value is the silent failure mode: the PDF looks correct, the XML is present, but compliant AP readers do not recognize it as a hybrid invoice.
Cost of doing nothing
The financial consequences of issuing a non-compliant invoice are not symmetric between the parties. The supplier may face penalties under German VAT law for failing to issue a proper invoice, but the deeper damage is on the buyer side: the buyer's tax office may refuse the input-VAT deduction on a non-compliant document. When that happens, the buyer's CFO calls the supplier's CFO and demands either a corrected invoice or a credit note. The remediation itself is straightforward; the brand damage of being the supplier whose invoices are getting flagged by customer tax teams is harder to repair.
For a SaaS issuing 500 invoices a month at an average ticket of 2,000 euros, the input-VAT exposure on a single month of non-compliant invoices is 190,000 euros (19% standard VAT). Most customers will not let that deduction lapse quietly; they will demand corrections, and a multi-customer escalation in the first weeks of 2027 absorbs more engineering time than the migration would have cost in the prior six months.
Frequently asked questions
The FAQ block at the top of this article and the inline guidance throughout cover the developer-facing questions: timeline, threshold, format choice, library selection, embedding mechanics, Peppol decision, and the consequences of staying on PDF-only. The shortest-path checklist for any team starting today is:
- Confirm whether your prior-year German B2B turnover crosses the 800,000 euro line. If yes, January 1, 2027 is your deadline; if no, January 1, 2028.
- Default to ZUGFeRD 2.1 with the EN16931 profile unless you have a specific reason to use XRechnung or Peppol.
- Audit your invoice schema against EN 16931 today, fix mapping gaps in August 2026, build the XML and PDF/A-3 pipeline in September and October, and roll out under feature flag in November.
- Validate every generated invoice in CI with Mustangproject and VeraPDF. A failure in CI costs one second; a failure at a customer's AP costs a phone call.
The German mandate is the second of three large 2026-2027 European e-invoicing flips after France's September 2026 deadline and Belgium's January 2026 Peppol rollout. The good news for any team that already shipped a Factur-X pipeline for France is that the German ZUGFeRD path is byte-compatible at the file level. The same hybrid PDF satisfies both jurisdictions if the profile is EN16931 or higher, which means one well-built pipeline covers two of the three big 2026-2027 deadlines. The remaining work is the operational layer: turnover tracking, customer segmentation, feature-flag rollout, and the December 31, 2026 cutover.
Start generating PDFs
Build PDF templates with a visual editor. Render them via API from any language in ~300ms.



