en16931_peppol 0.1.1
en16931_peppol: ^0.1.1 copied to clipboard
The Peppol BIS Billing 3.0 profile of the European electronic invoice: the identifiers it is claimed under, and the rules Peppol adds to EN 16931.
EN 16931 Peppol BIS #
Peppol BIS Billing 3.0: the 59 rules the network adds to EN 16931, and the identifiers an invoice is claimed under.
An invoice can satisfy the standard and still be refused by Peppol. This says so before it is sent.
Install #
dependencies:
en16931: ^0.1.0
en16931_peppol: ^0.1.0
Check an invoice #
Claim the profile on the invoice, then check it. The standard and the profile are checked together.
import 'package:en16931/en16931.dart';
import 'package:en16931_peppol/en16931_peppol.dart';
final invoice = Invoice.fromLines(
number: '2026-0042',
issueDate: DateTime(2026, 9, 13),
specificationIdentifier: peppolSpecification,
businessProcess: peppolBillingProcess,
buyerReference: 'PO-77812',
seller: const Seller(
name: 'COMAPPS SRL',
vatIdentifier: 'BE0123456789',
electronicAddress: Identifier('0123456749', scheme: Scheme.belgianEnterprise),
address: Address(city: 'Bruxelles', postalCode: '1000', country: 'BE'),
),
buyer: const Buyer(
name: 'Client SA',
electronicAddress: Identifier('0987654394', scheme: Scheme.belgianEnterprise),
address: Address(city: 'Namur', postalCode: '5000', country: 'BE'),
),
lines: [...],
);
for (final violation in validatePeppol(invoice)) {
print(violation);
}
What Peppol adds #
Three things an invoice that passes EN 16931 still gets refused for.
An electronic address on both sides. BT-34 and BT-49 are optional in the standard and required here, because they are how the network delivers.
A shorter list of address schemes. Peppol carries 94 of the schemes the standard allows, so a scheme that is perfectly valid under EN 16931 can still be refused.
A national identifier that is really shaped that way. A Belgian enterprise number under scheme 0208 has to pass the modulo 97 check, a GLN its GS1 check digit, an Australian Business Number its modulus 89. A receiver looks its supplier up by that number, and a mistyped one finds nobody.
isBelgianEnterprise('0123456749'); // true
isBelgianEnterprise('0123456789'); // false
Worth knowing up front #
Of the 59 rules, 48 are checked here, 6 cannot be broken by an invoice built
with this model, and 5 are about how the XML is put together rather than what
the invoice says. Those five belong to a syntax package, and
peppolForTheSyntax names them with what they ask.
The rule catalogue is read from the artefacts OpenPeppol publishes, so it is complete by construction. A test fails when a rule has no answer.
What it does not do #
It says whether an invoice is ready for the network, and nothing else. The model and the rules of the standard are in en16931, the document is written by en16931_ubl or en16931_cii, and sending it over an access point is a different problem again.
License #
MIT.
