Title: eInvoice Viewer for PEPPOL &amp; EN16931
Author: naranili
Published: <strong>September 19, 2026</strong>
Last modified: September 21, 2026

---

Search plugins

![](https://ps.w.org/einvoice-viewer-for-peppol-en16931/assets/banner-772x250.png?
rev=3703537)

![](https://ps.w.org/einvoice-viewer-for-peppol-en16931/assets/icon-256x256.png?
rev=3703537)

# eInvoice Viewer for PEPPOL & EN16931

 By [naranili](https://profiles.wordpress.org/naranili/)

[Download](https://downloads.wordpress.org/plugin/einvoice-viewer-for-peppol-en16931.2.14.10.zip)

 * [Details](https://wordpress.org/plugins/einvoice-viewer-for-peppol-en16931/#description)
 * [Reviews](https://wordpress.org/plugins/einvoice-viewer-for-peppol-en16931/#reviews)
 *  [Installation](https://wordpress.org/plugins/einvoice-viewer-for-peppol-en16931/#installation)
 * [Development](https://wordpress.org/plugins/einvoice-viewer-for-peppol-en16931/#developers)

 [Support](https://wordpress.org/support/plugin/einvoice-viewer-for-peppol-en16931/)

## Description

**➜ [Try the live demo](https://invoicepress.de/en/solutions/einvoice-tools/einvoice-viewer-for-peppol-en16931/einvoice-viewer-for-peppol-en16931-demo/)**–
upload an XRechnung, ZUGFeRD/Factur-X or Peppol BIS invoice and see it rendered 
instantly.

eInvoice Viewer for PEPPOL & EN16931 turns an uploaded electronic invoice into a
clear, structured HTML view directly on your page – without any external service
and without storing the file.

Add the `[einvoice_viewer]` shortcode to a page and your visitors can drag and drop
an electronic invoice into the viewer. **The document is read and rendered entirely
in the visitor’s own browser – it is never uploaded to your server.** The result(
invoice header, parties, order and delivery data, payment details, line items, VAT
breakdown and totals) appears instantly, without a page reload and without a single
byte of the invoice ever crossing the network. The layout is inspired by the official
ZUGFeRD Quba viewer and is rendered inside a Shadow DOM, so it looks identical in
every theme.

#### Supported formats

 * **ZUGFeRD / Factur-X (PDF)** – the embedded XML is extracted and read automatically.
 * **CII (UN/CEFACT) XML** – read directly.
 * **UBL / XRechnung (XML)** – converted to CII internally and then read.

#### Highlights

 * **Drag & drop uploader** – vanilla JavaScript, no framework, no page reload.
 * **Complete field coverage** – all 164 EN 16931 business terms and all 32 business
   groups, verified against 125 official sample invoices. Empty fields are shown
   as placeholders on purpose, so you can see which terms the standard defines and
   which ones this invoice omitted.
 * **Business-term labels with a short description** – each field can carry its 
   BT / BG code, and hovering it shows the term name plus a short description of
   the field in German, English or French. Further details (cardinality, data type,
   business rules) are provided by the separate “eInvoice Viewer – Technical Details”
   extension. Toggled live, per setting or via the shortcode attribute `bt="1"` /`
   bt="0"`.
 * **Trilingual** – the interface is available in English, German and French.
 * **Theme-independent** – rendered inside a Shadow DOM with a full style reset,
   so no theme styles leak through.
 * **The document never leaves your browser** – reading and rendering both happen
   client-side; your server never receives the file, so there is nothing to store,
   log or leak in the first place.
 * **Secure by design** – the invoice is parsed by the browser’s own `DOMParser`(
   no server-side XML parser, so no XXE surface for the upload itself); every invoice
   value is escaped on output. Sibling paid extensions that genuinely need server-
   side processing (validation, export, …) keep their own independent upload, nonce
   and rate-limit handling.
 * **Extensible** – additional layouts can be added as a template subclass, and 
   a structured-data API returns the whole invoice as a nested array. Two filters(`
   spev_code_tooltip`, `spev_invoice_model`) let an add-on extend the BT/BG tooltips
   and the invoice model itself.

#### Third-party libraries

Since reading moved into the browser, the only bundled third-party code is **Mozilla
pdf.js** (`assets/js/pdfjs/`, Apache License 2.0, license text next to the files),
used to pull the embedded XML out of a ZUGFeRD / Factur-X PDF. Everything else in`
vendor/` is this plugin family’s own code under GPL-2.0-or-later; `composer.lock`
lists it.

### Demo

Try the viewer without installing anything: [live demo on invoicePress.de](https://invoicepress.de/en/solutions/einvoice-tools/einvoice-viewer-for-peppol-en16931/einvoice-viewer-for-peppol-en16931-demo/).
Drop in your own e-invoice; it is read and rendered in your browser, exactly as 
on your own site. The plugin itself never contacts the demo site.

## Screenshots

[⌊The drag & drop uploader rendered by the [einvoice_viewer] shortcode.⌉⌊The drag&
drop uploader rendered by the [einvoice_viewer] shortcode.⌉[

The drag & drop uploader rendered by the `[einvoice_viewer]` shortcode.

[⌊A rendered invoice with the structured Quba-inspired layout.⌉⌊A rendered invoice
with the structured Quba-inspired layout.⌉[

A rendered invoice with the structured Quba-inspired layout.

[⌊The same invoice with the EN 16931 business-term numbers enabled.⌉⌊The same invoice
with the EN 16931 business-term numbers enabled.⌉[

The same invoice with the EN 16931 business-term numbers enabled.

[⌊The settings page under Settings -> E-Invoice Viewer.⌉⌊The settings page under
Settings -> E-Invoice Viewer.⌉[

The settings page under Settings -> E-Invoice Viewer.

## Installation

 1. Upload the plugin folder to `/wp-content/plugins/` or install it through the WordPress
    plugins screen.
 2. Activate the plugin through the “Plugins” screen in WordPress.
 3. Add the shortcode `[einvoice_viewer]` to any page or post. To show the EN 16931
    business-term numbers initially, use `[einvoice_viewer bt="1"]`.
 4. Optionally adjust the options under **Settings -> E-Invoice Viewer** (daily upload
    limit, maximum file size, proxy header, default BT visibility, layout template).

## FAQ

### Is the uploaded invoice stored anywhere?

No. The invoice is read and rendered entirely in the visitor’s own browser – it 
is never sent to your server, so there is nothing to store, log or delete. Nothing
is written to the uploads directory or the database. (Paid sibling extensions that
genuinely need server-side processing, such as validation or export, do their own
upload and say so.)

### Which invoice formats are supported?

ZUGFeRD and Factur-X PDFs (the embedded XML is extracted), plus CII (UN/CEFACT) 
XML and UBL / XRechnung XML.

### Why does the view not look pixel-perfect like the Quba viewer?

The Quba viewer transforms the invoice with the KoSIT XRechnung XSLT 3.0 via Saxon-
JS. PHP only supports XSLT 1.0, so an own, Quba-inspired PHP template is used instead–
functionally equivalent, but not the identical KoSIT markup.

### Can I limit how many invoices a visitor can upload?

Yes. Under Settings -> E-Invoice Viewer you can set a daily upload limit per visitor(
logged-in users are counted by user ID, anonymous visitors by hashed IP address).

## Reviews

There are no reviews for this plugin.

## Contributors & Developers

“eInvoice Viewer for PEPPOL & EN16931” is open source software. The following people
have contributed to this plugin.

Contributors

 *   [ naranili ](https://profiles.wordpress.org/naranili/)

[Translate “eInvoice Viewer for PEPPOL & EN16931” into your language.](https://translate.wordpress.org/projects/wp-plugins/einvoice-viewer-for-peppol-en16931)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/einvoice-viewer-for-peppol-en16931/),
check out the [SVN repository](https://plugins.svn.wordpress.org/einvoice-viewer-for-peppol-en16931/),
or subscribe to the [development log](https://plugins.trac.wordpress.org/log/einvoice-viewer-for-peppol-en16931/)
by [RSS](https://plugins.trac.wordpress.org/log/einvoice-viewer-for-peppol-en16931/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

#### 2.14.10

 * Changed: the bundled business-term catalogue is now much smaller (about 1.0 MB
   down to 0.2 MB) because it only carries what the viewer actually shows. The tooltips
   are unchanged: term name and a short description in German, English or French.
 * Fixed: the FAQ still said the invoice was uploaded to your server and that browser-
   side reading would come “in a future version” – it has been client-side since
   2.12.0. The answer now describes what the plugin actually does.
 * Changed: removed an unused internal file left over from the move to client-side
   rendering.

#### 2.14.9

 * Fixed: the “eInvoice Viewer — Technical Details” add-on’s tooltip enrichment (
   cardinality, data
    type, applicable rules, XSD level, reference table, CII/UBL
   path) stopped appearing when this plugin’s own rendering moved fully client-side–
   its PHP filter hook no longer fires for that code path. The BT/BG tooltip now
   calls that add-on’s own client-side module directly, the same way the Extended
   Profiles add-on’s model extension was already fixed.

#### 2.14.8

 * Fixed: when a trade party (seller, buyer, delivery location, payee) carries both
   a plain
    identifier and a global identifier (e.g. an ERP customer number alongside
   a GLN) at the same time, the plain identifier was silently dropped and its value
   shown mislabeled under the global-identifier’s BT tag. Both are now shown independently
   under their own correct BT tags (BT-29/-46/-60/-71 for the plain identifier, 
   the matching “-0″/”-1″ tags for the global identifier and its scheme).

#### 2.14.7

 * Fixed: on some hosts, uploading a PDF failed with “Failed to fetch dynamically
   imported module” –
    the bundled pdf.js files used the newer `.mjs` extension,
   which some servers have no correct file type mapping for. Renamed to the universally-
   supported `.js` extension; no behaviour change.

#### 2.14.6

 * Fixed: the pdf.js library the PDF-reading fix in 2.14.5 relies on was loaded 
   from a third-party
    CDN (cdnjs.cloudflare.com) – it is now bundled with the plugin
   instead, same as every other script and font here.

#### 2.14.5

 * Fixed: uploading a PDF (ZUGFeRD/Factur-X) still failed with “The PDF does not
   contain a readable
    e-invoice” even after 2.14.3’s pdf.js fix – a pdf.js update
   changed how attached files are read, and this plugin’s own code had not caught
   up. Verified this time against multiple real ZUGFeRD/ Factur-X sample invoices
   before release, not just claimed fixed.

#### 2.14.4

 * Changed: the visitor-facing colour accent (previously teal-blue and orange, from
   the original
    product logo) is now the same navy used across the rest of the 
   specialPress/invoicePress tool family, so the plugin’s look matches the family
   it belongs to.

#### 2.14.3

 * Fixed: uploading a PDF (ZUGFeRD/Factur-X) failed with “PDF reading needs pdf.
   js, which this page
    has not loaded.” – the PDF-reading library is now loaded
   automatically, only when a PDF is actually uploaded.
 * Fixed: for a UBL/PEPPOL-BIS invoice, several fields (party identifier schemes,
   unit codes, the
    payment means name, item classification codes) always rendered
   empty regardless of the document’s actual content.
 * Fixed: for a UBL/PEPPOL-BIS invoice, the delivery information section (deliver-
   to party, address,
    delivery date) always rendered empty regardless of the document’s
   actual content.

#### 2.14.2

 * Fixed: on some sites the upload widget could render an empty box with no error–
   depended on the
    active theme’s own template structure, not anything a visitor
   did. The required script could end up queued before it was registered, which 
   silently dropped the configuration data it needed.

#### 2.14.1

 * Fixed: the plugin header was missing a “Requires PHP” line.

Note: versions 2.12.5 through 2.14.0 are not documented here yet – this file’s changelog
fell behind
 the plugin’s actual version for a stretch and has not been fully backfilled.

#### 2.12.4

 * Fixed: the paid “Extended Profiles” add-on’s fields (Ship From, Invoicer, Invoicee,
   Product end user, Ultimate ship to, Buyer tax representative, document flags,
   cash discount / penalty payment terms, further references) had silently stopped
   appearing in the rendered invoice since 2.12.0, because the add-on’s own server-
   side hook no longer fires now that rendering happens entirely in the browser.
   It now hooks into the same client-side render path directly.

#### 2.12.3

 * The “Export to Excel” and “Visualizer” add-on buttons now also read the already-
   built client-side identifier model instead of re-sending the file for a second
   server-side parse – completes the same move for all four toolbar bridge extensions(
   Inbound Check and Identifier Check already made it in 2.12.1/2.12.2).

#### 2.12.2

 * The Identifier Check add-on now also reads the already-built client-side identifier
   list instead of re-sending the file for a second server-side parse – the same
   move already made for the Inbound Check add-on in 2.12.1. The remaining extensions(
   Excel export, Visualizer, Technical Details) still parse server-side for now 
   and are unaffected either way.

#### 2.12.1

 * The already-built client-side model is now also handed to any extension that 
   asks for it, instead of the extension re-sending the file for a second server-
   side parse. The Inbound Check add-on is the first to use this (its findings are
   now unaffected by this plugin’s own move to client-side rendering); the remaining
   extensions still parse server-side for now and are unaffected either way.

#### 2.12.0

 * **The invoice is now read and rendered entirely in the browser – it is never 
   uploaded to the server.** The upload endpoint, its nonce and its daily rate limit
   are gone from this plugin; the shortcode’s own JavaScript parses and renders 
   the file client-side, using the same code the standalone `@einvoice/core` Web
   Component uses. The paid companion extensions (KoSIT validator, Excel export,
   Visualizer, Identifier Check, Inbound Check, Technical Details) are unaffected
   and keep working exactly as before – they each still send the file to their own,
   independent endpoint when their own feature is used.
 * Business-term tooltips are now fetched and rendered client-side too, in the visitor’s
   own language (German/English/French, same as before).
 * Known, temporary trade-off: the Technical Details add-on’s tooltip extension (
   cardinality, data type, applicable rules) is not yet available in the client-
   rendered view – the BT/BG tooltip still shows the term name and description, 
   just without that extra detail for now.

#### 2.10.10

 * The upload dialog now measures exactly the same width (900px) in the Viewer, 
   the Validator and the Explainer, matching the two existing tools instead of the
   other way round.

#### 2.10.9

 * Fixed: the rendered invoice was capped to the upload box’s own, narrower width
   instead of using the full width available to the shortcode.

#### 2.10.8

 * New “Field Browser” and “Rule Browser” buttons in the result toolbar when the
   companion eInvoice Viewer – Technical Details add-on is active – each opens pre-
   filtered to the uploaded invoice’s own syntax (CII/UBL), scope (EN16931/EXTENDED)
   and rule set.

#### 2.10.7

 * New `spev_register_settings` action lets a companion add-on (currently the Exporter)
   add its own settings block to this plugin’s own Settings page.

#### 2.10.4

 * The shared rate-limiting/nonce/REST plumbing is now vendored via Composer instead
   of a hand-copied folder – internal packaging change, no user-visible effect.

#### 2.10.3

 * Updated the bundled horstoeko/invoicesuite library to v0.0.31, which fixes an
   upstream bug where the buyer’s contact card could show the seller’s contact name,
   phone and e-mail instead of the buyer’s own.

#### 2.10.2

 * The document hero no longer shows BT badges, even with “Show BT numbers” on –
   the same fields already carry their BT code in the Invoice data card below.
 * Swapped the display position of BT-5 (Currency) and BT-74 (End date) in the Invoice
   data card.
 * In the allowances/charges and VAT breakdown tables, each cell’s BT/BG badge now
   renders above its value instead of beside it.
 * The “Allowances & charges” table heading now names both business groups it covers(
   BG-20 and BG-21).

#### 2.10.1

 * Fixed: the buyer’s contact card silently showed the seller’s contact name, phone
   and e-mail (BT-56/BT-57/BT-58) whenever a document had a seller contact but no
   buyer one – worked around a bug in the vendored horstoeko/invoicesuite library.
 * Fixed: BT-10 (Buyer reference) was shown twice – once correctly under Invoice
   data, a second time under Buyer information where it does not belong.
 * Fixed: BT-33 (Seller further legal information) never displayed even when the
   source document carried it.

#### 2.10.0

 * New `SPEV_Renderer::model_json()` – the same model as `model()`, as a JSON string.
   Purely additive; `model()` itself is unchanged.
 * New `spev_register_templates` action: a companion plugin can register additional
   layouts from the outside without touching this plugin’s code. First consumer:
   the new eInvoice Viewer – Visualizer add-on, four print-oriented layouts selectable
   in Settings -> E-Invoice Viewer -> Layout template.

#### 2.9.0

 * Rate limiting and the einvoice/v1 REST namespace unified with the companion Explainer,
   Validator and Exporter plugins into a shared library – existing settings carry
   over unchanged. New route POST /wp-json/einvoice/v1/render, alongside the existing
   admin-ajax.php action.
 * horstoeko/invoicesuite updated to v0.0.30.

#### 2.8.0

 * Optional Excel export button in the result view when the companion eInvoice Viewer–
   Exporter add-on is active.

#### 2.7.0

 * Optional “Check with KoSIT” button in the result view when the companion eInvoice
   Validator add-on is active – runs the official KoSIT Validator against the uploaded
   invoice and shows the report in the Validation Explainer’s own layout, without
   leaving the page.

#### 2.6.1

 * Two more coded fields resolved to their designation instead of showing a bare
   code: BT-21 (note subject code) and BT-128-0 (scheme of a line’s object identifier).

#### 2.6.0

 * Fixed: the uploader dialog and its status messages always showed the site’s default
   language instead of the current visitor’s own language, even though the rendered
   invoice already respected it correctly (a WordPress quirk: requests through admin-
   ajax.php resolve the locale differently from an ordinary page load).
 * Code values are now shown as “code – designation” throughout (was “designation(
   code)”).
 * More coded fields resolved to their designation instead of a bare code: BT-29-
   1 / BT-46-1 (scheme of the seller/buyer identifier), BT-30-1 / BT-47-1 (scheme
   of the registration number), BT-34-1 / BT-49-1 (scheme of the electronic address)
   and BT-157-1 (scheme of the item identifier).
 * Fixed: a long CII/UBL XPath in a business-term tooltip could overflow the tooltip
   box instead of wrapping onto a new line.

#### 2.5.3

 * The reading engine now uses `horstoeko/invoicesuite` instead of `horstoeko/zugferd`(
   no visible change for existing installations).

#### 2.5.2

 * Fixed: BT-29-1 / BT-46-1 (scheme of the seller/buyer identifier) stayed empty
   when the source invoice carried the scheme on the plain identifier element instead
   of the separate global-identifier element – a real-world pattern the reading 
   library’s own convenience API does not expose on its own.

#### 2.5.0

 * New `spev_invoice_model` filter lets an add-on append whole additional sections
   to the invoice model.

#### 2.4.0

 * New `spev_code_tooltip` filter lets an add-on extend a business-term tooltip 
   with additional information (cardinality, data type, reference table, XSD level,
   XPath).
 * Fixed: the business-term tooltip cache was shared across every rendered invoice
   instead of being scoped to one render, which could show one invoice’s tooltip
   wording on another.

#### 2.3.0

 * Typography and colour palette aligned with the companion Validation Explainer
   plugin (Inter / Space Grotesk / JetBrains Mono, a neutral grey scale); the brand
   colours themselves are unchanged.

#### 2.2.0

 * Consistent section headers: a business group that opens its own block now always
   carries the same header tab, and a group nested inside another block (for example
   the tax representative’s postal address, BG-12 inside BG-11) is marked with its
   own, fainter tab. The dark / light distinction keeps its meaning, dark for a 
   block that carries data and light for an empty one.
 * Dates and numbers now follow the site instead of being hard-coded German. Invoice
   dates use the format from Settings -> General (new `spev_date_format` filter),
   numbers and amounts use the separators the active locale declares. On an English
   installation the invoice date read `13.11.2017` and the total `6.125,00 EUR` 
   before this release. Calendar dates are formatted in their own time zone on purpose,
   so the day printed is always the day that stands in the XML.
 * Fixed: the document type, payment means, unit of measure, VAT category and country
   were shown in German whatever the interface language. All five are translatable
   now, with the code appended in brackets, for example “Credit note (381)” or “
   kg (KGM)”; the section header keeps the plain name. Included in this: an unknown
   document type code was reported as “invoice”, so a credit note carrying a code
   the plugin did not know was labelled an invoice – a false statement about a legal
   document. An unknown code is now shown as the code itself, and a missing one 
   is left empty.
 * Documented the license of every bundled dependency: extracting the XML from a
   ZUGFeRD / Factur-X PDF uses `smalot/pdfparser` under the LGPL-3.0, everything
   else is MIT and the plugin’s own reading engine is GPL-2.0-or-later.
 * Tested against WordPress 7.1.

#### 2.1.0

 * Complete EN 16931 coverage: all 164 business terms and all 32 business groups
   are now extracted and labelled (previously 119 and 9). The seller tax representative(
   BG-11/BG-12) and payee (BG-10) blocks were not read at all before.
 * Business-term tooltips in German, English and French, taken verbatim from the
   official Factur-X specification.
 * French interface translation added; the German one extended to cover the new 
   strings.
 * Fixed: the allowances and charges table was labelled BG-20 throughout, which 
   was wrong for every charge row. The business-term code is now decided per row(
   BG-20 vs BG-21, and BG-27 vs BG-28 on line level).
 * Fixed: on Windows servers every upload failed with “No file received.” because
   the temporary upload path was passed through wp_unslash(), which strips its backslashes.
 * Values that were read but discarded are now displayed: allowance and charge base
   amounts, percentages and reason codes, the item attribute value (BT-161) and 
   the line identifier (BT-126).
 * The reading engine was extracted into a CMS-neutral library; the plugin’s own
   renderer shrank from about 1,100 lines to a thin bridge.
 * Bundled dependencies reduced from 126 MB to 17 MB by dropping an unused PDF-writing
   chain the plugin never referenced.
 * New: SPEV_Renderer::model() returns the structured invoice data instead of HTML.
 * New: the `spev_label_locale` filter chooses the business-term language independently
   of the site language.

#### 2.0.1

 * Business-term corrections, verified against the official EN 16931 specification(
   BT-115, BT-28/BT-33, BT-56/BT-41, BT-10, BT-47/BT-30 and the added scheme fields
   BT-47-1 / BT-30-1).
 * Updated and recompiled translations.
 * Renamed the plugin to “invoicePress – e-Invoice Viewer”.
 * Switched the text domain to `sp-einvoice-viewer` and hardened input handling (
   uploads and proxy headers) for the WordPress coding standards.

#### 2.0.0

 * New rectangular Quba-style layout with coloured section tabs and a dedicated 
   card group per line item.
 * Introduced the template engine (data model separated from HTML rendering).
 * Many more fields (BT-127 to BT-160, payment cards, delivery details and more).

## Meta

 *  Version **2.14.10**
 *  Last updated **22 hours ago**
 *  Active installations **Fewer than 10**
 *  WordPress version ** 5.8 or higher **
 *  Tested up to **7.1.2**
 *  PHP version ** 8.2 or higher **
 * Tags
 * [e-invoice](https://wordpress.org/plugins/tags/e-invoice/)[factur-x](https://wordpress.org/plugins/tags/factur-x/)
   [peppol](https://wordpress.org/plugins/tags/peppol/)[xrechnung](https://wordpress.org/plugins/tags/xrechnung/)
   [zugferd](https://wordpress.org/plugins/tags/zugferd/)
 *  [Advanced View](https://wordpress.org/plugins/einvoice-viewer-for-peppol-en16931/advanced/)

## Ratings

No reviews have been submitted yet.

[Your review](https://wordpress.org/support/plugin/einvoice-viewer-for-peppol-en16931/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/einvoice-viewer-for-peppol-en16931/reviews/)

## Contributors

 *   [ naranili ](https://profiles.wordpress.org/naranili/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/einvoice-viewer-for-peppol-en16931/)