R&D LAB Method In use Built for our own bookkeeping
Belegt
ZUGFeRD e-invoicing, self-hosted
Since 2025 a German invoice is a file a machine has to read. Belegt produces it in-house: the XML first, then the PDF, on our own hardware.
- PDF/A-3boutput with an embedded factur-x.xml
- 20rule codes checked offline, in-house
- 4steps in the wizard before a file exists
- 0invoice records that leave the house

Every figure in this article shows invented demo data. The working database was not opened for the capture.
Why this is published
We sell software and automation. Belegt is the evidence for that on an uncomfortable example: a regulated task, a fixed format, real deadlines, our own data. The tool runs in our own operation, not in a demo. Anyone who wants to know how we cut a line-of-business application, where we put rules hard into the code and where we leave the decision to a person, can see it here on our own bookkeeping.
Since 1 January 2025, companies in Germany have had to be able to receive electronic invoices in B2B trade; the duty to send them follows in stages until 2028. A PDF attached to an email no longer satisfies that. What is required is a structured data set to EN 16931, in practice ZUGFeRD or Factur-X. Belegt is our own answer to it, built because we needed it ourselves.
The decision
The XML is the document, the PDF is the view
Anyone building an e-invoice for the first time starts at the PDF. That is the mistake that gets expensive later. A ZUGFeRD document is a PDF/A-3 with a file called factur-x.xml attached to it, and when the two disagree, an accounting system goes by the attachment. So we reversed the order: Belegt builds the data set first, generates the XML from it, and renders the PDF as a view of that.
This one decision drags the rest along behind it. Because the XML is the document, checking has to happen before anything is generated, not after. Because it is the document, it is the thing that gets stored and hashed when the invoice is finalised, with the PDF lying beside it. And because it is the document, styling stops where it would touch machine readability.
The second reason for building it ourselves was less elegant. Invoice data is the densest collection of other people's master data a small company keeps: addresses, tax numbers, bank details, project names. A subscription billed per document takes that collection with it. Belegt puts it in a file on our own hardware; the sensitive fields sit there encrypted with AES-256-GCM, the key outside the source code.
What deliberately did not come out of this is legal advice. The application checks against the business rules of the standard, as far as they can be checked without a network. Legal certification of a document is done by the official KoSIT validator, and nothing here replaces it.
If the PDF and the XML disagree, the XML wins. So that is where you start.
How a document is made
Four steps, and only then a file
- 01 Draft Issuer, client, number and period, then the line items. Master data and the service catalogue are already stored. The suggested number is only a preview at this point: it reads the counter without moving it.
- 02 Check Before anything is generated, a rule set runs over the data: twenty named rules from EN 16931, from the reverse-charge annex and from the German XRechnung extension. Blocking findings appear as errors with their rule code, advisory ones separately.
- 03 Build the XML The checked data set becomes a CrossIndustryInvoice carrying the identifier urn:cen.eu:en16931:2017. In XRechnung mode the KoSIT identifier is added, and the Leitweg-ID moves from an advisory note to a requirement.
- 04 PDF/A-3b with attachment The PDF is typeset with embedded fonts, marked as PDF/A-3b, and receives factur-x.xml as an attachment with the relationship Alternative. On finalising, the data set, the XML, the PDF and a SHA-256 of the XML are stored.
The check comes before the file
The check runs entirely on the local machine. It knows twenty rule codes, recomputes the totals against the line items, and keeps a strict line between blocking and advisory: a missing IBAN does not stop a B2B document, an incomplete buyer address does.
What it is not is stated in the same view: a pre-flight without Java, not a replacement for the official KoSIT or Mustang validator. Legal certification of a document remains the job of that external run.
Structure
One data set, two readers
- Master dataClient, payment term, tax case
- Service catalogueLine items with unit and rate
- Number rangePrefix, year, month, running number
- The visible invoicePDF/A-3b, tied to the brand
- Embedded XMLfactur-x.xml to EN 16931
- Bookkeeping exportDATEV and CSV, SKR03 or SKR04
A single data set produces both the page a person reads and the record a machine reads. Both are stored together on finalising; the XML is additionally hashed.
What happens after it goes out
The second half of the work on an invoice begins once it has gone out. Belegt keeps receivables in a view of their own: days to the due date, dunning level, and the amount that late-payment interest would add if a reminder went out.
The dunning level does not climb by itself. It is a field on the document that someone sets, and the reminder is a button that someone presses. A tool that chases clients unattended is a risk rather than a relief in an operation with a handful of clients.
Dated drafts sit in the same view, fully prepared. They too do not leave on their date by themselves; they wait to be opened and sent.
What changed in 2025
PDF by email, until 2024
- A picture of an invoice. The figures on it are text inside a layout.
- Bookkeeping retypes them, or lets a recogniser guess.
- A transposed digit surfaces at reconciliation, at the earliest.
- Every recipient builds their own rule for your particular layout.
E-invoice to EN 16931, from 2025
- A structured data set. Every field carries a code from the standard.
- Bookkeeping imports it; the PDF beside it is for people.
- Business-rule violations surface before the document is sent.
- One format for every recipient, with an extension for the public sector.
What is hard-coded
The application, on invented data
What it was built for
- Small service firms that must be able to receive from 2025 and to send by 2028, without paying per document.
- Operations with few but recurring clients: retainers and project call-offs run through the same catalogue.
- Cross-border services inside the EU, where the tax case hangs on the client record and not on someone's memory.
- Anyone who does not want their client and bank data sitting in somebody else's tenant database.
- As a template: the same construction for another regulated form-filling job inside your own operation.
“What advantages does double-entry bookkeeping bring the merchant! It is among the finest inventions of the human mind.”
Why this is published
What this means for your project
More from the lab
Method Event Scout A language model reads the event pages; everything else is fixed code. What remains is a short list of where a day in person is worth it.
Applied Research Vellum Edges, perspective, light and text are all worked out on the phone. A document leaves the device only when someone sends it.
Computational Design Atlas EV1 Twelve chapters take an electric car apart, down to a single cell. No model files, no textures: 327 parts generated from one dimension table. Do you have a regulated form-filling job that someone is holding together by hand? That is exactly what a pilot is for.
Get in touch