Your HTML-to-PDF Invoices Just Stopped Being Legal in France: Factur-X, PDF/A-3 and the September 2026 Mandate

Since 1 September 2026, every VAT-registered business in France must be able to receive structured e-invoices, and large and mid-sized enterprises must be able…

Since 1 September 2026, every VAT-registered business in France must be able to receive structured e-invoices, and large and mid-sized enterprises must be able to issue them [1]. If your SaaS still emails HTML-rendered PDFs to French customers, those invoices stopped being legal weeks ago. The obligation is not suspended, even though no penalty will be applied to any business in 2026 [2].

What changed on 1 September 2026

The French e-invoicing reform that has been delayed since 2023 finally took effect. VAT-registered businesses must now receive invoices in one of three structured formats: UBL 2.1, CII, or Factur-X [1]. Large and mid-sized enterprises had to start issuing through approved platforms on the same date [1]. SMEs and micro-enterprises have until 1 September 2027 to begin issuing [1].

For invoices within the issuing obligation, an ordinary email attachment has not been a compliant channel since 31 August 2026 [2]. Instead, an approved platform (PA) — a private operator registered by the DGFiP for a renewable three-year term — is the only transmission channel [2]. The Finance Act for 2026 replaced the earlier term PDP (plateforme de dématérialisation partenaire) with plateforme agréée (PA) throughout the tax code [2].

The French ministry announced on 1 September 2026 that no penalty would be applied to any business in 2026, and the DGFiP practical guide sets out what the administration will weigh: real, documented difficulties followed by corrective action [2]. When penalties do begin, the amended Loi de Finances pour 2026 sets them at €50 per invoice, up from €15, with an annual cap of €15,000 [3].

Factur-X is just PDF/A-3 with an XML passenger

Factur-X is a hybrid format: a human-readable PDF/A-3 container with an embedded UN/CEFACT CII XML file carrying the structured invoice data [1]. The arrêté of 27 July 2026 sets five accepted formats; the hybrid format must conform to AFNOR standard XP Z12-012 [2].

PDF/A-3 is specifically required because it is the only PDF/A variant that permits embedding files such as the invoice XML [1]. Since ZUGFeRD 2.0, Factur-X and Germany's ZUGFeRD share the same UN/CEFACT CII XML syntax and EN 16931 semantic standard, making well-formed files structurally interchangeable [1]. Factur-X defines multiple profiles, with EN 16931 (Comfort, ~100 fields) recommended for France [4].

The visual layer is PDF/A-3. The compliance layer is valid CII XML. Both must be correct.

Four mechanical requirements your pipeline must satisfy

Generating a Factur-X invoice is not simply "print to PDF and attach an XML file." Four specific mechanical requirements determine whether a file passes validation:

  • The container must be genuine PDF/A-3b. This means embedded fonts, an sRGB OutputIntent, and XMP pdfaid metadata. Chromium's plain PDF output does not install or embed fonts by itself; the PDFik worker image adds DejaVu, Lato, Open Sans, Roboto and Noto fonts on top of the Playwright base.
  • The attachment must be named factur-x.xml and declared in the /AF (Associated Files) dictionary.
  • The AFRelationship value must match the profile: Data for MINIMUM and BASIC WL; Alternative for BASIC, EN 16931, and EXTENDED. Check the default in your library — some default to Data for all profiles, and not every validator catches this mismatch even though it fails specification compliance.
  • The XMP extension schema must declare fx:DocumentType, DocumentFileName, Version, and ConformanceLevel with exact spelling, including the space in 'EN 16931'. A typo here fails veraPDF structural validation.

You can still design invoices with CSS, custom fonts, and responsive layouts. But the PDF that reaches your customer must be normalised to PDF/A-3b, and the XML must be embedded with profile-correct metadata.

A concrete pipeline for HTML-template shops

If you already generate invoice PDFs from HTML templates, you can adapt your pipeline rather than replace it. The pattern is: one data source produces both the human-readable PDF and the structured XML, then a normalisation step binds them together.

Render your invoice from an HTML template as before. MarkupGo's API accepts a template ID and context data, using Handlebars syntax with {{ variable }} placeholders and {{#each items}} loops for line items [5]. The online editor lets you iterate designs without touching compliance code [5].

After rendering, normalise to PDF/A-3b. Tools like pikepdf can embed fonts, set the OutputIntent, and fix XMP metadata. Generate valid EN 16931 CII XML from the same invoice data source — this is your accounting system's responsibility, not the renderer's.

Embed the CII XML with the profile-correct AFRelationship. Validate the container with veraPDF and the structure/XML with Mustang. You must ensure your data pipeline feeds identical values to both outputs.

Germany already started, and ViDA is coming for everyone

France is not an outlier. Every German business has had to be able to receive e-invoices since 1 January 2025; suppliers with over €800,000 turnover in 2026 must issue from 1 January 2027, and from 1 January 2028 practically all domestic B2B invoices are covered [6].

Under EU ViDA, mandatory B2B e-invoicing and Digital Reporting Requirements for intra-Community transactions take effect 1 July 2030, with full harmonisation of domestic reporting systems by 1 January 2035 [7].

Where MarkupGo fits in your compliant pipeline

MarkupGo handles the HTML-to-PDF rendering half of this pipeline: template with Handlebars variables, loops for line items, API call with template ID and context [5]. Reusable templates and the online editor let you iterate invoice designs without touching compliance code [8][5]. Integration with Make.com and Google Sheets automates generation from spreadsheet rows [8].

The PDF/A-3 normalisation and XML embedding steps sit downstream of rendering. MarkupGo gives you the visual layer; you add the structured payload. Existing blog guides cover Stripe invoices [8], Google Sheets invoices, and QR-code invoices — the same templates, now feeding a hybrid pipeline.

A typical MarkupGo API call for the rendering stage:

fetch("https://api.markupgo.com/api/v1/pdf", {
  method: "POST",
  headers: {
    "x-api-key": process.env.MARKUPGO_API_KEY,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    source: {
      type: "template",
      data: {
        id: process.env.INVOICE_TEMPLATE_ID,
        context: {
          // invoice data matching your template's Handlebars variables
          invoice_number: "FR-2026-00042",
          items: [
            // see MarkupGo's API reference for full context structure
          ]
        }
      }
    }
  })
})
.then(res => res.json())
.then(task => {
  // task.url contains the rendered PDF
  // pass this to your PDF/A-3 normalisation and XML embedding step
});

The context object must match your template's {{ variable }} placeholders exactly. For line items, use {{#each items}} with fields like item_name, qty, rate, and amount [5].

Your next steps

Audit whether any of your customers are French VAT-registered or mid-size/large enterprises. Check if your current PDF output passes PDF/A-3b — raw Chromium does not install or embed fonts by itself. Identify who produces your EN 16931 CII or UBL XML; if nobody, that is your real blocker.

Build the hybrid pattern now: one data source → structured XML + human-readable PDF. Test with veraPDF and Mustang before your first production invoice. The 2026 penalty holiday is not a reason to wait; it is time to build without the pressure of immediate fines.

Additional resources

  • MarkupGo's guide to generating PDF invoices from HTML templates covers dynamic data, Handlebars loops, and reusable template IDs [5].
  • The Stripe payment event integration shows how to trigger branded PDF generation from webhooks [8].
  • The Google Sheets automation guide demonstrates no-code automation by connecting Google Sheets, Make.com, and MarkupGo [8].

Leave a comment if you have implemented Factur-X or ZUGFeRD in production — which normalisation tool did you choose, and what validation failures caught you first?

Sources

  1. pdfa.org
  2. e-invoice.app
  3. e-Invoicing France 2026: Timeline, Requirements, Guidelines and Format (cleartax.com)
  4. Factur-X Technical Guide: France's Hybrid E-Invoice Format Explained (invostaq.com)
  5. markupgo.com
  6. E-Invoicing in Germany 2027: XRechnung and ZUGFeRD Explained (invoiceradar.com)
  7. EU Guide to VAT in the Digital Age (ViDA) (vertexinc.com)
  8. markupgo.com