La norme EN 16931 définit une facture comme une liste de termes métier numérotés (BT-1, BT-2 …) regroupés en groupes métier (BG-23, BG-25 …), avec des cardinalités et des règles métier entre eux. Pour produire un fichier conforme, vous faites correspondre chaque terme à un élément d'une syntaxe — UBL 2.1 ou UN/CEFACT CII —, remplissez chaque terme obligatoire, faites en sorte que les totaux satisfassent les règles de calcul (BR-CO-xx) et vérifiez le résultat contre le Schematron publié avant qu'il ne quitte votre système. Ce guide parcourt tout cela dans l'ordre où un développeur le rencontre.
Le modèle, pas le fichier
La partie normative de la norme, EN 16931-1, est un modèle de données sémantique : elle dit ce que contient une facture et ce que signifie chaque élément, sans prescrire de XML. La CEN/TS 16931-2 liste les deux syntaxes qui doivent être acceptées, UBL 2.1 (Invoice et CreditNote) et UN/CEFACT Cross Industry Invoice (CII) D16B. Les liaisons syntaxiques de la CEN/TS 16931-3 indiquent quel élément porte quel terme. Les parties 1 et 2 sont disponibles gratuitement auprès des organismes nationaux de normalisation en vertu d'un accord entre la Commission européenne et le CEN ; les liaisons sont des documents payants, mais tout ce dont un implémenteur a besoin pour valider — les règles Schematron — est publié ouvertement par l'équipe eInvoicing de la Commission sur GitHub. Pour le contexte, les versions et le concept de CIUS de la norme, voir EN 16931 expliquée.
Trois conséquences façonnent l'implémentation :
- Votre modèle de domaine doit porter des termes métier, pas des chemins XML. Un seul objet facture interne, converti une fois en UBL et une fois en CII, représente bien moins de travail que deux sérialiseurs écrits à la main, et le même objet sert XRechnung, ZUGFeRD, Factur-X et Peppol BIS, qui sont tous des profils (CIUS) ou des extensions de l'EN 16931. Voir les formats comparés.
- La cardinalité est imposée par le Schematron, pas seulement par le XSD. Un fichier UBL valide selon le XSD mais sans nom de vendeur est valide pour le schéma et invalide pour l'EN 16931.
- Les règles de calcul sont exactes au centime après arrondi. Une arithmétique en virgule flottante quelque part dans la chaîne finira par produire une violation BR-CO.
Les termes métier obligatoires
Le modèle de base a un petit ensemble obligatoire. Chaque facture EN 16931 doit porter les termes suivants ; une CIUS telle que XRechnung ou Peppol BIS ajoute par-dessus d'autres exigences (référence acheteur, adresse électronique du vendeur, moyens de paiement, etc.), qui sont contrôlées par les règles propres à ce profil.
| Terme | Nom | Élément UBL 2.1 | Élément CII (abrégé) | Règle |
|---|---|---|---|---|
| BT-1 | Numéro de facture | cbc:ID | ram:ExchangedDocument/ram:ID | BR-02 |
| BT-2 | Date d'émission de la facture | cbc:IssueDate | ram:ExchangedDocument/ram:IssueDateTime | BR-03 |
| BT-3 | Code de type de facture (UNTDID 1001, p. ex. 380, 381) | cbc:InvoiceTypeCode | ram:ExchangedDocument/ram:TypeCode | BR-04, BR-CL-01 |
| BT-5 | Code de devise de la facture (ISO 4217) | cbc:DocumentCurrencyCode | ram:InvoiceCurrencyCode | BR-05 |
| BT-24 | Identifiant de spécification (quelle CIUS) | cbc:CustomizationID | ram:GuidelineSpecifiedDocumentContextParameter/ram:ID | BR-01 |
| BT-27 | Nom du vendeur | cac:AccountingSupplierParty/…/cac:PartyLegalEntity/cbc:RegistrationName | ram:SellerTradeParty/ram:Name | BR-06 |
| BT-31 | Identifiant TVA du vendeur | cac:PartyTaxScheme/cbc:CompanyID (scheme VAT) | ram:SellerTradeParty/ram:SpecifiedTaxRegistration/ram:ID[@schemeID='VA'] | BR-CO-26 (l'un de BT-29, BT-30, BT-31) ; BR-CO-09 (préfixe pays) |
| BT-35 … BT-40 | Adresse postale du vendeur, au minimum le code pays (BT-40) | cac:PostalAddress/cac:Country/cbc:IdentificationCode | ram:PostalTradeAddress/ram:CountryID | BR-08, BR-09 |
| BT-44 | Nom de l'acheteur | cac:AccountingCustomerParty/…/cbc:RegistrationName | ram:BuyerTradeParty/ram:Name | BR-07 |
| BT-50 … BT-55 | Adresse postale de l'acheteur, au minimum le code pays (BT-55) | cac:PostalAddress/cac:Country/cbc:IdentificationCode | ram:PostalTradeAddress/ram:CountryID | BR-10, BR-11 |
| BT-106 | Somme des montants nets des lignes | cac:LegalMonetaryTotal/cbc:LineExtensionAmount | ram:SpecifiedTradeSettlementHeaderMonetarySummation/ram:LineTotalAmount | BR-12, BR-CO-10 |
| BT-109 | Montant total de la facture hors TVA | cbc:TaxExclusiveAmount | ram:TaxBasisTotalAmount | BR-13, BR-CO-13 |
| BT-110 | Montant total de TVA de la facture | cac:TaxTotal/cbc:TaxAmount | ram:TaxTotalAmount | BR-CO-14 |
| BT-112 | Montant total de la facture TVA comprise | cbc:TaxInclusiveAmount | ram:GrandTotalAmount | BR-14, BR-CO-15 |
| BT-115 | Montant à payer | cbc:PayableAmount | ram:DuePayableAmount | BR-15, BR-CO-16 |
| BG-23 | Ventilation de la TVA : un groupe par catégorie et taux, chacun avec BT-116 base imposable, BT-117 montant de taxe, BT-118 code de catégorie, BT-119 taux | cac:TaxTotal/cac:TaxSubtotal | ram:ApplicableTradeTax | BR-CO-17, BR-CO-18, règles BR-S/-AE/-E/-Z |
| BG-25 | Ligne de facture : BT-126 identifiant, BT-129 quantité, BT-130 unité, BT-131 montant net, BT-146 prix net, BT-151 catégorie de TVA, BT-153 nom de l'article | cac:InvoiceLine | ram:IncludedSupplyChainTradeLineItem | BR-16, BR-21 … BR-26, BR-CO-04 |
La liste complète des éléments, avec la cardinalité et la description de chaque terme, se trouve dans l'EN 16931-1 elle-même et est reproduite élément par élément dans la documentation de syntaxe de Peppol BIS. Le tableau ci-dessus est le minimum de travail, pas un substitut à sa lecture.
Les règles métier
Les règles se déclinent en familles, identifiées par leur préfixe. Un validateur rapporte l'identifiant de la règle ; apprenez les familles et la plupart des messages d'erreur deviennent explicites.
- BR-xx
- Règles structurelles : présence et cardinalité. BR-01 « An Invoice shall have a Specification identifier (BT-24) » ; BR-02 « An Invoice shall have an Invoice number (BT-1) » ; BR-03 la date d'émission ; BR-05 la devise ; BR-06 le nom du vendeur ; BR-07 le nom de l'acheteur ; BR-16 « An Invoice shall have at least one Invoice line (BG-25) ».
- BR-CO-xx
- Conditions et calculs. BR-CO-10 : BT-106 = Σ BT-131. BR-CO-13 : BT-109 = BT-106 − BT-107 (remises) + BT-108 (frais). BR-CO-14 : BT-110 = Σ BT-117. BR-CO-15 : BT-112 = BT-109 + BT-110. BR-CO-16 : BT-115 = BT-112 − BT-113 (payé) + BT-114 (arrondi). BR-CO-17 : BT-117 = BT-116 × BT-119 / 100, arrondi à deux décimales. BR-CO-04 exige un code de catégorie de TVA sur chaque ligne.
- BR-S, BR-Z, BR-E, BR-AE, BR-IC, BR-G, BR-O, BR-IG, BR-IP
- Une famille par code de catégorie de TVA (BT-118/BT-151) : S taux normal, Z taux zéro, E exonéré, AE autoliquidation, K livraison intracommunautaire, G exportation, O non soumis à la TVA, et les taxes des Canaries et de Ceuta/Melilla. Chaque famille dit ce que la ventilation doit contenir lorsqu'une ligne de cette catégorie existe. BR-AE-01 : une facture comportant une ligne en autoliquidation doit contenir exactement une ventilation de TVA de catégorie « AE ». BR-S-08 : pour chaque taux normal, la base imposable dans la ventilation est égale à la somme des montants nets des lignes (plus frais, moins remises) à ce taux.
- BR-CL-xx
- Règles de listes de codes : le code de type doit provenir de UNTDID 1001 (BR-CL-01), la devise d'ISO 4217, le pays d'ISO 3166-1, les unités des recommandations 20 et 21 de l'UN/ECE, etc.
- UBL-SR-xx, CII-SR-xx
- Règles de syntaxe : les éléments que la liaison n'utilise pas doivent être absents, et les éléments restreints ne doivent pas se répéter.
Les violations de règles portent un drapeau. Un échec fatal signifie que le fichier n'est pas une facture EN 16931 et qu'un destinataire peut le rejeter ; un avertissement signifie que quelque chose est inhabituel mais permis. Traitez les erreurs fatales comme des erreurs de compilation.
Une facture UBL minimale
Le fichier suivant satisfait les règles de base pour une seule ligne au taux normal de 19 %. Les espaces de noms sont ceux d'UBL 2.1 ; CustomizationID nomme le profil EN 16931 pur. Un véritable fichier XRechnung ou Peppol BIS a besoin en plus de son propre CustomizationID, d'un ProfileID, d'une référence acheteur et de coordonnées de paiement.
<?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
<cbc:CustomizationID>urn:cen.eu:en16931:2017</cbc:CustomizationID>
<cbc:ID>RE-2026-0142</cbc:ID>
<cbc:IssueDate>2026-09-03</cbc:IssueDate>
<cbc:DueDate>2026-10-03</cbc:DueDate>
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
<cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>
<cac:AccountingSupplierParty><cac:Party>
<cac:PostalAddress><cbc:StreetName>Beispielstrasse 1</cbc:StreetName>
<cbc:CityName>Berlin</cbc:CityName><cbc:PostalZone>10115</cbc:PostalZone>
<cac:Country><cbc:IdentificationCode>DE</cbc:IdentificationCode></cac:Country>
</cac:PostalAddress>
<cac:PartyTaxScheme><cbc:CompanyID>DE123456789</cbc:CompanyID>
<cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme></cac:PartyTaxScheme>
<cac:PartyLegalEntity><cbc:RegistrationName>Beispiel GmbH</cbc:RegistrationName></cac:PartyLegalEntity>
</cac:Party></cac:AccountingSupplierParty>
<cac:AccountingCustomerParty><cac:Party>
<cac:PostalAddress><cbc:CityName>Hamburg</cbc:CityName><cbc:PostalZone>20095</cbc:PostalZone>
<cac:Country><cbc:IdentificationCode>DE</cbc:IdentificationCode></cac:Country>
</cac:PostalAddress>
<cac:PartyLegalEntity><cbc:RegistrationName>Kunde AG</cbc:RegistrationName></cac:PartyLegalEntity>
</cac:Party></cac:AccountingCustomerParty>
<cac:TaxTotal>
<cbc:TaxAmount currencyID="EUR">190.00</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="EUR">1000.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="EUR">190.00</cbc:TaxAmount>
<cac:TaxCategory><cbc:ID>S</cbc:ID><cbc:Percent>19</cbc:Percent>
<cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme></cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>
<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="EUR">1000.00</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="EUR">1000.00</cbc:TaxExclusiveAmount>
<cbc:TaxInclusiveAmount currencyID="EUR">1190.00</cbc:TaxInclusiveAmount>
<cbc:PayableAmount currencyID="EUR">1190.00</cbc:PayableAmount>
</cac:LegalMonetaryTotal>
<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:InvoicedQuantity unitCode="HUR">10</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">1000.00</cbc:LineExtensionAmount>
<cac:Item><cbc:Name>Consulting</cbc:Name>
<cac:ClassifiedTaxCategory><cbc:ID>S</cbc:ID><cbc:Percent>19</cbc:Percent>
<cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme></cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price><cbc:PriceAmount currencyID="EUR">100.00</cbc:PriceAmount></cac:Price>
</cac:InvoiceLine>
</Invoice>
Vérifiez les totaux contre les règles : net de ligne 10 × 100,00 = 1000,00 (BT-131) ; Σ lignes = 1000,00 (BR-CO-10) ; ni remises ni frais, donc BT-109 = 1000,00 (BR-CO-13) ; une ventilation, S à 19 %, base 1000,00, taxe 190,00 (BR-CO-17) ; BT-110 = 190,00 (BR-CO-14) ; BT-112 = 1190,00 (BR-CO-15) ; rien de prépayé, BT-115 = 1190,00 (BR-CO-16).
Artefacts et outils de validation
Validez avec les mêmes artefacts que ceux qu'utilisent les destinataires. Il n'est pas nécessaire de réimplémenter les règles.
| Artefact | Mainteneur | Couvre | Comment l'exécuter |
|---|---|---|---|
| Schematron eInvoicing-EN16931 (UBL et CII), version 1.3.16 du 10 avril 2026 à la date de lecture | Équipe eInvoicing de la Commission européenne (ConnectingEurope sur GitHub) | Les règles de base de l'EN 16931 : BR, BR-CO, BR-CL, familles de catégories de TVA, règles de syntaxe | Tout processeur Schematron/XSLT 2.0 ; le dépôt fournit aussi le XSLT compilé |
Règles Peppol BIS Billing 3.0 (CEN-EN16931-UBL.sch plus PEPPOL-EN16931-UBL.sch) | OpenPeppol | Les règles de base plus les règles de la CIUS Peppol | Téléchargées depuis docs.peppol.eu ; mêmes processeurs |
| Schematron XRechnung et configuration du validateur | KoSIT | Les règles de base plus les règles de la CIUS allemande (XRechnung) | java -jar validator-*-standalone.jar -s scenarios.xml file.xml ; le validateur est un moteur générique, version 1.6.2 de février 2026, qui charge un paquet « scénario » pour XRechnung ou Peppol |
| Mustangproject | Communauté open source, Apache 2.0 | Lit, écrit et valide ZUGFeRD/Factur-X (CII dans PDF/A-3) et XRechnung ; contrôle le conteneur PDF/A ainsi que le XML | Bibliothèque Java sur Maven Central, ou l'outil en ligne de commande ; --action validate |
Une chaîne pratique exécute d'abord le XSD (peu coûteux, attrape les structures malformées), puis le Schematron EN 16931, puis le Schematron du profil (XRechnung ou Peppol) et, pour les formats hybrides, un contrôle PDF/A-3 du conteneur. Intégrez-la à l'intégration continue avec un corpus de vos propres documents : un par catégorie de TVA que vous prenez en charge, un avec remises et frais, un avoir, un en devise étrangère avec BT-6 renseigné.
Erreurs de validation fréquentes et leurs causes
La plupart des échecs proviennent d'une poignée de causes. Les reconnaître à l'identifiant de règle fait gagner des heures.
- BR-CO-10, BR-CO-13, BR-CO-15 — totaux décalés de 0,01. Les montants de ligne ont été arrondis individuellement et les totaux calculés à partir de valeurs non arrondies, ou l'inverse. Choisissez un seul point d'arrondi (par ligne, deux décimales, au plus proche sauf si le profil dit autrement) et dérivez chaque total des montants de ligne arrondis.
- BR-CO-17 — le montant de taxe de la ventilation n'est pas égal à base × taux. Même cause, appliquée à la ventilation de TVA. Calculez BT-117 à partir de BT-116, pas en sommant la TVA au niveau des lignes.
- BR-S-08 / BR-AE-08 / BR-E-08 — la ventilation pour une catégorie existe mais sa base imposable ne correspond pas aux lignes. Généralement, une remise ou des frais au niveau du document ont été appliqués aux totaux sans recevoir de catégorie de TVA, ou la catégorie d'une ligne et celle de la ventilation ne concordent pas.
- BR-AE-02 … BR-AE-04 — autoliquidation sans les identifiants des deux parties. Pour la catégorie AE, l'identifiant TVA du vendeur et celui de l'acheteur (ou l'immatriculation fiscale de l'acheteur) doivent être présents.
- BR-E-10 / BR-AE-10 — un motif d'exonération est requis. Une ventilation exonérée ou en autoliquidation a besoin d'un texte de motif d'exonération de TVA (BT-120) ou d'un code (BT-121) ; une ventilation à taux zéro (BR-Z-10), à l'inverse, ne doit pas en porter.
- BR-CL-xx — un code de la mauvaise liste. « PCE » n'est pas une unité valide ; « C62 » (un) ou « H87 » (pièce) l'est. « EURO » n'est pas ISO 4217 ; « EUR » l'est. Les codes pays sont deux lettres en majuscules.
- BR-CO-09 — l'identifiant TVA du vendeur n'a pas de préfixe pays (« 123456789 » au lieu de « DE123456789 »).
- BR-01 / CustomizationID non reconnu — l'identifiant de profil est absent ou nomme un profil que le destinataire n'accepte pas. Peppol et XRechnung exigent chacun leur chaîne exacte.
- Règles de profil (PEPPOL-EN16931-Rxxx, BR-DE-xx) — la base passe mais la CIUS échoue : référence acheteur manquante (BR-DE-15), adresse électronique du vendeur manquante, moyens de paiement manquants, ou Leitweg-ID mal formée. Voir XRechnung et Peppol.
Pour contrôler un fichier isolé sans monter de chaîne d'outils, le vérificateur de factures électroniques gratuit valide un document contre les règles d'un pays et rapporte les identifiants de règles sans stocker le fichier.
Comment KRONENWERK gère cela
Pris en charge KRONENWERK génère le document structuré au moment où une facture est émise et le valide avant que le numéro ne soit consommé : XRechnung et ZUGFeRD pour l'Allemagne, contrôlés avec les règles Schematron de la KoSIT et contre-vérifiés avec la bibliothèque Mustang ; Factur-X pour la France ; Peppol BIS Billing 3.0 UBL pour la Belgique ; FA(3) pour la Pologne. La catégorie de TVA de chaque ligne est dérivée d'un verdict fiscal stocké (taux normal, taux zéro, exonéré, autoliquidation, hors champ) plutôt que saisie, et le numéro de TVA de l'acheteur est vérifié dans VIES à l'émission, de sorte que les échecs BR-AE et BR-CO-09 ne naissent pas de la saisie. Les fichiers XRechnung, ZUGFeRD/Factur-X et UBL entrants sont lus dans les factures fournisseurs. Par l'API, POST /invoices/drafts crée un brouillon et GET /invoices/{number} lit une facture émise ; l'émission, et donc la génération et la validation, se fait dans le produit. L'API n'accepte ni ne renvoie de XML brut, et elle ne valide pas de fichiers tiers — c'est le rôle du vérificateur. Voir la page produit facturation électronique et l'API de facturation.
Questions fréquentes
Dois-je acheter la norme pour l'implémenter ?
L'EN 16931-1 et la CEN/TS 16931-2 sont disponibles gratuitement auprès des organismes nationaux de normalisation en vertu de l'accord Commission–CEN. Les liaisons syntaxiques (partie 3) sont payantes, mais les artefacts Schematron publiés et la documentation Peppol et XRechnung couvrent la correspondance en pratique.
UBL ou CII ?
Les deux sont des syntaxes obligatoires pour les destinataires. Peppol BIS Billing et la Belgique utilisent UBL ; ZUGFeRD et Factur-X intègrent du CII ; XRechnung accepte les deux. Si vous devez en choisir une, UBL a la plus large portée réseau et la structure la plus simple ; si vous produisez des PDF hybrides, vous avez de toute façon besoin de CII.
Pourquoi mon fichier passe-t-il le XSD mais échoue chez le destinataire ?
Le XSD contrôle la structure, pas les règles métier. La présence des termes obligatoires, les listes de codes et l'arithmétique entre les totaux sont des règles Schematron, et les destinataires les exécutent.
Quel arrondi la norme exige-t-elle ?
BR-CO-17 dit que le montant de taxe d'une catégorie de TVA est base imposable × taux / 100 « arrondi à deux décimales » ; la norme ne prescrit pas d'autre algorithme d'arrondi. Gardez tous les montants à deux décimales et dérivez les totaux des montants de ligne arrondis.
Un fichier EN 16931 est-il automatiquement une facture XRechnung ou Peppol valide ?
Non. Ce sont des spécifications d'usage par-dessus le noyau : elles exigent des termes supplémentaires et leur propre CustomizationID. Un fichier valide pour le noyau avec le mauvais identifiant est rejeté par les deux.
Sources
- European Commission — Obtaining a copy of the European standard on eInvoicing — consulté le
- ConnectingEurope — eInvoicing-EN16931 validation artefacts (Schematron, UBL and CII) — consulté le
- OpenPeppol — Peppol BIS Billing 3.0, EN 16931 (TC434) rules for UBL — consulté le
- KoSIT — validator (XML validation engine for XRechnung and Peppol scenarios) — consulté le
- Mustangproject — open-source Java library for ZUGFeRD, Factur-X and XRechnung — consulté le
- KRONENWERK developer documentation — consulté le