En bref
- Le parcours dépend de votre version de Dolibarr et du module ou connecteur choisi. Vérifiez leurs compatibilités documentées et testez un fichier réellement généré.
- En France CTC, BT-30 porte le SIREN vendeur à 9 chiffres, avec
schemeID="0002". Le SIRET identifie un établissement; son mapping est distinct. - Les factures multi-taux et les arrondis peuvent produire des incohérences de totaux. Vérifiez la ventilation TVA par catégorie et taux.
- Pipeline : Dolibarr génère → validation documentaire → correction des données à la source ou réparation XML pour les corrections couvertes → régénération et revalidation.
/repairreçoit et renvoie du XML; il ne répare pas l’enveloppe PDF.
Dolibarr est un ERP/CRM open source utilisé par des entreprises et intégrateurs. Ce guide présente les points à vérifier pour préparer les données et contrôler les exports Factur-X.
Depuis le 1er septembre 2026, les entreprises dans le champ de la réforme doivent pouvoir recevoir les factures électroniques via la Plateforme Agréée choisie. L’émission est obligatoire à cette date pour les grandes entreprises et ETI, puis au 1er septembre 2027 pour les PME et micro-entreprises. Le PPF assure l’annuaire et la concentration des données; il n’est pas une alternative à la PA pour échanger les factures. Voir le calendrier de la DGFiP et le rôle des plateformes agréées.
Si votre flux utilise Factur-X, le fichier associe un PDF/A-3 et un XML CII. Vérifiez le profil documentaire et les contrôles France CTC applicables; un résultat de validation documentaire ne prouve pas l’acceptation par la PA.
Pour le contexte complet de la réforme et du calendrier, voir Facturation électronique 2026 : le guide technique complet.
Le module Factur-X dans Dolibarr
Le parcours de génération et d’échange dépend du module ou connecteur installé. La documentation du projet Dolibarr sur la facturation électronique décrit les solutions disponibles. Certains modules utilisent la bibliothèque PHP atgp/factur-x, publiée par @GP; d’autres ont leurs propres dépendances.
Vérifier la version de Dolibarr
Avant installation, relevez votre version Dolibarr, la version du module, ses dépendances, les profils produits et la documentation de son connecteur PA. Vérifiez la matrice de compatibilité publiée par le mainteneur et conservez ces versions avec vos résultats de test. Un numéro de version Dolibarr seul ne prouve pas la conformité d’un export.
Installer le module
Suivez d’abord la procédure du mainteneur. Pour un module distribué sous forme d’archive, les étapes habituelles sont :
- Télécharger le module depuis le DoliStore ou le dépot GitHub du développeur
- Extraire l’archive dans le répertoire
htdocs/custom/de votre installation Dolibarr - Aller dans Accueil > Configuration > Modules/Applications
- Chercher “Factur-X” dans la liste et activer le module
- Configurer le module via le lien Configuration qui apparait après activation
Après installation, le module ajoute généralement une option dans la génération PDF des factures : lors de la création ou du téléchargement d’une facture, un bouton ou une option permet de générer la version Factur-X.
Configuration des informations société
La conformité EN16931 commence par la fiche société de Dolibarr. Les champs renseignés dans Accueil > Configuration > Société/Organisation alimentent directement les nœuds XML du vendeur (BG-4).
SIREN — BT-30, identifiant légal du vendeur en France CTC
Pour le mapping France CTC, BT-30 porte le SIREN vendeur à 9 chiffres avec schemeID="0002"; BT-47 porte le SIREN acheteur. Le SIRET à 14 chiffres identifie un établissement et reste dans le champ prévu pour cet usage, notamment BT-29 avec schemeID="0009" selon le flux. Les adresses électroniques BT-34 et BT-49, avec le schéma 0225 en France CTC, ont une fonction de routage distincte.
Vérifiez le mapping réel du module depuis les champs d’identité de la société et des tiers. Ne remplacez pas un SIRET métier déjà présent par un SIREN dans un champ qui attend un établissement. L’annexe de mapping FNFE-MPE, dans son édition historique 1.2, distingue ces usages; confrontez votre implémentation aux ressources normatives actuelles.
Ce fragment est un gabarit à renseigner, pas une facture valide :
<ram:SellerTradeParty>
<ram:Name>RAISON_SOCIALE_VENDEUR</ram:Name>
<ram:SpecifiedLegalOrganization>
<ram:ID schemeID="0002">SIREN_VENDEUR_9_CHIFFRES</ram:ID>
</ram:SpecifiedLegalOrganization>
</ram:SellerTradeParty>
Dans le socle EN16931, BR-CO-26 exige au moins un identifiant vendeur parmi BT-29, BT-30 et BT-31. Cette alternative ne dispense pas de renseigner le SIREN demandé par votre cible France CTC.
Pour la cartographie complète des BT obligatoires, voir Champs obligatoires EN16931 : cartographie et mapping ERP.
TVA intracommunautaire — BT-31
Le numéro de TVA intracommunautaire (BT-31) se configure dans la fiche société. Le fragment ci-dessous est un gabarit à renseigner avec le numéro réel. Format attendu : FRXX999999999 (préfixe pays + clé + SIREN). Le schemeID dans le XML doit être VA.
<ram:SpecifiedTaxRegistration>
<ram:ID schemeID="VA">NUMERO_TVA_VENDEUR</ram:ID>
</ram:SpecifiedTaxRegistration>
Dans Dolibarr : le champ “N° TVA intra.” dans la fiche société. Vérifier que le format est bien celui attendu par l’administration fiscale (avec le préfixe FR).
Adresse complète — BT-35 à BT-40
Le groupe d’adresse vendeur et son code pays sont requis dans le socle EN16931. Les autres détails dépendent du profil et des règles applicables. Pour une facture française, renseignez l’adresse réelle complète requise par votre contexte.
Dans Dolibarr : vérifier dans Configuration > Société/Organisation que l’adresse, la ville, le code postal et le pays sont tous remplis. Le code pays doit être un code ISO 3166-1 alpha-2 (FR pour la France). Dolibarr gère nativement les codes pays ISO, donc si le pays est sélectionné dans la liste déroulante, le code sera correct.
Coordonnées bancaires — BG-17
Les coordonnées bancaires sont nécessaires si le moyen de paiement est un virement (code UNTDID 4461 = 30 ou 58 pour SEPA). Le nœud XML correspondant (BG-17) attend le compte de paiement vendeur (BT-84 : IBAN via IBANID, ou identifiant propriétaire via ProprietaryID pour les comptes hors zone IBAN) et optionnellement le BIC (BT-86).
Dans Dolibarr : Accueil > Configuration > Société/Organisation > onglet “Comptes bancaires”. L’IBAN doit être renseigné sans espaces.
Échéance et conditions de paiement — BT-9 / BT-20
Si BT-115, montant à payer, est positif, la règle BR-CO-25 exige une date d’échéance (BT-9) ou des conditions de paiement en texte (BT-20). Leur cardinalité individuelle 0..1 ne les rend pas tous deux facultatifs dans ce cas. Voir la règle BR-CO-25 publiée par OpenPeppol.
Dans Dolibarr : les conditions de paiement se configurent dans Accueil > Configuration > Dictionnaires > Conditions de paiement. Le module Factur-X mappe ces conditions vers le nœud SpecifiedTradePaymentTerms du XML CII.
Configuration des fiches clients
Les informations de l’acheteur (BG-7) sont tirées de la fiche tiers dans Dolibarr. Pour chaque client soumis à la réforme, vérifier :
| Champ Dolibarr | BT EN16931 | Cardinalité | Où le renseigner |
|---|---|---|---|
| Nom | BT-44 (nom acheteur) | 1..1 | Fiche tiers > Nom |
| Adresse | BT-50 (adresse) | Selon profil et contexte | Fiche tiers > Adresse |
| Ville | BT-52 | Selon profil et contexte | Fiche tiers > Ville |
| Code postal | BT-53 | 0..1 | Fiche tiers > Code postal |
| Pays | BT-55 (code pays) | 1..1 | Fiche tiers > Pays |
| SIREN | BT-47 (id légal acheteur) | Requis pour la cible France CTC | Champ SIREN selon le mapping du module |
| TVA intra. | BT-48 (TVA acheteur) | 0..1 | Fiche tiers > N° TVA intra. |
BT-44 — Nom de l’acheteur : un nom vide peut entraîner une erreur de validation. Vérifiez que le module exporte la raison sociale réelle du client, et non un code interne ou une valeur provisoire.
Choix du profil Factur-X
Le profil Factur-X détermine le niveau de détail du XML embarqué. Le module Dolibarr propose généralement un choix dans sa configuration.
| Profil | Niveau | Usage |
|---|---|---|
| MINIMUM | Identifiants seulement | Insuffisant pour la réforme B2B |
| BASIC WL | Sans lignes de détail | Limité, pas de détail articles |
| BASIC | Avec lignes, périmètre réduit | À confronter aux exigences du flux |
| EN16931 | Modèle EN16931 | Vérifier aussi les règles France CTC applicables |
| EXTENDED | Champs supplémentaires | À choisir selon les données et la cible d’échange |
Le profil doit couvrir les données et les règles de votre cible d’échange. Une déclaration EN16931 ne prouve pas à elle seule l’exécution des règles France CTC; les profils partiels ne portent pas tout le modèle EN16931.
Le choix du profil se fait dans la configuration du module : Accueil > Configuration > Modules > Factur-X > Configuration. Sélectionner “EN16931” comme profil par défaut.
Pour comprendre les différences entre chaque profil, voir Profils Factur-X : MINIMUM, BASIC, EN16931, EXTENDED.
Les erreurs de validation courantes et leurs corrections
Erreur 1 — PDF non conforme PDF/A-3
Symptome : la validation retourne une erreur de conformité PDF/A-3 alors que le PDF s’ouvre correctement.
Cause : Dolibarr utilise TCPDF comme bibliothèque de génération PDF. TCPDF peut produire du PDF/A-1 dans certaines configurations, mais la génération PDF/A-3 conforme (ISO 19005-3) est plus exigeante. Les points à contrôler incluent :
- Polices non embarquées : TCPDF n’embarque pas toujours les sous-ensembles de polices requis. Les polices système référencées sans embedding violent la clause PDF/A sur l’autonomie du document.
- Profil ICC manquant : le dictionnaire
OutputIntentsdoit contenir un profil colorimétrique ICC valide. TCPDF ne l’ajoute pas automatiquement dans tous les cas. - Métadonnées XMP incomplètes : les propriétés
pdfaid:part=3etpdfaid:conformancecorrespondant au niveau PDF/A ciblé doivent figurer dans le flux XMP, accompagnées des descriptions d’extension de schéma Factur-X. - AFRelationship incorrect : la valeur dépend du profil et de la relation réelle entre PDF et XML. Vérifiez la spécification de l’édition ciblée; ne forcez pas
/Alternativedans tous les cas.
Corrections possibles :
Un outil d’assemblage peut ajouter le XML et les métadonnées au PDF. L’usage d’une bibliothèque ne prouve pas à lui seul la conformité PDF/A-3 : contrôlez le résultat avec un validateur PDF/A et les contrôles Factur-X du profil ciblé.
Si le PDF produit n’est pas conforme, vérifier dans la configuration du module :
- Que l’option “Générer en PDF/A” est activée (si disponible)
- Que les polices configurées dans Dolibarr sont bien des polices TrueType embarquées (pas des polices core PDF)
- Que les dépendances exigées par le module sont installées dans la version documentée. Si le module utilise
atgp/factur-x, relevez sa version avec Composer
# Vérifier l'installation de la bibliothèque dans le répertoire du module
cd /var/www/dolibarr/htdocs/custom/facturx
composer show atgp/factur-x
Pour un diagnostic approfondi des erreurs PDF/A-3, voir PDF/A-3 pour Factur-X : checklist de conformité.
Erreur 2 — Champs obligatoires manquants
Symptome : erreurs Schematron de type BR-CO-26, BR-05, BR-09.
Causes et corrections :
BR-CO-26 — Aucun identifiant vendeur : au moins un des champs BT-29, BT-30 ou BT-31 doit être présent. Vérifiez l’identifiant réel et son mapping; pour France CTC, renseignez le SIREN en BT-30 avec le schéma 0002, comme décrit plus haut.
BR-05 — Devise absente : le code devise (BT-5) n’est pas renseigné dans le XML. Dans Dolibarr, vérifier que la devise par défaut est configurée dans Accueil > Configuration > Société/Organisation > onglet “Identité” (champ “Devise”). La devise doit être un code ISO 4217 alpha-3 (EUR).
BR-09 — Code pays vendeur absent : le pays de l’émetteur n’est pas dans le XML. Vérifier que le pays est bien sélectionné dans la fiche société Dolibarr.
Erreur 3 — BT-44 nom de l’acheteur manquant
Symptome : erreur Schematron sur le nœud BuyerTradeParty/Name.
Cause : la fiche tiers du client dans Dolibarr a un nom vide ou non exploitable. Le module Factur-X lit le champ nom de la table llx_societe pour alimenter BT-44. Si ce champ est vide, l’erreur est inévitable.
Correction : dans Dolibarr, ouvrir la fiche du tiers client et vérifier que le champ “Nom” est renseigné avec la raison sociale complète. Pour vérifier toutes les fiches en lot :
-- Identifier les tiers sans nom (à exécuter dans phpMyAdmin ou en CLI)
SELECT rowid, nom, code_client
FROM llx_societe
WHERE fournisseur = 0
AND (nom IS NULL OR nom = '');
Erreur 4 — Déclaration de profil incohérente
Symptome : le validateur indique une incohérence entre le profil déclaré dans les métadonnées et le contenu XML.
Cause : le profil Factur-X est déclaré dans le nœud GuidelineSpecifiedDocumentContextParameter du XML. Si le module déclare le profil EN16931 mais que le XML ne contient pas tous les champs requis par ce profil, la validation échoue.
L’identifiant de profil EN16931 dans le XML CII pour Factur-X 1.08 est :
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:cen.eu:en16931:2017</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
Correction : s’assurer que le profil configuré dans le module correspond au niveau de détail effectivement renseigné dans Dolibarr. Si les fiches articles, clients et la fiche société sont complètes, le profil EN16931 peut etre alimenté. Complétez les informations réellement nécessaires à votre cible. Changer le profil pour faire disparaître une erreur ne remplace pas ces données.
Erreur 5 — Arrondis et incohérences de montants (BR-CO-*)
Symptome : erreurs BR-CO-10, BR-CO-13, BR-CO-14, BR-CO-15 — les totaux ne correspondent pas.
Cause : Dolibarr calcule les montants avec sa propre logique d’arrondi (configurable dans Accueil > Configuration > Divers > Calculs). Le module Factur-X reprend ces montants pour le XML. Si la logique d’arrondi de Dolibarr et la vérification arithmétique Schematron ne concordent pas, des écarts d’un centime apparaissent.
Les règles Schematron concernées :
| Regle | Verification |
|---|---|
| BR-CO-10 | Somme des montants nets de ligne = total HT lignes (BT-106) |
| BR-CO-13 | Total HT (BT-109) = lignes + charges - remises |
| BR-CO-14 | Total TVA = somme des montants TVA par catégorie |
| BR-CO-15 | Total TTC (BT-112) = HT (BT-109) + TVA (BT-110) |
| BR-CO-17 | Montant TVA catégorie = base x taux / 100 (arrondi 2 décimales) |
Corrections :
-
Dans Accueil > Configuration > Divers, vérifier le paramètre “Nombre de décimales pour les arrondis de montants”. La valeur doit être 2 pour les devises à 2 décimales (EUR).
-
Vérifier la ventilation par catégorie et taux et les règles d’arrondi du profil exécuté. BR-CO-14 compare le total TVA à la somme des montants TVA par catégorie. La somme des TVA arrondies ligne par ligne n’est pas une méthode universellement plus conforme.
-
Si des remises globales ou des frais sont appliqués, vérifier que le module les inclut dans les nœuds
AllowanceChargedu XML. Un écart entre les totaux Dolibarr et les totaux recalculés par Schematron provient souvent d’une remise ou d’un frais non transcrit dans le XML.
Pour comprendre en détail les règles BR-CO et le fonctionnement de la validation Schematron, voir Valider EN16931/Factur-X : XSD vs Schematron, erreurs BR-*.
Erreur 6 — Unité de mesure non conforme (BT-130)
Symptome : erreur Schematron sur BilledQuantity/@unitCode.
Cause : Dolibarr stocke les unités dans un dictionnaire interne (Accueil > Configuration > Dictionnaires > Unités de mesure). Le module Factur-X doit mapper ces unités vers les codes UN/ECE Rec 20 avec l’extension Rec 21 applicable. Si le mapping n’est pas configuré, le XML contient un label en clair (“pièce”, “heure”) au lieu du code normalisé (C62, HUR).
Codes UN/ECE les plus utilisés :
| Code | Signification |
|---|---|
C62 | Unité / pièce |
HUR | Heure |
DAY | Jour |
MON | Mois |
KGM | Kilogramme |
MTR | Mètre |
LTR | Litre |
SET | Ensemble / lot |
Correction : vérifier dans la configuration du module Factur-X que chaque unité Dolibarr est mappée vers un code UN/ECE. Si le module ne propose pas de table de mapping, ajoutez le mapping à l’export ou avec son mainteneur, sans modifier aveuglément les libellés métier partagés par d’autres fonctions.
Intégrer l’API FacturX pour la validation pre-envoi
La validation manuelle d’une facture est suffisante pour un test ponctuel. Mais dans un contexte de production, avec des dizaines ou des centaines de factures par mois, il faut un pipeline automatisé qui valide chaque facture avant l’envoi à la PA.
L’API FacturX permet d’automatiser cette validation via un appel HTTP depuis Dolibarr ou un script intermédiaire. Pour un récapitulatif côté intégrateur (hook PHP, données structurées et choix de Plateforme Agréée), voir Brancher Dolibarr à un moteur Factur-X via API REST.
Avec invoice_data complet, l’API utilise la facture structurée comme source et rend le PDF lisible depuis ces données; la présentation du PDF existant n’est pas promise conservée. Pour un complément ciblé à un document analysé, utilisez seulement les chemins invoice_patch, seller_context et buyer_context indiqués par le diagnostic.
Validation d’un fichier PDF Factur-X
curl -X POST https://api.facturxapi.com/api/v1/validate \
-H "Authorization: Bearer votre-cle-api" \
-F "file=@./facture-dolibarr.pdf"
Lisez le verdict de la cible, les étapes exécutées et les diagnostics. Cet extrait JSON illustratif et incomplet montre une erreur de montant; ce n’est pas une réponse enregistrée ni une preuve d’exécution :
{
"valid": false,
"profile": "EN16931",
"issues": [
{
"ruleId": "BR-CO-15",
"severity": "error",
"message": "Le montant TTC (BT-112) doit être égal au montant HT (BT-109) plus le total TVA (BT-110).",
"location": "/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement"
}
]
}
Dans la réponse complète, examinez target, validationReadiness et stages avant de décider de la suite du flux. Un contrôle non évalué reste non évalué; un avertissement n’est pas automatiquement une erreur bloquante. La validation documentaire ne soumet aucune facture à la PA.
Appel depuis un hook Dolibarr (PHP)
Dolibarr dispose d’un système de hooks qui permet d’exécuter du code personnalisé lors d’événements précis. Le hook le plus pertinent pour la validation Factur-X est celui déclenché après la génération du PDF.
Le squelette ci-dessous illustre un appel HTTP et l’affichage de diagnostics. Il n’a pas été exécuté sur une installation Dolibarr dans ce guide. Vérifiez les hooks, paramètres et règles de retour de votre version; ce code ne constitue pas un verrou de transmission PA.
<?php
// htdocs/custom/monmodule/class/actions_monmodule.class.php
class ActionsMonmodule
{
/**
* Hook exécuté après la génération du PDF de facture.
* Valide le fichier Factur-X via l'API avant tout envoi.
*/
public function afterPDFCreation($parameters, &$object, &$action, $hookmanager)
{
if ($object->element !== 'facture') {
return 0;
}
$filePath = $parameters['file'];
if (!file_exists($filePath)) {
return 0;
}
$apiKey = getDolGlobalString('FACTURX_API_KEY');
if (empty($apiKey)) {
dol_syslog('FacturX API key not configured', LOG_WARNING);
return 0;
}
$result = $this->validateFacturX($filePath, $apiKey);
if ($result === false) {
dol_syslog('FacturX validation: API call failed', LOG_ERR);
return 0;
}
if (!$result['valid']) {
$errorMessages = [];
foreach ($result['issues'] as $issue) {
$code = $issue['ruleId'] ?? $issue['code'];
$errorMessages[] = $code . ': ' . $issue['message'];
dol_syslog('FacturX validation issue: ' . $code . ' - ' . $issue['message'], LOG_ERR);
}
setEventMessages(
'Validation documentaire à examiner : ' . implode(' | ', $errorMessages),
null,
'errors'
);
// Vérifier la convention de retour du hook dans votre version.
// Le contrôle de transmission PA doit être implémenté séparément.
return 1;
}
setEventMessages('Résultat documentaire positif pour le périmètre exécuté (profil ' . $result['profile'] . ')', null, 'mesgs');
return 0;
}
/**
* Appel à l'API de validation FacturX.
*
* @param string $filePath Chemin du fichier PDF
* @param string $apiKey Clé API FacturX
* @return array|false Résultat de la validation ou false en cas d'erreur
*/
private function validateFacturX(string $filePath, string $apiKey)
{
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => 'https://api.facturxapi.com/api/v1/validate',
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
],
CURLOPT_POSTFIELDS => [
'file' => new CURLFile($filePath, 'application/pdf'),
],
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($error !== '' || $httpCode !== 200) {
dol_syslog(
'FacturX API error: HTTP ' . $httpCode . ' - ' . $error,
LOG_ERR
);
return false;
}
$decoded = json_decode($response, true);
if (!is_array($decoded)) {
dol_syslog('FacturX API: invalid JSON response', LOG_ERR);
return false;
}
return $decoded;
}
}
Pour intégrer ce squelette, suivez la documentation des contextes et hooks de votre version Dolibarr; ne déduisez pas l’enregistrement du seul nom afterPDFCreation. La clé API se configure dans un paramètre Dolibarr via Accueil > Configuration > Divers > Paramètres divers (constante FACTURX_API_KEY).
Configurer la clé API dans Dolibarr
La clé API ne doit pas etre codée en dur dans le code source. Dolibarr fournit un mécanisme de constantes globales pour stocker ce type de configuration.
Via l’interface : Accueil > Configuration > Divers > Paramètres divers. Ajouter une entrée :
- Nom de la constante :
FACTURX_API_KEY - Valeur : votre clé API
- Entité :
0(toutes les entités) ou l’entité spécifique
Restreignez l’accès à cette configuration aux administrateurs autorisés et choisissez l’entité correspondant au flux. N’inscrivez pas une clé réelle dans une commande conservée dans l’historique shell.
Workflow complet : Dolibarr vers la PA
Le workflow recommandé pour une utilisation en production est le suivant :
Dolibarr (saisie facture)
│
▼
Génération PDF + XML CII (module Factur-X)
│
▼
Validation API FacturX (intégration à adapter)
│
├── ✓ Contrôles exécutés réussis → poursuite du parcours PA
│ │
│ ▼
│ Envoi vers la PA (manuellement ou via connecteur)
│
└── ✗ Erreur ou contrôle non évalué → diagnostic à traiter
│
▼
Correction des données (fiche société, tiers, articles)
│
▼
Régénération du PDF → nouvelle validation
Ce pipeline détecte en amont les erreurs couvertes par les contrôles exécutés et réduit le risque de rejet documentaire. Il ne garantit pas l’acceptation au premier passage : la PA applique aussi ses règles de routage, ses contrôles métier et son propre cycle de vie. Un rejet peut entraîner un retard de paiement et des relances manuelles.
Validation en lot
Un traitement en lot peut compléter le hook unitaire. Ce squelette PHP n’a pas été exécuté ici : adaptez les chemins PDF, l’initialisation CLI et le périmètre d’entité, puis testez-le sur des fixtures publiques avant tout usage réel. Les compteurs ci-dessous lisent seulement le booléen valid; ils ne prouvent ni une couverture complète des contrôles ni l’acceptation PA.
<?php
// scripts/validate_facturx_batch.php
// Valide toutes les factures d'un mois donné
require '../htdocs/master.inc.php';
require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php';
$apiKey = getDolGlobalString('FACTURX_API_KEY');
if (empty($apiKey)) {
print "Erreur : constante FACTURX_API_KEY non configurée\n";
exit(1);
}
$year = $argv[1] ?? date('Y');
$month = $argv[2] ?? date('m');
$sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . "facture";
$sql .= " WHERE datef BETWEEN '" . $db->escape($year . '-' . $month . '-01') . "'";
$sql .= " AND LAST_DAY('" . $db->escape($year . '-' . $month . '-01') . "')";
$sql .= " AND fk_statut > 0";
$resql = $db->query($sql);
if (!$resql) {
print "Erreur SQL : " . $db->lasterror() . "\n";
exit(1);
}
$total = 0;
$valid = 0;
$invalid = 0;
$errors = [];
while ($obj = $db->fetch_object($resql)) {
$facture = new Facture($db);
$facture->fetch($obj->rowid);
$dir = $conf->facture->dir_output . '/' . get_exdir(0, 0, 0, 1, $facture, 'invoice');
$file = $dir . '/' . $facture->ref . '.pdf';
if (!file_exists($file)) {
$errors[] = $facture->ref . ' : fichier PDF introuvable';
$total++;
continue;
}
// Appel API (réutiliser la fonction validateFacturX du hook)
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => 'https://api.facturxapi.com/api/v1/validate',
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
CURLOPT_POSTFIELDS => ['file' => new CURLFile($file, 'application/pdf')],
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$total++;
if ($httpCode !== 200) {
$errors[] = $facture->ref . ' : erreur API (HTTP ' . $httpCode . ')';
continue;
}
$result = json_decode($response, true);
if (!is_array($result)) {
$errors[] = $facture->ref . ' : réponse API invalide';
continue;
}
if ($result['valid']) {
$valid++;
print " ✓ " . $facture->ref . " — résultat documentaire positif (" . $result['profile'] . ")\n";
} else {
$invalid++;
$errIds = array_map(fn($e) => $e['ruleId'] ?? $e['code'], $result['issues']);
print " ✗ " . $facture->ref . " — " . implode(', ', $errIds) . "\n";
}
}
print "\n";
print "Résultats pour $month/$year :\n";
print " Total : $total\n";
print " Résultats positifs : $valid\n";
print " Invalides : $invalid\n";
print " Erreurs : " . count($errors) . "\n";
if (!empty($errors)) {
print "\nDétail des erreurs :\n";
foreach ($errors as $err) {
print " - $err\n";
}
}
Exécution :
php scripts/validate_facturx_batch.php 2026 09
Après adaptation et test, ce traitement peut aider à repérer les documents à examiner. Pour piloter le flux de production, distinguez erreurs techniques, contrôles non évalués, erreurs documentaires et avertissements.
Conseils pour les développeurs qui étendent le module
Structure du XML CII Factur-X
Le XML CII (Cross-Industry Invoice) suit la structure UN/CEFACT D22B (pour Factur-X 1.08, extension rétrocompatible de D16B). Le namespace racine est urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100.
Cet extrait incomplet montre BT-24, identifiant du profil. BT-23 décrit le contexte métier de facturation : renseignez sa valeur réelle lorsqu’elle est requise par la cible. Ne recopiez pas l’URN de BT-24.
Les nœuds principaux :
<?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">
<!-- Contexte : profil, process -->
<rsm:ExchangedDocumentContext>
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:cen.eu:en16931:2017</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:ExchangedDocumentContext>
<!-- En-tête : numéro, type, date -->
<rsm:ExchangedDocument>
<ram:ID>FA-2026-001</ram:ID>
<ram:TypeCode>380</ram:TypeCode>
<ram:IssueDateTime>
<udt:DateTimeString format="102">20260901</udt:DateTimeString>
</ram:IssueDateTime>
</rsm:ExchangedDocument>
<!-- Corps : parties, lignes, totaux -->
<rsm:SupplyChainTradeTransaction>
<!-- ... -->
</rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>
Utiliser la bibliothèque atgp/factur-x
La bibliothèque PHP atgp/factur-x est publiée par @GP. Elle fournit des fonctions d’assemblage et de gestion de fichiers Factur-X. Consultez sa documentation officielle dans le tag correspondant à la version installée : noms de classes, méthodes et signatures doivent venir de cette version.
Relevez la version avec composer show atgp/factur-x, suivez son exemple d’assemblage PDF/XML, puis contrôlez le fichier produit avec les validateurs PDF/A et Factur-X du profil ciblé. La présence de XML et de métadonnées ne suffit pas à prouver que l’ensemble respecte PDF/A-3.
Points d’attention pour les contributeurs
Versionnement Factur-X : la version 1.08, désormais précédente, est basée sur CII D22B. La dernière publication FNFE-MPE / FeRD et sa date d’application sont indiquées dans le repère versionné en tête de page. Vérifiez que le module référence les schémas XSD et Schematron de la version réellement ciblée.
Tests de non-régression : après chaque modification du module, valider un jeu de factures représentatives (facture simple, avoir, facture avec remise globale, facture multi-TVA, facture B2G). Chaque cas exerce des chemins de code différents dans la génération XML.
Hooks Dolibarr disponibles : au-delà de afterPDFCreation, les hooks beforePDFCreation (pour modifier les données avant génération), createFrom (lors de la création d’avoir depuis une facture), et formObjectOptions (pour ajouter des champs dans le formulaire de facture) peuvent etre utiles pour enrichir l’intégration Factur-X.
Checklist de conformité Dolibarr + Factur-X
CONFIGURATION DOLIBARR POUR FACTUR-X — CHECKLIST
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Fiche société (Configuration > Société/Organisation)
☐ Raison sociale renseignée (BT-27)
☐ SIREN vendeur 9 chiffres, schemeID 0002 (BT-30, France CTC)
☐ N° TVA intracommunautaire format FRXX... (BT-31)
☐ Adresse complète : rue, ville, code postal, pays (BT-35 à BT-40)
☐ Devise par défaut = EUR (BT-5)
☐ Compte de paiement vendeur — BT-84 (IBAN ou identifiant propriétaire)
Fiches tiers clients
☐ Nom / raison sociale renseigné (BT-44)
☐ Adresse complète : rue, ville, code postal, pays (BT-50 à BT-55)
☐ SIREN acheteur, schemeID 0002 (BT-47, France CTC)
☐ N° TVA client si intracommunautaire (BT-48)
Module Factur-X
☐ Module installé et activé
☐ Profil par défaut = EN16931
☐ Dépendances du module installées dans les versions documentées
☐ Mapping unités de mesure → codes UN/ECE Rec 20
Calculs et arrondis
☐ Nombre de décimales = 2 pour EUR
☐ Ventilation TVA et totaux cohérents avec le profil contrôlé
☐ Remises/frais correctement transcrits dans le XML
Validation
☐ Clé API FacturX configurée (FACTURX_API_KEY)
☐ Hook de validation activé
☐ Facture représentative : profil, cible et contrôles exécutés relevés
☐ Avoir : erreurs et contrôles non évalués examinés
☐ Facture multi-TVA : ventilation et totaux contrôlés
Erreurs fréquentes et fiches de diagnostic
- schemeID SIREN/SIRET — distinguer SIREN légal et SIRET d’établissement dans le mapping
- BR-CO-14 — Total TVA somme des catégories — multi-taux mal sommé
- BT-131 — Montant net de ligne — base quantity et prix unitaire
- PDF/A-3 conformance — TCPDF sans configuration explicite ICC/XMP
Les 22 fiches unitaires : catalogue complet des erreurs BR-*.
Et maintenant ?
Tester ma facture maintenant →
curl -X POST https://api.facturxapi.com/api/v1/validate \
-H "Authorization: Bearer VOTRE_CLE" \
-F "file=@./facture.pdf"
Clé Sandbox : 100 factures traitées offertes les 14 premiers jours, puis 10 factures traitées/mois. Le scanner public reste gratuit et séparé du quota API. Obtenir une clé API.
Ressources
- Facturation électronique 2026 : le guide technique complet — calendrier, obligations, architecture technique
- Champs obligatoires EN16931 : cartographie et mapping ERP — tous les BT obligatoires et leur mapping
- PDF/A-3 pour Factur-X : checklist de conformité — diagnostic et correction des erreurs PDF/A-3
- Valider EN16931/Factur-X : XSD vs Schematron, erreurs BR-* — comprendre les erreurs Schematron
- Profils Factur-X : MINIMUM, BASIC, EN16931, EXTENDED — choisir le bon profil