DEV Community

Olivier EBRAHIM
Olivier EBRAHIM

Posted on

Factur-X 2026 Implementation Cheatsheet for French Construction SaaS

Factur-X 2026 Implementation Cheatsheet for French Construction SaaS

Factur-X 2026 is no longer optional for French B2B invoicing. If you're building construction software (logiciel BTP), your invoice engine must emit valid Factur-X XML alongside PDF by January 2026. This cheatsheet cuts through the spec bloat and gives you the exact implementation path.

What is Factur-X 2026?

Factur-X = e-invoice standard (French "invoice" = "facture", hence the name). It's:

  • Mandatory for all B2B invoices in France starting Jan 2026
  • An XML file embedded inside the PDF or sent separately
  • Validates seller SIRET, buyer SIRET, VAT IDs, line items, payment terms
  • Machine-readable (no OCR needed by accountant software)
  • Compliant with EU Directive 2014/55/EU (cross-border standard)

If you don't support Factur-X: large clients (Décathlon, SNCF, etc.) will reject your invoices. SME construction teams will face penalties.

The Implementation Pipeline

Step 1: Choose Your Library (Don't Reinvent XML)

Node.js / JavaScript:

npm install --save factur-x-js
# or
npm install --save invoice-x
Enter fullscreen mode Exit fullscreen mode

Python:

pip install factur-x
# (official French standard library)
Enter fullscreen mode Exit fullscreen mode

PHP:

composer require denys-duchenko/facturx-generator
Enter fullscreen mode Exit fullscreen mode

Rule: Use a validated library, not hand-rolled XML. The spec is 100+ pages; libraries handle edge cases (namespace prefixes, character encoding, SIRET checksums).

Step 2: Gather Required Data

Before generating an invoice, ensure you have:

{
  "seller": {
    "name": "SARL Building Masters",
    "siret": "12345678901234",  // 14 digits, validated
    "siren": "123456789",       // 9 digits (first 9 of SIRET)
    "address": "123 Rue de la Paix, 75002 Paris",
    "vatId": "FR12345678901"    // VAT ID (optional but recommended)
  },
  "buyer": {
    "name": "Acme Corp",
    "siret": "98765432101234",  // SIRET or just VAT ID
    "vatId": "FR98765432101"
  },
  "invoice": {
    "number": "INV-2026-001",
    "issueDate": "2026-01-15",
    "dueDate": "2026-02-15",
    "currency": "EUR",
    "paymentTerms": "Net 30"
  },
  "lineItems": [
    {
      "description": "Placo pose chambre étage 2",
      "quantity": 8,
      "unit": "hours",
      "unitPrice": 65.00,
      "vatRate": 0.20,  // 20% is standard for construction labor
      "total": 624.00
    }
  ],
  "totalExcludingVat": 624.00,
  "totalVat": 124.80,
  "totalIncludingVat": 748.80,
  "paymentMethod": "SEPA",
  "bankAccount": {
    "iban": "FR1420041010050500013M02606",
    "bic": "PCHQFRPP"
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Generate the Factur-X XML

import { generateFacturX } from 'factur-x-js';

const invoice = {
  // ... data from Step 2
};

const facturXXml = await generateFacturX(invoice, {
  format: 'BASIC',  // or 'EXTENDED' (BASIC is sufficient for SMEs)
  languageId: 'fr'
});

console.log(facturXXml); // Valid XML string, ready to embed
Enter fullscreen mode Exit fullscreen mode

Format choice:

  • BASIC: Covers 90% of construction invoices (seller, buyer, line items, totals)
  • EXTENDED: Adds purchase order references, delivery notes, project codes
  • For SME BTP, start with BASIC. Upgrade to EXTENDED only if clients demand it.

Step 4: Embed XML in PDF or Send Separately

Option A: Embed in PDF (Recommended)

Use a library that embeds Factur-X XML as PDF attachment:

import PDFDocument from 'pdfkit';
import fs from 'fs';

const pdfDoc = new PDFDocument();
const pdfStream = fs.createWriteStream('invoice.pdf');

pdfDoc.pipe(pdfStream);
pdfDoc.fontSize(12).text('Invoice INV-2026-001');
pdfDoc.text(`Total: €${invoice.totalIncludingVat}`);
pdfDoc.end();

// Then attach Factur-X XML to the PDF
// (library-specific; pdfkit doesn't support this natively, use pdf-lib or similar)
Enter fullscreen mode Exit fullscreen mode

Better approach: Use php-invoice-x (PHP) or Factur-X-Lib (Python) which handle PDF + XML embedding directly.

Option B: Send XML Separately

Some workflows require the XML as a separate file:

POST /api/v1/invoices/send
{
  "invoiceId": "INV-2026-001",
  "recipientEmail": "buyer@acme.com",
  "attachments": [
    {
      "filename": "INV-2026-001.pdf",
      "mimeType": "application/pdf"
    },
    {
      "filename": "INV-2026-001.xml",
      "mimeType": "application/xml",
      "content": "<facturx>...</facturx>"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Large clients often prefer XML separately for automation.

Step 5: Validate & Test

Before shipping to production:

# Command-line validation (Linux/macOS)
java -jar facturx-validator.jar invoice.pdf

# Online validator
# https://www.codelint.net/facturation/facturx/
Enter fullscreen mode Exit fullscreen mode

Common errors:

  • ❌ SIRET format invalid (must be 14 digits, numeric only)
  • ❌ VAT ID mismatch (France = "FR" + 11 digits)
  • ❌ Line item VAT rate missing
  • ❌ Currency not EUR
  • ❌ Date format (must be YYYY-MM-DD)

Fix these before production. A single invalid invoice breaks downstream accounting software.

Step 6: Archive & Audit Trail

Store the Factur-X XML alongside the PDF:

{
  "invoiceId": "INV-2026-001",
  "pdfUrl": "s3://bucket/INV-2026-001.pdf",
  "facturXUrl": "s3://bucket/INV-2026-001.xml",
  "generatedAt": "2026-01-15T10:30:45Z",
  "validatedAt": "2026-01-15T10:30:50Z",
  "sentAt": "2026-01-15T10:31:00Z"
}
Enter fullscreen mode Exit fullscreen mode

French tax authorities can audit XML files. Keep them immutable.

Integration Checklist

  • [ ] SIRET/SIREN database lookup (validate seller/buyer existence)
  • [ ] VAT ID format validation (REGEX or library)
  • [ ] Line item VAT rates (20% labor, 10% materials, 5.5% social housing, 2.1% books/medicine)
  • [ ] PDF + XML generation tested with validator
  • [ ] Unit tests for edge cases (SIRET with zeros, multi-currency conversion if applicable)
  • [ ] Error handling: invalid SIRET → user-friendly message ("Validate SIRET on societe.com first")
  • [ ] Audit log: every invoice generation logged with operator ID + timestamp
  • [ ] Backup: nightly export of all Factur-X XMLs to cold storage
  • [ ] Deadline: January 2026 (but deploy by October 2025 to let clients test)

Common Pitfalls (Based on Real Deployments)

Pitfall What Happens How to Avoid
Hard-code VAT rates Labor = 20%, materials = 10% (French rule). Hard-code wrong. Use a lookup table, let accountant verify quarterly
SIRET validation via regex only Fake SIRETs pass validation. Buyers reject invoice. Validate against INSEE database (free API exists)
PDF without XML Compliant with 2024, not 2026. Late discovery. Generate both, embed early, test in staging
No timezone on timestamps Auditor can't reconcile invoice time with payment time. Always use ISO 8601 with UTC (+00:00)
XML encoding utf-8 vs latin1 Accents (Côte, Île) break parsing. Force UTF-8; validate before embedding

Real-World Example: Anodos Invoice Flow

At Anodos, we handle 500+ invoices/month for French construction SMEs. Our flow:

  1. Foreman creates estimate → AI voice-to-quote → generates line items
  2. Site manager converts to invoice (one-click)
  3. Backend:
    • Validates seller/buyer SIRET (5ms lookup)
    • Calculates VAT (20% for labor, 10% for materials, per French rules)
    • Generates Factur-X XML (using factur-x library)
    • Embeds XML in PDF (using pdf-lib)
    • Stores both in S3
  4. Email sent with PDF + XML (optional separate file)
  5. Accountant receives machine-readable invoice (no re-keying)

Result: Zero rejected invoices (since adoption in May 2025), 60% faster accounting reconciliation.

Resources

Conclusion

Factur-X 2026 is mandatory in 9 months (January 2026). For construction SaaS:

  • Use a validated library (don't reinvent).
  • Validate SIRET + VAT early.
  • Test with French accountant software before launch.
  • Plan for Q4 2025 deployment so clients can test before the deadline.

Your invoices will be machine-readable, audit-proof, and compliant. Accountants will love you. Anodos did it—so can you.


Olivier Ebrahim

Founder, Anodos — Real-time job site management for French construction SMEs

Top comments (0)