Factur-X: the electronic invoice

Since 1 September 2026, every business in France registered for VAT has to be able to receive an electronic invoice, and the large and mid-sized ones have to send theirs in that form. Smaller businesses follow on 1 September 2027. An invoice that is only a well-made page stops counting as an invoice, and not issuing one electronically is charged at 50 € an invoice, up to 15 000 € a year.

An electronic invoice is not a PDF sent by e-mail. It is the invoice written out as entries a machine reads, in one of the three forms the French reform accepts: two of them are XML files with no page at all, and the third is Factur-X, a PDF carrying that XML inside it. Factur-X is the only one of the three a person can still open and read, and it is the one most used in France.

This file is one. A person opens it and sees the page: the work, the tax at twenty per cent, five thousand one hundred euros to pay. Accounting software opens the same file, finds the invoice attached inside it, and reads those same amounts without anybody retyping them. The two cannot contradict each other, because there is only one document — and what it carries is printed further down this page, pulled back out of the very file offered here.

What goes inside is yours to choose. This library writes any of the five levels of detail the standard defines: Minimum, the few entries a document needs to be booked at all; Basic WL, the head of an invoice with no lines; Basic, the lines as well; EN 16931, everything the European standard asks for; and Extended, everything again including what only some trades use. It writes the file as PDF/A-3, which is the shape an invoice keeps to be filed away for years, attaches your XML under the name you give it, and states in the document itself that the attachment is the invoice and not a file riding along. The same invoice is written from Rust, from Python, or as the description a program of yours posts to our address.

And what goes inside must match what the document says about it. A file declaring an EN 16931 invoice and carrying a minimum one is not a file we write: the invoice is read back before the document goes out, and the document is refused rather than sent out contradicting itself. The same for an invoice attached under a name the document carries no file under, and for a file that is no invoice at all. What the invoice says inside is yours and is not judged here — but the two halves of the file can no longer say different things.

What this example shows

  • One page: the work, the tax at twenty per cent, and five thousand one hundred euros to pay — and the same invoice inside the file, written as the XML that accounting software reads.
  • The document saying what it carries: an invoice, Factur-X version 1.0, the Minimum level of detail, attached under factur-x.xml and carried as the document's own data — and any of the five levels of detail, from Minimum to Extended, written the same way.
  • Handed to veraPDF, a free program with no hand in writing it, as a file fit for long-term keeping — and the invoice inside it pulled back out and compared with what went in.

The source code, complete

Nothing is left out and nothing is simplified: this is the program exactly as it runs, for the developer who uses this library. The third is the description itself: a plain list of what the page has to say, which is what the service is sent.

Read the Rust source Read the Python source Read the JSON source

The document itself

Open the document in English Open the document in French

Factur-X: the electronic invoice, first page

Optimised, this document weighs 23.0 kB — at least 80 % lighter than most PDF generators would write it

The document is lighter than it was, and every page still looks exactly the same. See this document's row in the table of every example.

The invoice hidden inside this file

Nothing here is written out beside the invoice: this is the attachment itself, all 1 977 bytes of it, pulled back out of the file above the way accounting software pulls it out. The invoice attaches it under factur-x.xml, states that it is an invoice following version 1.0 of the specification at its MINIMUM level of detail, and declares it the invoice's own data rather than a file that happens to ride along.

The Minimum level of detail carries what can be read below: who is selling and the number they are registered under, who is buying, the invoice's number and the day it was issued, the currency, and the three totals — before tax, the tax itself, and the amount to pay. The fuller levels add the lines of the invoice, the addresses, the payment details and the rest.

<?xml version="1.0" encoding="UTF-8"?>
<rsm:CrossIndustryInvoice
    xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
    xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
    xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
  <rsm:ExchangedDocumentContext>
    <ram:GuidelineSpecifiedDocumentContextParameter>
      <ram:ID>urn:factur-x.eu:1p0:minimum</ram:ID>
    </ram:GuidelineSpecifiedDocumentContextParameter>
  </rsm:ExchangedDocumentContext>
  <rsm:ExchangedDocument>
    <ram:ID>1964413</ram:ID>
    <ram:TypeCode>380</ram:TypeCode>
    <ram:IssueDateTime>
      <udt:DateTimeString format="102">20260714</udt:DateTimeString>
    </ram:IssueDateTime>
  </rsm:ExchangedDocument>
  <rsm:SupplyChainTradeTransaction>
    <ram:ApplicableHeaderTradeAgreement>
      <ram:SellerTradeParty>
        <ram:Name>Olivier Pons</ram:Name>
        <ram:SpecifiedLegalOrganization>
          <ram:ID schemeID="0002">123456789</ram:ID>
        </ram:SpecifiedLegalOrganization>
        <ram:PostalTradeAddress>
          <ram:CountryID>FR</ram:CountryID>
        </ram:PostalTradeAddress>
      </ram:SellerTradeParty>
      <ram:BuyerTradeParty>
        <ram:Name>ACME Ltd</ram:Name>
      </ram:BuyerTradeParty>
    </ram:ApplicableHeaderTradeAgreement>
    <ram:ApplicableHeaderTradeDelivery/>
    <ram:ApplicableHeaderTradeSettlement>
      <ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
      <ram:SpecifiedTradeSettlementHeaderMonetarySummation>
        <ram:TaxBasisTotalAmount>4250.00</ram:TaxBasisTotalAmount>
        <ram:TaxTotalAmount currencyID="EUR">850.00</ram:TaxTotalAmount>
        <ram:GrandTotalAmount>5100.00</ram:GrandTotalAmount>
        <ram:DuePayableAmount>5100.00</ram:DuePayableAmount>
      </ram:SpecifiedTradeSettlementHeaderMonetarySummation>
    </ram:ApplicableHeaderTradeSettlement>
  </rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>

Examples near this one

A sheet that measures what it says

Three rulers — centimetres, inches and points — on a page that tells whatever prints it to put it out at exactly the size it was drawn, and to offer nothing else. Lay a tape measure on the printed sheet and you can check for yourself.

A register whose pages say where they came from

Two sittings bound into one file. Each page carries a record of its own — what it is, whose hand wrote it, the day it was written — the photograph on the second page carries one too, and each transcription is tied to the page it transcribes rather than to the file at large.

A file that explains its own entries

A records office's reference, the department it came from, the date until which the document must be kept and its classification, carried inside a file an archive still accepts. No archiving rule knows what a keep-until date is, so each entry carries a description of itself, and that description is what makes a checker accept a fact you alone invented.

A delivery note that knows its own order

Every line of the note carries the order it was picked for, the article code and the shelf it came off, and prints none of them. The place where the driver signs carries the round and the van, and one beside the fold tick carries nothing but its own place.

A document that can be read aloud

Two pages carrying a copy of themselves that nobody sees: this is a heading, this is a table, and this is the order to read them in. Software reading the document aloud follows that instead of the order the marks were drawn in, and skips the running head. On the page, nothing looks any different.

A list whose pictures speak too

A parts list whose first column is a picture rather than a word. Each picture carries the sentence somebody hears in its place, so nothing in the list is lost on a reader who cannot see it. On the page, the pictures are simply pictures.

Every example, by subject