About this plugin
Germany phases in mandatory B2B electronic invoicing in 2027 and 2028; the obligation to receive electronic invoices has been in force since 1 January 2025. This plugin turns any WooCommerce order into a structured invoice in the EN 16931 format — no external service, no account, no running costs. Everything happens on the shop’s own server.
The interface and the generated documents are German, because the formats this plugin implements (XRechnung, the Leitweg-ID routing identifier, the BR-DE business rules) are the German national implementation of EN 16931.
What the plugin does
- Produces an XRechnung in UBL 2.1 from an order — the standard format for invoices to public authorities and large customers.
- Produces, instead or in addition, the UN/CEFACT CII syntax used by ZUGFeRD and Factur-X.
- Attaches the XML file to the WooCommerce invoice e-mail automatically.
- Adds a download button per format to the order screen.
- Freezes an invoice that has been issued, so the document that went out can still be downloaded unchanged after the order has been corrected.
- Collects the Leitweg-ID per order — at checkout, and editable afterwards on the order screen.
- Collects the customer’s VAT identification number and derives reverse-charge cases from it.
- Validates before output against the mandatory fields of EN 16931 and the German rule set (BR-DE), and says in plain language which field is missing and where to enter it.
Why valid EN 16931 XML is not yet an XRechnung
EN 16931 is the European semantic core of an electronic invoice. XRechnung is the German implementation of it, and it adds a rule set of its own — BR-DE — on top of the European rules. Which of the two a validator applies is decided by a single field in the file, the specification identifier BT-24.
eu:en16931:2017 is measured against the European rules only; the German rules are never applied to it, no matter how correct it is. That is why software can write XML a validator accepts and still not produce an XRechnung.
0 identifier and fills the fields the German rules then demand, among them:
- BT-10 — the Leitweg-ID as the buyer reference, collected per order; for customers who are not a public authority the order number takes its place.
- BT-41 and BT-42 — a seller contact point and a seller telephone number inside the XML, not only on a printed invoice.
- BT-72 — the delivery or service date, always present.
- BT-23 — the business process identifier, and the electronic addresses of seller ( BT-34 ) and buyer ( BT-49 ).
A file that is missing these is rejected the moment it claims to be an XRechnung — which is exactly what a German authority asks for.
What the plugin deliberately does not do
It does not create a PDF and does not embed anything into a PDF/A-3. A complete ZUGFeRD document is a PDF with embedded XML; this plugin delivers the XML. If you need a PDF, combine it with an invoice PDF plugin.
Data and requests
The plugin makes no outbound HTTP requests at all: no update check, no telemetry, no validation service, no CDN. Nothing about an order or about the shop leaves the server. The XML is built in memory; only the e-mail attachment needs a file on disk, and that one is written to the server’s temporary directory with owner-only permissions and deleted again as soon as WooCommerce has handed the mail over.
htaccess deny there blocks access, on nginx such a deny has no effect and the file is instead protected only by its random name for the seconds it exists.
Everything the plugin stores lives in WordPress options and order meta, all prefixed wc_erechnung_, and uninstalling removes every one of them.
A refund booked in WooCommerce does not change the e-invoice itself — the file keeps showing the full amount — but it gets its own credit note (BT-3 = 381) with a reference to the original invoice (BG-3), downloadable per format right next to the invoice on the order screen.
A wrongly issued invoice is handled the other way round: correct the order, then tick Rechnung berichtigen on the order screen and the plugin writes a corrected invoice (BT-3 = 384) that names the superseded document in BG-3 and states that it is not to be paid.
An invoice that has gone out stays reproducible. The first time an invoice is really issued — the moment its number is drawn, which is what a download and the e-mail attachment do and what the preview deliberately does not — the plugin freezes the XML of both syntaxes on the order. Every later request returns that copy byte for byte, even after the order has been corrected, and the order screen says since when.
So the shop can still produce the document it actually sent, which is what an audit asks for; a changed state is a correction with a number of its own, not a rewritten invoice.
Conformance
2” configuration. All bundled test cases — standard invoice, small-business exemption, reverse charge, mixed tax rates, prepayment, minimal invoice, credit note, corrected invoice — are rated ACCEPTABLE in both syntaxes.
Which scenario the validator picks is part of the test, not just the verdict: every one of the 48 documents the test suite generates is matched to an XRechnung scenario — EN16931 XRechnung (UBL Invoice), EN16931 XRechnung (UBL CreditNote) or EN16931 XRechnung (CII) — and therefore measured against the BR-DE rules, not only against the European ones. A file that landed in the plain EN16931 scenario would fail the test suite even if the validator accepted it.