Aller au contenu

Ironfang Finance - Exemple

Exemple de facture XML Peppol

Une facture Peppol BIS Billing 3 complète en XML UBL qui réussit la validation, expliquée champ par champ, avec une copie erronée qui montre à quoi ressemble une erreur de totaux et comment la corriger.

Télécharger ou valider l'exemple

Résultat
Valide : les étapes XML, schéma UBL, EN 16931 et Peppol ont toutes réussi, sans avertissement.
Contrôle
25 septembre 2026, avec le validateur gratuit d'Ironfang Finance
Règles
Peppol BIS Billing 3.0, version de mai 2026 (2026.5, aussi appelée 3.0.21) ; jeu de règles fwrs_bis3_billing_invoice_2026_5_r5, VESID eu.peppol.bis3:invoice:2026.5
Moteur
phive 12.1.0 avec phive-rules-peppol 4.5.6 et Saxon-HE 12.10
SHA-256
c9d1474941163526a1a518405de43c5a31d3f5261a72adf80877cc9389534ea9

Tout y est fictif : des adresses example.test et des numéros de localisation GS1 sous le préfixe 952, que GS1 réserve aux démonstrations. Les identifiants d'adresse électronique ne sont pas des participants Peppol enregistrés ; n'y envoyez jamais de document réel.

La facture complète

Voici le document complet, exactement tel qu'il est téléchargé. Les sections ci-dessous le décomposent. C'est le même fichier que le validateur envoie lorsque vous essayez son exemple valide.

<?xml version="1.0" encoding="UTF-8"?>
<!--
  A fictional Peppol BIS Billing 3.0 invoice published by Ironfang for the
  free validator at https://ironfang.uk/tools/peppol-validator. Every party,
  identifier, address and amount is invented: example.test names, GS1
  location numbers under prefix 952, which GS1 designates for demonstrations
  and examples, and an account reference that is not a bank account. Reuse it
  freely.
-->
<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#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0</cbc:CustomizationID>
    <cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID>
    <cbc:ID>EX-2026-0001</cbc:ID>
    <cbc:IssueDate>2026-06-15</cbc:IssueDate>
    <cbc:DueDate>2026-07-15</cbc:DueDate>
    <cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
    <cbc:Note>Fictional sample invoice for the Ironfang Peppol validator.</cbc:Note>
    <cbc:DocumentCurrencyCode>GBP</cbc:DocumentCurrencyCode>
    <cbc:BuyerReference>PO-EXAMPLE-0001</cbc:BuyerReference>
    <cac:AccountingSupplierParty>
        <cac:Party>
            <cbc:EndpointID schemeID="0088">9520000000011</cbc:EndpointID>
            <cac:PartyIdentification>
                <cbc:ID schemeID="0088">9520000000011</cbc:ID>
            </cac:PartyIdentification>
            <cac:PartyName>
                <cbc:Name>Example Supplier Ltd</cbc:Name>
            </cac:PartyName>
            <cac:PostalAddress>
                <cbc:StreetName>1 Example Street</cbc:StreetName>
                <cbc:CityName>Exampleton</cbc:CityName>
                <cbc:PostalZone>EX1 1EX</cbc:PostalZone>
                <cac:Country>
                    <cbc:IdentificationCode>GB</cbc:IdentificationCode>
                </cac:Country>
            </cac:PostalAddress>
            <cac:PartyTaxScheme>
                <cbc:CompanyID>GB000000000</cbc:CompanyID>
                <cac:TaxScheme>
                    <cbc:ID>VAT</cbc:ID>
                </cac:TaxScheme>
            </cac:PartyTaxScheme>
            <cac:PartyLegalEntity>
                <cbc:RegistrationName>Example Supplier Ltd</cbc:RegistrationName>
            </cac:PartyLegalEntity>
            <cac:Contact>
                <cbc:Name>Accounts</cbc:Name>
                <cbc:ElectronicMail>accounts@supplier.example.test</cbc:ElectronicMail>
            </cac:Contact>
        </cac:Party>
    </cac:AccountingSupplierParty>
    <cac:AccountingCustomerParty>
        <cac:Party>
            <cbc:EndpointID schemeID="0088">9520000000028</cbc:EndpointID>
            <cac:PartyIdentification>
                <cbc:ID schemeID="0088">9520000000028</cbc:ID>
            </cac:PartyIdentification>
            <cac:PartyName>
                <cbc:Name>Example Buyer Ltd</cbc:Name>
            </cac:PartyName>
            <cac:PostalAddress>
                <cbc:StreetName>2 Sample Road</cbc:StreetName>
                <cbc:CityName>Sampleford</cbc:CityName>
                <cbc:PostalZone>EX2 2EX</cbc:PostalZone>
                <cac:Country>
                    <cbc:IdentificationCode>GB</cbc:IdentificationCode>
                </cac:Country>
            </cac:PostalAddress>
            <cac:PartyLegalEntity>
                <cbc:RegistrationName>Example Buyer Ltd</cbc:RegistrationName>
            </cac:PartyLegalEntity>
            <cac:Contact>
                <cbc:Name>Purchasing</cbc:Name>
                <cbc:ElectronicMail>purchasing@buyer.example.test</cbc:ElectronicMail>
            </cac:Contact>
        </cac:Party>
    </cac:AccountingCustomerParty>
    <cac:Delivery>
        <cbc:ActualDeliveryDate>2026-06-10</cbc:ActualDeliveryDate>
    </cac:Delivery>
    <cac:PaymentMeans>
        <cbc:PaymentMeansCode name="Credit transfer">30</cbc:PaymentMeansCode>
        <cbc:PaymentID>EX-2026-0001</cbc:PaymentID>
        <cac:PayeeFinancialAccount>
            <cbc:ID>EXAMPLE-ACCOUNT-0001</cbc:ID>
            <cbc:Name>Example Supplier Ltd</cbc:Name>
        </cac:PayeeFinancialAccount>
    </cac:PaymentMeans>
    <cac:PaymentTerms>
        <cbc:Note>Payment within 30 days of the invoice date.</cbc:Note>
    </cac:PaymentTerms>
    <cac:TaxTotal>
        <cbc:TaxAmount currencyID="GBP">148.00</cbc:TaxAmount>
        <cac:TaxSubtotal>
            <cbc:TaxableAmount currencyID="GBP">740.00</cbc:TaxableAmount>
            <cbc:TaxAmount currencyID="GBP">148.00</cbc:TaxAmount>
            <cac:TaxCategory>
                <cbc:ID>S</cbc:ID>
                <cbc:Percent>20</cbc:Percent>
                <cac:TaxScheme>
                    <cbc:ID>VAT</cbc:ID>
                </cac:TaxScheme>
            </cac:TaxCategory>
        </cac:TaxSubtotal>
    </cac:TaxTotal>
    <cac:LegalMonetaryTotal>
        <cbc:LineExtensionAmount currencyID="GBP">740.00</cbc:LineExtensionAmount>
        <cbc:TaxExclusiveAmount currencyID="GBP">740.00</cbc:TaxExclusiveAmount>
        <cbc:TaxInclusiveAmount currencyID="GBP">888.00</cbc:TaxInclusiveAmount>
        <cbc:PayableAmount currencyID="GBP">888.00</cbc:PayableAmount>
    </cac:LegalMonetaryTotal>
    <cac:InvoiceLine>
        <cbc:ID>1</cbc:ID>
        <cbc:InvoicedQuantity unitCode="C62">10</cbc:InvoicedQuantity>
        <cbc:LineExtensionAmount currencyID="GBP">500.00</cbc:LineExtensionAmount>
        <cac:Item>
            <cbc:Description>Example widget, standard finish</cbc:Description>
            <cbc:Name>Example widget</cbc:Name>
            <cac:SellersItemIdentification>
                <cbc:ID>EX-WIDGET-01</cbc:ID>
            </cac:SellersItemIdentification>
            <cac:ClassifiedTaxCategory>
                <cbc:ID>S</cbc:ID>
                <cbc:Percent>20</cbc:Percent>
                <cac:TaxScheme>
                    <cbc:ID>VAT</cbc:ID>
                </cac:TaxScheme>
            </cac:ClassifiedTaxCategory>
        </cac:Item>
        <cac:Price>
            <cbc:PriceAmount currencyID="GBP">50.00</cbc:PriceAmount>
        </cac:Price>
    </cac:InvoiceLine>
    <cac:InvoiceLine>
        <cbc:ID>2</cbc:ID>
        <cbc:InvoicedQuantity unitCode="HUR">2</cbc:InvoicedQuantity>
        <cbc:LineExtensionAmount currencyID="GBP">240.00</cbc:LineExtensionAmount>
        <cac:Item>
            <cbc:Description>Installation of example widgets, per hour</cbc:Description>
            <cbc:Name>Installation service</cbc:Name>
            <cac:SellersItemIdentification>
                <cbc:ID>EX-INSTALL-01</cbc:ID>
            </cac:SellersItemIdentification>
            <cac:ClassifiedTaxCategory>
                <cbc:ID>S</cbc:ID>
                <cbc:Percent>20</cbc:Percent>
                <cac:TaxScheme>
                    <cbc:ID>VAT</cbc:ID>
                </cac:TaxScheme>
            </cac:ClassifiedTaxCategory>
        </cac:Item>
        <cac:Price>
            <cbc:PriceAmount currencyID="GBP">120.00</cbc:PriceAmount>
        </cac:Price>
    </cac:InvoiceLine>
</Invoice>
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0</cbc:CustomizationID>
<cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID>
<cbc:ID>EX-2026-0001</cbc:ID>
<cbc:IssueDate>2026-06-15</cbc:IssueDate>
<cbc:DueDate>2026-07-15</cbc:DueDate>
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
<cbc:Note>Fictional sample invoice for the Ironfang Peppol validator.</cbc:Note>
<cbc:DocumentCurrencyCode>GBP</cbc:DocumentCurrencyCode>
<cbc:BuyerReference>PO-EXAMPLE-0001</cbc:BuyerReference>
  • CustomizationID indique la spécification que suit la facture. Cette valeur désigne Peppol BIS Billing 3.0 au-dessus du socle EN 16931 ; le validateur s'en sert pour choisir le jeu de règles, et un point d'accès destinataire pour savoir ce qu'il reçoit.
  • ProfileID nomme le processus métier, ici le processus de facturation Peppol 01.
  • ID, IssueDate et DueDate sont le numéro et les dates de la facture, les dates toujours au format YYYY-MM-DD. InvoiceTypeCode 380 est une facture commerciale ; un avoir est normalement envoyé comme document CreditNote distinct.
  • DocumentCurrencyCode est la devise dans laquelle chaque montant est exprimé, et chaque montant la répète dans un attribut currencyID.
  • BuyerReference est la référence que l'acheteur vous a demandé de rappeler. Peppol exige soit celle-ci, soit une référence de bon de commande (PEPPOL-EN16931-R003).

Vendeur, acheteur et adresses électroniques

<cac:AccountingSupplierParty>
    <cac:Party>
        <cbc:EndpointID schemeID="0088">9520000000011</cbc:EndpointID>
        <cac:PartyIdentification>
            <cbc:ID schemeID="0088">9520000000011</cbc:ID>
        </cac:PartyIdentification>
        <cac:PartyName>
            <cbc:Name>Example Supplier Ltd</cbc:Name>
        </cac:PartyName>
        <cac:PostalAddress>
            <cbc:StreetName>1 Example Street</cbc:StreetName>
            <cbc:CityName>Exampleton</cbc:CityName>
            <cbc:PostalZone>EX1 1EX</cbc:PostalZone>
            <cac:Country>
                <cbc:IdentificationCode>GB</cbc:IdentificationCode>
            </cac:Country>
        </cac:PostalAddress>
        <cac:PartyTaxScheme>
            <cbc:CompanyID>GB000000000</cbc:CompanyID>
            <cac:TaxScheme>
                <cbc:ID>VAT</cbc:ID>
            </cac:TaxScheme>
        </cac:PartyTaxScheme>
        <cac:PartyLegalEntity>
            <cbc:RegistrationName>Example Supplier Ltd</cbc:RegistrationName>
        </cac:PartyLegalEntity>
        <cac:Contact>
            <cbc:Name>Accounts</cbc:Name>
            <cbc:ElectronicMail>accounts@supplier.example.test</cbc:ElectronicMail>
        </cac:Contact>
    </cac:Party>
</cac:AccountingSupplierParty>
  • EndpointID est l'adresse électronique de la partie sur le réseau Peppol : là où un document qui lui est destiné est remis. Les deux parties doivent en avoir une (PEPPOL-EN16931-R020 pour le vendeur, PEPPOL-EN16931-R010 pour l'acheteur), et chacune doit indiquer dans schemeID le schéma d'identifiant qu'elle utilise (BR-62, BR-63).
  • Le schéma 0088 est un GS1 Global Location Number, issu de la liste de codes Electronic Address Scheme. Les factures réelles utilisent souvent à la place un schéma national de numéro d'entreprise ou de TVA ; utilisez le schéma et la valeur que votre point d'accès a enregistrés pour vous.
  • PartyTaxScheme porte le numéro de TVA du vendeur, et PartyLegalEntity sa dénomination légale enregistrée. PartyIdentification est un identifiant supplémentaire facultatif.

L'acheteur est construit de la même façon, avec sa propre adresse :

<cbc:EndpointID schemeID="0088">9520000000028</cbc:EndpointID>

Lignes de facture

<cac:InvoiceLine>
    <cbc:ID>1</cbc:ID>
    <cbc:InvoicedQuantity unitCode="C62">10</cbc:InvoicedQuantity>
    <cbc:LineExtensionAmount currencyID="GBP">500.00</cbc:LineExtensionAmount>
    <cac:Item>
        <cbc:Description>Example widget, standard finish</cbc:Description>
        <cbc:Name>Example widget</cbc:Name>
        <cac:SellersItemIdentification>
            <cbc:ID>EX-WIDGET-01</cbc:ID>
        </cac:SellersItemIdentification>
        <cac:ClassifiedTaxCategory>
            <cbc:ID>S</cbc:ID>
            <cbc:Percent>20</cbc:Percent>
            <cac:TaxScheme>
                <cbc:ID>VAT</cbc:ID>
            </cac:TaxScheme>
        </cac:ClassifiedTaxCategory>
    </cac:Item>
    <cac:Price>
        <cbc:PriceAmount currencyID="GBP">50.00</cbc:PriceAmount>
    </cac:Price>
</cac:InvoiceLine>

Chaque ligne comporte une quantité avec une unité de la recommandation UN/ECE 20 (C62 signifie une unité, HUR une heure), un montant net, l'article et sa catégorie de TVA, et le prix unitaire. La catégorie S est le taux normal, ici 20 pour cent. Le montant net de la ligne est la quantité multipliée par le prix, sans remise ni frais sur ces lignes.

Calcul des lignes de facture
LigneArticleQuantitéPrixMontant net
1Example widget10 unités (C62)50.0010 x 50.00 = 500.00
2Installation service2 heures (HUR)120.002 x 120.00 = 240.00

Ventilation de la TVA et totaux du document

<cac:TaxTotal>
    <cbc:TaxAmount currencyID="GBP">148.00</cbc:TaxAmount>
    <cac:TaxSubtotal>
        <cbc:TaxableAmount currencyID="GBP">740.00</cbc:TaxableAmount>
        <cbc:TaxAmount currencyID="GBP">148.00</cbc:TaxAmount>
        <cac:TaxCategory>
            <cbc:ID>S</cbc:ID>
            <cbc:Percent>20</cbc:Percent>
            <cac:TaxScheme>
                <cbc:ID>VAT</cbc:ID>
            </cac:TaxScheme>
        </cac:TaxCategory>
    </cac:TaxSubtotal>
</cac:TaxTotal>
<cac:LegalMonetaryTotal>
    <cbc:LineExtensionAmount currencyID="GBP">740.00</cbc:LineExtensionAmount>
    <cbc:TaxExclusiveAmount currencyID="GBP">740.00</cbc:TaxExclusiveAmount>
    <cbc:TaxInclusiveAmount currencyID="GBP">888.00</cbc:TaxInclusiveAmount>
    <cbc:PayableAmount currencyID="GBP">888.00</cbc:PayableAmount>
</cac:LegalMonetaryTotal>

Chaque total peut être recalculé à partir des lignes, et les règles EN 16931 contrôlent chaque étape :

Comment les totaux se rapprochent
ChampCalculGBPRègle
LineExtensionAmount500.00 + 240.00740.00BR-CO-10
TaxExclusiveAmountTotal des lignes, moins les remises, plus les frais du document (aucun ici)740.00BR-CO-13
TaxableAmount (S, 20%)Net des lignes de la catégorie S740.00BR-S-08
TaxAmount (S, 20%)740.00 x 20%, arrondi à deux décimales148.00BR-S-09
TaxTotal/TaxAmountSomme des montants de TVA de la ventilation148.00BR-CO-14
TaxInclusiveAmount740.00 + 148.00888.00BR-CO-15
PayableAmountTotal TVA comprise, moins le montant prépayé, plus l'arrondi (ni l'un ni l'autre ici)888.00BR-CO-16

Calculez ces montants en arithmétique décimale, pas en virgule flottante, et arrondissez chaque montant à deux décimales lorsque les règles l'exigent. Un total obtenu en additionnant des nombres binaires à virgule flottante peut être décalé d'un penny, ce qui suffit à échouer. L'article en anglais Understanding EN 16931 validation errors explique plus en détail les règles de calcul.

Données de paiement

<cac:PaymentMeans>
    <cbc:PaymentMeansCode name="Credit transfer">30</cbc:PaymentMeansCode>
    <cbc:PaymentID>EX-2026-0001</cbc:PaymentID>
    <cac:PayeeFinancialAccount>
        <cbc:ID>EXAMPLE-ACCOUNT-0001</cbc:ID>
        <cbc:Name>Example Supplier Ltd</cbc:Name>
    </cac:PayeeFinancialAccount>
</cac:PaymentMeans>
<cac:PaymentTerms>
    <cbc:Note>Payment within 30 days of the invoice date.</cbc:Note>
</cac:PaymentTerms>

Le code de moyen de paiement 30 désigne un virement. PaymentID est la référence que l'acheteur doit rappeler lors du paiement, et PayeeFinancialAccount/ID le compte à créditer : un IBAN, ou l'identifiant de compte qu'utilise votre banque. Le compte de cet exemple est une valeur de remplacement, pas un compte bancaire.

Une copie erronée, et sa correction

Le second exemple est la même facture avec un seul nombre modifié : le total des lignes du document indique 750.00 alors que les deux lignes totalisent 740.00.

<cac:LegalMonetaryTotal>
    <cbc:LineExtensionAmount currencyID="GBP">750.00</cbc:LineExtensionAmount>
    <cbc:TaxExclusiveAmount currencyID="GBP">740.00</cbc:TaxExclusiveAmount>
    <cbc:TaxInclusiveAmount currencyID="GBP">888.00</cbc:TaxInclusiveAmount>
    <cbc:PayableAmount currencyID="GBP">888.00</cbc:PayableAmount>
</cac:LegalMonetaryTotal>

Validé le même jour avec le même jeu de règles, il est non valide avec exactement deux constats, tous deux de niveau erreur et tous deux à l'étape EN 16931 :

  • BR-CO-10 : le total des lignes (750.00) n'est pas la somme des montants nets des lignes (740.00).
  • BR-CO-13 : le total hors TVA (740.00) n'est plus le total des lignes moins les remises plus les frais (750.00).

Un seul champ erroné produit deux constats, car une seconde règle dépend de la même valeur. Le total TVA comprise et le montant à payer concordent toujours entre eux, si bien qu'aucune autre règle ne se déclenche. La correction consiste à remettre la vraie somme, 740.00, dans LegalMonetaryTotal/LineExtensionAmount : c'est l'exemple valide ci-dessus.

L'adapter à une vraie facture

  • Remplacez les deux parties, y compris chaque EndpointID et son schemeID, par les identifiants enregistrés pour le vrai vendeur et le vrai acheteur.
  • Utilisez vos vrais numéro de TVA, numéro de facture, dates, référence de l'acheteur ou de commande, et compte de paiement.
  • Choisissez la catégorie et le taux de TVA qui s'appliquent à chaque ligne. Les catégories autres que S (taux zéro, exonération, autoliquidation et autres) ont leurs propres règles ; cet exemple ne les couvre pas, et savoir laquelle s'applique est une question fiscale pour votre conseiller.
  • N'ajoutez des remises ou des frais au niveau du document qu'avec leurs totaux et leur effet fiscal, afin que les calculs ci-dessus concordent toujours.
  • Gardez une seule devise d'un bout à l'autre, et validez chaque modification avant l'envoi.

Un résultat valide signifie que le document a réussi les contrôles du schéma UBL et des règles EN 16931 et Peppol BIS Billing pour la version indiquée. Il n'envoie pas la facture, n'inscrit personne sur le réseau Peppol, ne prouve pas qu'un destinataire l'acceptera et ne la certifie pas à des fins fiscales. La remise se fait par un point d'accès Peppol. L'article en anglais How Peppol invoice validation actually works explique les étapes par lesquelles passe un document.

Valider depuis du code

Le validateur du site est gratuit sans compte. Pour contrôler des documents depuis votre propre système, envoyez les mêmes octets à l'API de validation avec une clé API Ironfang qui dispose de la portée finance:einvoices:write :

curl --fail-with-body https://api.ironfang.uk/finance/v1/einvoices/validate \
      -H "Authorization: Bearer $IRONFANG_API_KEY" \
      -H 'Content-Type: application/xml' \
      --data-binary @peppol-bis-billing-3-invoice.xml

La réponse est un JSON avec le résultat, le jeu de règles, un statut pour chaque étape et chaque constat avec son identifiant de règle. Le guide de l'API Finance couvre les portées, les limites et les résultats enregistrés, la référence des règles explique les constats règle par règle, et la génération à partir de JSON construit pour vous des documents comme celui-ci, validés avant d'être renvoyés ; le bac à sable JSON de facture vous permet de l'essayer sans compte.