Skip to content

Ironfang Finance - Example

Peppol XML invoice example

A complete Peppol BIS Billing 3 invoice in UBL XML that passes validation, explained field by field, with a broken copy that shows what a totals error looks like and how it is fixed.

Download or validate the example

Result
Valid: XML, UBL schema, EN 16931 and Peppol layers all passed, with no warnings.
Checked
25 September 2026, with the free Ironfang Finance validator
Rules
Peppol BIS Billing 3.0, May 2026 release (2026.5, also known as 3.0.21); ruleset fwrs_bis3_billing_invoice_2026_5_r5, VESID eu.peppol.bis3:invoice:2026.5
Engine
phive 12.1.0 with phive-rules-peppol 4.5.6 and Saxon-HE 12.10
SHA-256
c9d1474941163526a1a518405de43c5a31d3f5261a72adf80877cc9389534ea9

Everything in it is fictional: example.test addresses, and GS1 location numbers under prefix 952, which GS1 reserves for demonstrations. The endpoint identifiers are not registered Peppol participants; never send a real document to them.

The whole invoice

This is the complete document, exactly as downloaded. The sections below take it apart. It is the same file the validator's Try a valid sample button sends.

<?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>[email protected]</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>[email protected]</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 says which specification the invoice follows. This value is Peppol BIS Billing 3.0 on top of the EN 16931 core; the validator uses it to choose the ruleset, and a receiving access point uses it to know what it has.
  • ProfileID names the business process, here the Peppol billing process 01.
  • ID, IssueDate and DueDate are the invoice number and dates, dates always in YYYY-MM-DD form. InvoiceTypeCode 380 is a commercial invoice; a credit note is normally sent as a separate CreditNote document.
  • DocumentCurrencyCode is the currency every amount is stated in, and every amount repeats it in a currencyID attribute.
  • BuyerReference is the reference the buyer asked you to quote. Peppol requires either it or a purchase order reference (PEPPOL-EN16931-R003).

Seller, buyer and electronic addresses

<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>[email protected]</cbc:ElectronicMail>
        </cac:Contact>
    </cac:Party>
</cac:AccountingSupplierParty>
  • EndpointID is the party's electronic address on the Peppol network: where a document for them is delivered. Both parties must have one (PEPPOL-EN16931-R020 for the seller, PEPPOL-EN16931-R010 for the buyer), and each must say which identifier scheme it uses in schemeID (BR-62, BR-63).
  • Scheme 0088 is a GS1 Global Location Number, from the Electronic Address Scheme code list. Real invoices often use a national company or VAT number scheme instead; use the scheme and value your access point registered for you.
  • PartyTaxScheme carries the seller's VAT number, and PartyLegalEntity the registered legal name. PartyIdentification is an optional further identifier.

The buyer is built the same way, with its own address:

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

Invoice lines

<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>

Each line has a quantity with a unit from UN/ECE Recommendation 20 (C62 means one unit, HUR an hour), a net amount, the item and its VAT category, and the unit price. Category S is the standard rate, here 20 percent. The line net amount is quantity times price, with no allowances or charges on these lines.

Invoice line calculations
LineItemQuantityPriceNet amount
1Example widget10 one (unit) (C62)50.0010 x 50.00 = 500.00
2Installation service2 hour (HUR)120.002 x 120.00 = 240.00

Tax breakdown and document totals

<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>

Every total can be worked out from the lines, and the EN 16931 rules check each step:

How the totals reconcile
FieldCalculationGBPRule
LineExtensionAmount500.00 + 240.00740.00BR-CO-10
TaxExclusiveAmountLine total, less document allowances, plus charges (none here)740.00BR-CO-13
TaxableAmount (S, 20%)Net of the lines in category S740.00BR-S-08
TaxAmount (S, 20%)740.00 x 20%, rounded to two decimals148.00BR-S-09
TaxTotal/TaxAmountSum of the breakdown tax amounts148.00BR-CO-14
TaxInclusiveAmount740.00 + 148.00888.00BR-CO-15
PayableAmountTotal with VAT, less prepaid, plus rounding (neither here)888.00BR-CO-16

Calculate these with decimal arithmetic, not floating point, and round each amount to two decimals where the rules say so. A total built by adding binary floating-point numbers can come out a penny off, which is enough to fail. The Understanding EN 16931 validation errors article explains the calculation rules in more depth.

Payment details

<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>

Payment means code 30 is a credit transfer. PaymentID is the reference the buyer should quote when paying, and PayeeFinancialAccount/ID the account to pay into: an IBAN, or the account identifier your banking arrangement uses. This sample's account is a placeholder, not a bank account.

A broken copy, and the fix

The second sample is the same invoice with one number changed: the document's line total says 750.00 where the two lines add up to 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>

Validated on the same day with the same ruleset, it is invalid with exactly two findings, both fatal and both in the EN 16931 layer:

  • BR-CO-10: the line total (750.00) is not the sum of the line net amounts (740.00).
  • BR-CO-13: the total without VAT (740.00) is no longer the line total less allowances plus charges (750.00).

One wrong field produces two findings, because a second rule depends on the same value. The totals with VAT and payable still agree with each other, so no other rule fires. The fix is to put the true sum, 740.00, back into LegalMonetaryTotal/LineExtensionAmount: that is the valid sample above.

Adapting it to a real invoice

  • Replace both parties, including each EndpointID and its schemeID, with the identifiers registered for the real seller and buyer.
  • Use your real VAT number, invoice number, dates, buyer reference or order reference, and payment account.
  • Choose the VAT category and rate that apply to each line. Categories other than S (zero rated, exempt, reverse charge and others) bring their own rules; this example does not cover them, and which one applies is a tax question for your adviser.
  • Add document-level allowances or charges only with their totals and tax effect, so the calculations above still reconcile.
  • Keep one currency throughout, and validate every change before sending it.

A valid result means the document passed the UBL schema, EN 16931 and Peppol BIS Billing rules for the stated release. It does not send the invoice, register anybody on the Peppol network, prove a recipient will accept it, or certify it for tax purposes. Delivery happens through a Peppol access point. The How Peppol invoice validation actually works article explains the layers a document passes through.

Validating from code

The validator on the site is free without an account. To check documents from your own system, send the same bytes to the validation API with an Ironfang API key that has the finance:einvoices:write scope:

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

The response is JSON with the outcome, the ruleset, a status for each layer and every finding with its rule identifier. The Finance API guide covers scopes, limits and stored results, the rule reference explains findings one rule at a time, and generation from JSON builds documents like this one for you, validated before they are returned; the invoice JSON playground lets you try it without an account.