Veelvoorkomende Peppol BIS 3.0 validatiefouten en hoe je ze oplost
Peppol BIS 3.0 validatiefouten vallen in een voorspelbare set categorieen. De foutmeldingen verwijzen naar business rule-codes (BR-xx) en business term-nummers (BT-xx) uit de EN16931-standaard, waarvoor de specificatie vereist is om ze te interpreteren. Dit artikel koppelt de meest voorkomende fouten aan hun oorzaken en biedt concrete oplossingen.
Alle voorbeelden gebruiken UBL 2.1-syntaxis. Voor CII-equivalenten, zie UBL vs CII.
BR-01 t/m BR-06: ontbrekende verplichte headervelden
Deze regels controleren de aanwezigheid van verplichte velden op het hoogste niveau. Ze falen wanneer een element ontbreekt of leeg is.
| Regel | Veld | BT | Oplossing |
|---|---|---|---|
| BR-01 | Specificatie-identifier | BT-24 | Voeg CustomizationID toe met de exacte Peppol BIS 3.0-URI |
| BR-02 | Factuurnummer | BT-1 | Voeg een niet-leeg ID-element toe |
| BR-03 | Factuurdatum | BT-2 | Voeg IssueDate toe in JJJJ-MM-DD-formaat |
| BR-04 | Valutacode factuur | BT-5 | Voeg DocumentCurrencyCode toe met ISO 4217-code |
| BR-05 | Naam verkoper | BT-27 | Voeg AccountingSupplierParty/Party/PartyName/Name toe |
| BR-06 | Naam koper | BT-44 | Voeg AccountingCustomerParty/Party/PartyName/Name toe |
BR-01 specifiek: de meest voorkomende oorzaak is het gebruik van de EN16931-basis-URI in plaats van de Peppol BIS 3.0-URI. Deze lijken op elkaar maar zijn verschillend:
Fout (EN16931-basis):
<cbc:CustomizationID>urn:cen.eu:en16931:2017</cbc:CustomizationID>
Correct (Peppol BIS 3.0):
<cbc:CustomizationID>
urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::2.1
</cbc:CustomizationID>
De validator controleert de exacte string. Zie Peppol BIS 3.0 introductie voor context over waarom dit belangrijk is.
BR-CO-10: som van regelbedragen komt niet overeen met totaal
[BR-CO-10]-Sum of Invoice line net amount (BT-106) =
sum of Invoice line net amount (BT-131).
Deze regel vereist dat LegalMonetaryTotal/LineExtensionAmount (BT-106) gelijk is aan de som van alle InvoiceLine/LineExtensionAmount-waarden (BT-131).
De fout is bijna altijd een afrondingsfout. Als je elk regelbedrag afzonderlijk afrondt voordat je optelt, kan de som van afgeronde waarden afwijken van de afgeronde som van de ruwe waarden.
Fout (afronden per regel, dan optellen):
// Regel 1: 3 x 33,333... = 100,00 (afgerond)
// Regel 2: 3 x 33,333... = 100,00 (afgerond)
// Som van afgeronden: 200,00
// Maar ruwe som: 3 x 33,333... + 3 x 33,333... = 200,00 exact in dit geval
De fout is duidelijker zichtbaar bij tarieven zoals 7% btw op wisselende hoeveelheden waarbij afrondingsverschillen over veel regels accumuleren.
Correct: optellen van de ruwe niet-afgeronde waarden over alle regels, dan eenmalig afronden van het aggregaat:
var lineNetTotal = invoiceLines.Sum(l => l.Quantity * l.UnitPrice); // ruw
var lineNetTotalRounded = Math.Round(lineNetTotal, 2, MidpointRounding.AwayFromZero);
BR-CO-15: rekenkundig probleem met het btw-bedrag van de factuur
[BR-CO-15]-Invoice total VAT amount (BT-110) =
sum of VAT category tax amount (BT-117).
Het totale btw-bedrag in TaxTotal/TaxAmount moet gelijk zijn aan de som van de TaxTotal/TaxSubtotal/TaxAmount-waarden over alle belastingcategorieen.
Voor een factuur met een enkel tarief lijkt dit triviaal, maar fouten doen zich voor wanneer:
- Er meerdere btw-tarieven zijn en de afronding per categorie wordt toegepast in plaats van op het aggregaat
- Een nultarief- of vrijgestelde categorie aanwezig is en haar
TaxAmount0.00is in plaats van afwezig - Het
TaxAmountop het niveau vanTaxTotalonafhankelijk van deTaxSubtotal-bedragen wordt berekend
Oplossing: bereken eerst alle TaxSubtotal/TaxAmount-waarden, tel ze op en gebruik die som als de TaxTotal/TaxAmount-waarde. Bereken TaxTotal/TaxAmount niet apart.
BR-CO-16: te betalen bedrag
[BR-CO-16]-Amount due for payment (BT-115) =
Invoice total with VAT (BT-112) - Paid amount (BT-113) + Rounding amount (BT-114).
Als BT-113 (betaald bedrag) en BT-114 (afrondingsbedrag) niet aanwezig zijn, vereenvoudigt dit tot BT-115 = BT-112. De fout treedt op wanneer PayableAmount en TaxInclusiveAmount meer dan de toegestane afrondingstolerantie van elkaar afwijken.
Veelvoorkomende oorzaak: PayableAmount berekenen op basis van afgeronde regelbedragen en TaxInclusiveAmount op basis van een afzonderlijke totaalberekening die een licht afwijkend resultaat oplevert.
Oplossing: bereken een enkel canoniek eindbedrag en gebruik dat voor zowel TaxInclusiveAmount als PayableAmount.
BR-S-08 en BR-S-09: consistentie btw-tarief en -bedrag
[BR-S-08]-For each different value of VAT category rate (BT-119) where the
VAT category code (BT-118) is "S", the VAT category taxable amount (BT-116)
in a VAT breakdown (BG-23) shall equal the sum of Invoice line net amounts
(BT-131) where the VAT category code of the Invoice line (BT-151) is "S"
and the VAT rate for the Invoice line (BT-152) equals the VAT category rate.
Deze regel groepeert alle regels per btw-tarief en verifieert dat het belastbare bedrag in elk TaxSubtotal overeenkomt met de som van regels met dat tarief. De fout treedt op wanneer:
- Een regel een btw-tarief heeft waarvoor geen corresponderende
TaxSubtotalbestaat - Een
TaxSubtotalbestaat voor een tarief maar geen regels dat tarief gebruiken - Afrondingsverschillen accumuleren tussen berekeningen op regelniveau en subtotaalniveau
Oplossing: bouw de TaxSubtotal-elementen dynamisch op uit de regelitems, gegroepeerd op (btw-categoriecode, btw-tarief), in plaats van ze onafhankelijk te construeren.
BR-E-01 / BR-AE-01: facturen met verlegging en vrijstelling
[BR-E-01]-An Invoice that contains an Invoice line (BG-25), a Document level
allowance (BG-20) or a Document level charge (BG-21) where the VAT category
code (BT-151) is "E" shall contain exactly one VAT breakdown...
Facturen met vrijgestelde (E), verlegd (AE) of nultarief (Z) btw vereisen specifieke TaxCategory-structuren die afwijken van standaard (S) tarief-facturen.
Veelgemaakte fouten:
ID-waardeSgebruiken voor alle regels, ongeacht de werkelijke btw-behandeling- Het ontbreken van de vereiste
TaxExemptionReasonCodeofTaxExemptionReasonvoor vrijgestelde categorieen - Het ontbreken van
AccountingSupplierParty/Party/PartyTaxSchemewanneer de factuur verlegging bevat
Bij verlegging (AE) moeten zowel de btw-identificator van de belastingregeling van de koper aanwezig zijn als de btw-identificator van de verkoper.
Peppol-specifieke extensieregels: Duitsland
Duitse Peppol-profielen voegen regels toe bovenop de EN16931-basis. Veelvoorkomende fouten:
BR-DE-TMP-32: leveringsdatum (BT-72) is verplicht voor Duitse B2G-facturen. Voeg Delivery/ActualDeliveryDate toe in JJJJ-MM-DD-formaat.
BR-DE-18: hetzij de btw-identificator van de verkoper (BT-31) hetzij een belastingregistratienummer (BT-32) moet aanwezig zijn. Als beide ontbreken, volgt afwijzing. Als de verkoper btw-vrijgesteld is, geef dan BT-32 op met het belastingregistratienummer.
BR-DE-16: de koperreferentie (BT-10, Leitweg-ID) is verplicht voor Duitse B2G-facturen. Het Leitweg-ID-formaat wordt gevalideerd: het moet overeenkomen met het patroon \d{2,12}-\d{4,12}-\d{2}.
Efficient debuggen
De Schematron-foutuitvoer bevat een XPath-locatie:
<svrl:failed-assert location="/Invoice[1]/cac:LegalMonetaryTotal[1]">
<svrl:text>[BR-CO-10]-Sum of Invoice line net amounts...</svrl:text>
</svrl:failed-assert>
Gebruik de XPath-locatie om direct naar het falende element te navigeren. Voeg voor rekenkundige regels debug-uitvoer toe die de ruwe waarden voor afronding logt, zodat je kunt traceren waar de afwijking ontstaat.
De voorgecompileerde XSLT-bestanden van de Peppol BIS GitHub releases zijn de gezaghebbende validatieartefacten. Voer ze uit met Saxon HE zoals beschreven in Peppol BIS 3.0-facturen genereren in C#. Uitvoeren tegen de nieuwste release is belangrijk: regelsets worden bijgewerkt bij elke Peppol BIS-release, en een regel die slaagt tegen een oudere XSLT kan mislukken tegen de huidige.
SealDoc en validatiefouten
SealDoc voert EN16931- en Peppol BIS 3.0 Schematron-validatie uit op elke factuur voor aflevering. Wanneer validatie mislukt, retourneert de API een gestructureerde foutrespons die elke fout koppelt aan de BR-code, de geschonden BT en de XPath-locatie in het ingediende document.
Voor organisaties die een bestaande factuurgenerasiepijplijn debuggen, accepteert de SealDoc publieke validator UBL- en CII-factuurbestanden, voert de actuele Peppol BIS 3.0 XSLT uit en retourneert de volledige lijst van fouten met omschrijvingen in begrijpelijke taal. Regelsets worden actueel gehouden met Peppol BIS-releases, zodat de validator altijd de regels weerspiegelt die een ontvangend Access Point zal toepassen.