Download or validate the example
- Result
- Valid: XML, UBL schema, EN 16931 and Peppol layers all passed, with no warnings.
- Checked
- 23 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_r4, VESIDeu.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>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>
Specification identifiers and invoice details
<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>CustomizationIDsays 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.ProfileIDnames the business process, here the Peppol billing process 01.ID,IssueDateandDueDateare the invoice number and dates, dates always in YYYY-MM-DD form.InvoiceTypeCode380 is a commercial invoice; a credit note is normally sent as a separateCreditNotedocument.DocumentCurrencyCodeis the currency every amount is stated in, and every amount repeats it in acurrencyIDattribute.BuyerReferenceis 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>accounts@supplier.example.test</cbc:ElectronicMail>
</cac:Contact>
</cac:Party>
</cac:AccountingSupplierParty>EndpointIDis 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 inschemeID(BR-62, BR-63).- Scheme
0088is 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. PartyTaxSchemecarries the seller's VAT number, andPartyLegalEntitythe registered legal name.PartyIdentificationis 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.
| Line | Item | Quantity | Price | Net amount |
|---|---|---|---|---|
| 1 | Example widget | 10 one (unit) (C62) | 50.00 | 10 x 50.00 = 500.00 |
| 2 | Installation service | 2 hour (HUR) | 120.00 | 2 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:
| Field | Calculation | GBP | Rule |
|---|---|---|---|
LineExtensionAmount | 500.00 + 240.00 | 740.00 | BR-CO-10 |
TaxExclusiveAmount | Line total, less document allowances, plus charges (none here) | 740.00 | BR-CO-13 |
TaxableAmount (S, 20%) | Net of the lines in category S | 740.00 | BR-S-08 |
TaxAmount (S, 20%) | 740.00 x 20%, rounded to two decimals | 148.00 | BR-S-09 |
TaxTotal/TaxAmount | Sum of the breakdown tax amounts | 148.00 | BR-CO-14 |
TaxInclusiveAmount | 740.00 + 148.00 | 888.00 | BR-CO-15 |
PayableAmount | Total with VAT, less prepaid, plus rounding (neither here) | 888.00 | BR-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
EndpointIDand itsschemeID, 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.uk/finance/v1/einvoices/validate \
-H "Authorization: Bearer $IRONFANG_API_KEY" \
-H 'Content-Type: application/xml' \
--data-binary @peppol-bis-billing-3-invoice.xmlThe 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.
