eInvoice Validator for PEPPOL & EN16931

Solution 3 · free

The official validator. On your server.

One shortcode puts the official KoSIT validator on your page. A visitor drops an e-invoice XML onto it, the plugin runs it through exactly the Schematron and XSD scenarios the XRechnung ecosystem itself relies on, and shows the verdict with every finding. Nothing leaves your server: no third-party validation API, no account, no key.


Real output, not a mockup

KoSIT validation report: rejected with four errors, each finding with its rule identifier, plain-language text and XPath

A rejected report: four errors, each with its rule identifier, the rule text in plain language and the exact location in the document. Separated into errors, warnings and notices.

Not a reimplementation

The same tool the reference body itself uses.

Tools Tools

The real validator.jar

The plugin runs the Java application the German XRechnung project ships itself — and the one PEPPOL and Factur-X publish their own scenario configurations for. Not a rebuilt approximation of the rules.

Note Note

Three rule sets in turn

XRechnung 3.0.2, ZUGFeRD / Factur-X EN16931 including EXTENDED, and PEPPOL BIS Billing 3.0. Every configured scenario is tried in turn, so one upload is checked against every format it could plausibly be. A format that is not installed is skipped rather than treated as an error.

Search Search

Rejected is not broken

The KoSIT validator also exits with an error code when it correctly finds a document invalid — which, for a faulty invoice, is the expected outcome. So the verdict never hangs on the exit code alone, but on whether a report was produced at all.

What comes out

The authoritative report — or one in plain language.

The raw KoSIT report XML is always offered as a download — for anyone who needs the authoritative artefact itself, to file or to pass on.

With the Validation Explainer active alongside, the same report appears in plain language instead: every finding labelled with its EN 16931 business term, inside a nested Shadow DOM so its typography never leaks into the surrounding page. If the Explainer cannot make sense of a report, the raw KoSIT HTML is shown rather than nothing.

Working with its neighbours

Explainer takes over the presentation of the report as soon as it is active.

Viewer gains a „check with the KoSIT validator“ button right in its result view — for the invoice the visitor has already uploaded. No second upload, no page change.

No configuration both bridges depend only on the other plugin being there. If it is missing, nothing breaks.

Accepted validation report listing the individual validation steps: XML schema, Schematron rules and val.xml, all without errors

Accepted: the validation steps listed one by one – XML schema, Schematron rules, val.xml.

Document content of the checked invoice with the offending line highlighted

The document content alongside – the offending line is marked right in the tree.

A process that takes real seconds

A Java run that gets in nobody’s way.

Unlike the Viewer and the Explainer, this plugin cannot avoid a temporary file: the validator command line wants a file path, not data on standard input. The compensating control is a fresh, unpredictably named directory per request — outside the uploads folder, deleted together with the report in a finally block that runs whether the check succeeded, failed or threw.

A hanging validator cannot wedge a worker: the process output is drained non-blocking in the same loop that watches the timeout, not only once the process is done. The process itself is invoked in array mode rather than as a composed shell string, which avoids Windows path-escaping pitfalls entirely.

Requirements and settings

Requires a local Java runtime and a KoSIT validator installation. Neither is bundled — the plugin invokes an existing installation.

Settings validator directory, path to the Java binary, timeout, daily limit, maximum file size, proxy header.

Timeout a run typically takes 10–15 seconds, because the JVM starts and the scenarios are loaded. Default 60 seconds.

Daily limit per visitor, logged-in by user ID, anonymous by hashed IP — more important here than in the sibling plugins, because every upload starts a Java process lasting several seconds.

Embedding kosit_validator in square brackets, no attributes. Plus the REST route POST /wp-json/einvoice/v1/validate.

Environment WordPress 5.8+ (tested up to 7.1), PHP 8.2+.

Checking is one thing. Understanding is another.

The Validator delivers the verdict, the Validation Explainer turns it into sentences you can read without knowing Schematron. Together that is two plugins and one upload.