EN 16931 · Peppol BIS · XRechnung · PINT A-NZ · Factur-X
Rendering infrastructure for structured e-invoices.
Open-source XSL-FO stylesheets and a self-hosted container that turn structured invoice XML — Peppol BIS, XRechnung, PINT A-NZ, CII — into archive-grade, human-readable PDF.
docker run -p 8080:8080 ghcr.io/faktorei/render:2025.11 Every feature, no signup, your infrastructure — watermarked output, 500 documents/day. What a license removes →
One pipeline, every syntax
Normalize once, render once.
Every document normalizes to the EN 16931 semantic model before anything is drawn, so one renderer serves UBL and CII alike and national profiles are configuration deltas, not forks. The normalizers are held to a strict contract in CI: a UBL invoice and its CII twin must produce byte-identical semantic XML — and they render pixel-identically. What changes between Peppol, XRechnung, and a plain EN 16931 invoice is a parameter, never the rendering logic.
There are two national profiles today — XRechnung (Germany) and PINT A-NZ (Australia and New Zealand) — and they share every line of rendering logic. Two is the number that matters: one profile is a special case, two is a pattern. The A-NZ work is also where the fixture corpus stopped being European. Japanese yen (a currency with no minor unit), Australian dollars, and GST rather than VAT are fixtures now, checked on every commit.
Labels ship in English, German, French and Dutch. That is not a convenience: the Loi Toubon requires an invoice between French parties to be in French, and Belgium fixes the language by the seller's region — Dutch in Flanders, French in Wallonia, German in Ostbelgien — where the wrong one can cost the invoice its validity. The language is a parameter, like the profile.
One renderer, one theme, one code path. The profile is a parameter — and the number of decimal places comes from the document's currency, not its language. Each image is a blessed baseline — the same file the pixel gate compares against on every commit — cropped to the totals block, the only part that carries the difference. Each links to the source XML that produced it.
Pagination the way ledgers did it
Long invoices that still read like documents.
Table headers repeat on every page. A running subtotal is carried forward across page breaks — printed at the top of each continuation page, the way a counting-house ledger did it — so a reader never loses the thread on a hundred-line invoice. The totals block is never orphaned from its lines, and page numbers and document identifiers sit in a quiet footer strip. It is designed to look correct in a tax auditor's hands.
Getting that right meant working around a real bug in Apache FOP: the footer that lied.
Open core, honestly drawn
What renders your invoice is open. What you pay for is not having to operate it.
Stylesheets — Apache-2.0
- The normalizers, the renderer, the themes, the i18n labels
- The full test corpus and blessed visual baselines
- The validation machinery (official CEN + Peppol + KoSIT + PINT A-NZ, pinned)
Container — licensed
- Deterministic PDF/A-3b with embedded fonts
- Factur-X / ZUGFeRD hybrid packaging
- Batch — resumable when driven by a manifest — an HTTP service, Prometheus metrics
- Spec-cycle SLA — updates within 3 weeks of each release
An expired license degrades gracefully — Faktorei never turns off your production rendering.
Built on the spec treadmill
The specification moves twice a year. So do we.
EN 16931, Peppol BIS, and XRechnung ship changes on a May/November cadence, with hotfixes in between. The national profiles do not all keep that calendar — PINT A-NZ versions on its own schedule, which is why we pin it by content hash rather than by release tag. Faktorei tracks all five pinned official artefact sets automatically (specwatch) and commits to shipping the updated stylesheets and validation within three weeks of each release, on whichever cadence it arrives — so the image you run always validates against the current, hotfixed rules. This is the treadmill the annual license buys you off of.
Render your own invoice against it in the next five minutes.
docker run -p 8080:8080 ghcr.io/faktorei/render:2025.11