En bref
- Retour d’expérience : un éditeur ERP BTP a intégré la conformité Factur-X en 3 jours-homme d’un développeur senior.
- Mode ERP-assisted (
invoice_dataJSON) : les données sont déjà structurées dans l’ERP, pas d’OCR nécessaire. - Jour 1 : mapping ERP → JSON
invoice_data. Jour 2 : intégration API + gestion d’erreurs. Jour 3 : tests, idempotence, CI/CD. - ~500 factures/mois en production, coût fixe 5 unités par conversion.
- Prérequis : ERP avec données exportables, développeur connaissant le modèle de données et les cas métier.
Un éditeur ERP spécialisé dans le BTP devait rendre ses factures conformes Factur-X avant l’échéance de la réforme. Le contexte : un logiciel métier mature, un pipeline PDF existant qu’il ne fallait pas réécrire, aucun expert XML ou PDF/A dans l’équipe, et ~500 factures par mois en production.
Ce retour d’expérience décrit un cas favorable : ERP déjà structuré avec données exportables, développeur senior, usage du mode ERP-assisted (invoice_data). Le temps d’intégration varie selon la maturité de vos données et la complexité de vos cas métier.
L’intégration via API a pris 3 jours-homme d’un développeur senior. Pas 3 jours calendaires pour un junior qui découvre EN16931 — 3 jours pleins d’un développeur qui connaissait le modèle de données de l’ERP et les cas métier BTP. Voici les étapes concrètes.
Jour 1 : le mapping ERP vers JSON
La première journée a été consacrée à un seul objectif : construire l’objet invoice_data attendu par l’API à partir des tables existantes de l’ERP.
Identifier les Business Terms
EN16931 définit des Business Terms (BT) numérotés : BT-1 pour le numéro de facture, BT-2 pour la date d’émission, BT-27 pour le nom du vendeur, etc. Le travail consiste à trouver, dans les tables de l’ERP, quelle colonne correspond à chaque BT obligatoire.
Pour un ERP BTP français, les champs fondamentaux existaient : numéro, date, SIRET, TVA intra, lignes de détail. L’essentiel du mapping s’est fait mécaniquement. Le guide complet est dans Données ERP vers Factur-X CII : mapper JSON vers XML EN16931.
Les points de friction réels
Trois transformations de format ont consommé du temps :
Le format de date. L’ERP stockait les dates en ISO 8601 (2026-04-13). L’API attend le format CII, soit 20260413 — sans tirets. Une transformation triviale, mais qu’il faut appliquer à chaque champ date : issueDate, dueDate, deliveryDate.
Les identifiants fiscaux. Le SIRET (14 chiffres) est le legalId du bloc seller, avec un schemeID implicite 0002 pour la France. Le numéro de TVA intracommunautaire (FR32123456789) est le vatId. L’ERP stockait les deux dans un même bloc “identifiants entreprise” — il a fallu les séparer explicitement.
Le code devise. L’ERP gérait la devise comme un libellé (“Euro”) plutôt qu’un code ISO 4217. Le remplacement par EUR dans le champ currencyCode était immédiat, mais c’est le genre de détail qui fait échouer silencieusement la validation si on l’oublie.
Le cas spécifique BTP : l’autoliquidation
Le BTP a une particularité majeure : l’autoliquidation de TVA sur la sous-traitance (article 283, 2 nonies du CGI). Le sous-traitant facture hors taxe, l’entreprise principale autoliquide. En termes de mapping :
vatCategorypasse deS(Standard) àAE(Reverse Charge)vatRatepasse à0- Un motif d’exonération (
vatExemptionReason) est obligatoire :"Autoliquidation - art. 283, 2 nonies du CGI"
Côté EN16931, le code d’exonération interopérable est VATEX-EU-AE. En complément, la facture française doit porter la mention “Autoliquidation” conformément au CGI. Les deux informations peuvent coexister dans le XML (BT-121 pour le code, BT-120 pour le texte).
L’ERP gérait déjà le flag “autoliquidation” — il a suffi de le traduire en code AE dans le JSON. Sans ce mapping, les règles Schematron BR-AE-* rejettent systématiquement la facture. Les erreurs spécifiques sont documentées dans Les erreurs Factur-X qui bloquent vos factures BTP.
Bilan du jour 1 : une fonction d’extraction qui transforme un objet facture ERP en JSON invoice_data conforme.
Jour 2 : l’appel API et la gestion des erreurs
L’intégration HTTP proprement dite : appeler l’API, traiter les réponses, gérer les erreurs.
Premier appel
L’appel /api/v1/convert prend le PDF existant (inchangé) et le JSON invoice_data du jour 1. L’API génère le XML CII, l’embarque dans le PDF, convertit en PDF/A-3, et renvoie le Factur-X complet. Le pipeline PDF existant n’est pas modifié. Les deux modes de conversion sont détaillés dans Convertir une facture PDF en Factur-X 1.08 conforme.
Premier appel avec une facture réelle : erreur insufficient_data. Le JSON ne contenait pas tous les champs conditionnellement obligatoires.
Les erreurs rencontrées en production
Deux types d’erreurs ont dominé les premiers tests :
insufficient_data — champs manquants. L’API valide le JSON en amont et signale les absences avant la génération XML. Champs manquants fréquents : buyer.address.country (obligatoire même sans adresse complète), au moins un identifiant vendeur parmi BT-29 (identifiant commercial), BT-30 (identifiant légal) ou BT-31 (identifiant TVA) doit être présent (règle BR-CO-26), dueDate quand un code de paiement est fourni.
totals_mismatch — incohérence arithmétique. EN16931 impose des règles strictes : somme des nets de ligne = total net (BR-CO-13), TVA calculée = total TVA déclaré (BR-CO-14). L’ERP calculait les totaux avec des arrondis intermédiaires différents — un écart de 0.01 EUR suffisait au rejet.
Correction : arrondir chaque ligne au centime, puis sommer les lignes arrondies, plutôt que sommer puis arrondir le total.
Idempotency et retries
Chaque appel est associé à une clé d’idempotence basée sur le numéro de facture. En cas de timeout ou d’erreur réseau, le retry avec la même clé garantit l’absence de doublon :
curl -X POST https://api.facturxapi.com/api/v1/convert \
-H "Authorization: Bearer $API_KEY" \
-H "Idempotency-Key: INV-2026-04-0042" \
-F "[email protected]" \
-F 'invoice_data={"invoiceNumber":"INV-2026-04-0042",...}'
Bilan du jour 2 : un appel API fonctionnel, avec gestion des erreurs métier et réseau, testé sur une dizaine de factures représentatives.
Jour 3 : les cas spéciaux et la mise en production
Les variantes métier non testées au jour 2, puis la mise en production.
Avoirs (note de crédit)
Un avoir utilise le typeCode 381 au lieu de 380. Point d’attention : les montants d’un avoir sont positifs dans le XML CII, contrairement aux ERP qui stockent parfois des montants négatifs. L’API gère ce cas correctement si le typeCode est déclaré.
Multi-taux TVA
Un chantier de rénovation peut combiner 20% (gros oeuvre) et 10% (travaux d’amélioration, logement > 2 ans). Le JSON doit regrouper les lignes par taux dans le bloc vatBreakdown, avec un sous-total par catégorie. L’ERP calculait déjà ces sous-totaux — conversion directe.
Autoliquidation mixte
Le cas le plus subtil : un chantier où certaines lignes sont en autoliquidation (sous-traitance, AE) et d’autres en TVA standard (S). Chaque ligne porte son propre vatCategory, et le vatBreakdown doit contenir une entrée pour chaque combinaison catégorie/taux rencontrée. L’erreur classique est de déclarer un vatBreakdown global unique quand les lignes sont hétérogènes.
Validation systématique avant envoi PDP
Avant d’envoyer une facture à la Plateforme de Dématérialisation Partenaire (PDP), le pipeline valide systématiquement le Factur-X généré via l’endpoint /validate. Cette étape coûte quelques centaines de millisecondes mais évite les rejets en aval, qui impliquent des délais de correction et de renvoi. Pour les détails de la validation XSD et Schematron, voir Valider EN16931/Factur-X : XSD vs Schematron, erreurs BR-*.
Monitoring des premières semaines
L’éditeur a suivi les taux d’erreur sur les 4 premières semaines : factures traitées, succès première passe, erreurs par type. Ce monitoring a permis de détecter les cas de données ERP incomplètes (opérateur qui omet le code postal acheteur, par exemple) et de les corriger rapidement.
Résultat en production
Après 3 mois d’exploitation sur le parc client :
| Indicateur | Valeur |
|---|---|
| Volume mensuel | ~500 factures/mois |
| Taux de conformité première passe | > 95% |
| Cause des 5% restants | Données ERP incomplètes (saisie opérateur) |
| Temps d’intégration total | 3 jours-homme (développeur senior) |
| Modification du pipeline PDF existant | Aucune |
Les 5% d’échecs ne sont pas des bugs d’intégration mais des erreurs de saisie dans l’ERP : code postal manquant, numéro de TVA mal formaté, montant de ligne à zéro. L’API renvoie un message explicite, l’opérateur corrige et relance. Ces erreurs se concentrent sur les premières semaines d’utilisation par un nouvel opérateur, puis disparaissent.
Les prérequis pour reproduire ce résultat
Toute intégration ERP suit le même schéma si les prérequis sont remplis.
Votre ERP doit exposer les données comptables. Pas nécessairement via une API REST — une requête SQL sur les tables de facturation suffit. L’important : accéder aux données structurées (numéro, date, montants, lignes, identifiants fiscaux).
Vous devez connaître vos cas de TVA. Chaque combinaison correspond à un code vatCategory : S (Standard), AE (autoliquidation), E (Exempt), Z (Zero rated). Cet inventaire est un prérequis au mapping.
Vous devez disposer d’un identifiant vendeur valide. Au moins un identifiant vendeur parmi BT-29 (identifiant commercial), BT-30 (identifiant légal) ou BT-31 (identifiant TVA) doit être présent (règle BR-CO-26). Pour une entreprise française, le couple SIRET + TVA intra est le plus robuste.
Le reste est géré par l’API. Génération XML CII D22B, conversion PDF/A-3, validation XSD et Schematron, packaging avec AFRelationship correct — tout ce qui relève de la norme est délégué. C’est ce qui permet une intégration en 3 jours plutôt qu’en 3 mois.
Erreurs fréquentes et fiches de diagnostic
- BT-131 — Montant net de ligne — base quantity oubliée sur les prix au m²/lot
- BR-AE-05 — Autoliquidation — sous-traitance BTP
- BR-05 — Code devise — premier champ oublié en migration ERP
- Format date 102 — conversion ISO → yyyymmdd en sortie d’ERP
- Mapping ERP → JSON complet — guide de référence pour
invoice_data
Les 22 fiches unitaires : catalogue complet des erreurs BR-*.
Et maintenant ?
Convertir mon PDF en Factur-X →
curl -X POST https://api.facturxapi.com/api/v1/convert \
-H "Authorization: Bearer VOTRE_CLE" \
-F "[email protected]"
10 opérations gratuites par mois, sans carte bancaire. Obtenir une clé API.
Aller plus loin
- Données ERP vers Factur-X CII : mapper JSON vers XML EN16931 — le guide complet du mapping JSON, avec tous les champs, les cardinalités et les cas spéciaux
- Convertir une facture PDF en Factur-X 1.08 conforme — les deux modes de conversion (extraction PDF et données ERP), avec exemples curl, Python et Node.js
- Les erreurs Factur-X qui bloquent vos factures BTP — diagnostic et correction des erreurs spécifiques au BTP (autoliquidation, factures de situation, retenue de garantie)
- Valider EN16931/Factur-X : XSD vs Schematron, erreurs BR-* — comprendre les deux niveaux de validation et déboguer les erreurs
- Automatiser la validation Factur-X dans votre pipeline CI/CD — intégrer la validation dans un workflow automatisé pour les volumes importants
- Checklist développeur : préparer la réception obligatoire du 1er septembre 2026 — tout ce qu’il faut livrer avant l’échéance réglementaire