itdatex E-Invoice Intake

Description

Since 1 January 2025, all businesses in Germany must be able to receive electronic invoices (e-invoices) under § 14 UStG. By 2027/2028 they must also issue them. Most existing tools require uploading sensitive supplier data — amounts, VAT IDs, bank details — to a third-party cloud service. itdatex E-Invoice Intake does the work locally inside your own WordPress installation.

What it does

  • Accepts XRechnung (UBL and UN/CEFACT/CII), ZUGFeRD (hybrid PDF/A-3 with embedded XML) and Factur-X via drag-and-drop upload
  • Detects the format automatically and parses the core fields: invoice number, dates, seller and buyer, VAT ID, totals (net/tax/gross), positions, buyer reference (Leitweg-ID)
  • Validates against the embedded EN-16931 XML schema and checks for required fields (BT-1, BT-2, BT-27, BT-112)
  • Stores each file with a random name in a protected upload directory and chains every file’s SHA-256 with the previous one (revision-evidence)
  • Provides a human-readable single-invoice view with header data, parties, amounts, validation issues and an audit trail
  • Logs every action (upload, status change, download) in a dedicated audit table

Privacy by design

The free version performs all processing locally on your own server. No data leaves your WordPress installation. There is no telemetry, no automatic update check against a third party, no analytics, no external font or asset loading.

A separate Pro version (sold via wp.itdatex.support, not part of this free plugin) adds optional cloud-assisted features — KoSIT deep validation, AI-based error explanations in plain German, IMAP auto-import, DATEV export — and is opt-in only.

GoBD-supporting, not GoBD-certified

The plugin supports GoBD-conformant processes through immutable storage, SHA-256 hash chaining and a complete audit trail. Note that software cannot be “GoBD-certified” — conformity is a property of your process, not of any single tool. Consult your tax advisor for the specifics of your setup.

Open source

The full source code is released under GPL-2.0-or-later. You can verify, audit and adapt the plugin yourself. Dependencies (josemmo/einvoicing for UBL, horstoeko/zugferd for CII/ZUGFeRD) are vendored with prefixed namespaces so they cannot conflict with other plugins in the same WordPress installation.

Screenshots

Installation

  1. Upload the plugin folder to /wp-content/plugins/itdatex-e-invoice-intake/, or install via the Plugins screen.
  2. Activate the plugin.
  3. Open the “Rechnungen” menu in the admin sidebar. You can upload your first XRechnung or ZUGFeRD file straight away.

The plugin creates three database tables (*_reing_invoices, *_reing_files, *_reing_audit_log) and a protected upload directory under wp-content/uploads/itdatex-e-invoice-intake-{random}/. On uninstall, invoice data and files are NOT deleted by default because of statutory retention requirements (8 to 10 years under German tax and commercial law).

To force a full cleanup on uninstall, add this line to your wp-config.php before deleting the plugin:

define( 'REING_UNINSTALL_DELETE_ALL', true );

FAQ

Does the plugin send anything to your server?

The free version makes no external HTTP calls. All parsing, validation and storage happens locally in your WordPress installation. You can verify this by inspecting the source — the only network code path is the optional Pro upgrade, which is not part of this plugin.

Which formats are supported?

XRechnung in both UBL and UN/CEFACT (CII) syntax, ZUGFeRD from version 2.0.1 onwards (PDF/A-3 with embedded XML), and Factur-X. Pure PDFs without an embedded XML payload are recognized as “legacy PDF” and stored as files, but their fields can only be extracted with the optional Pro AI extraction.

Is this GoBD-conformant?

The plugin provides the technical foundation — immutable storage, hash chain, audit log — that a GoBD-conformant process requires. Whether your concrete bookkeeping process is GoBD-conformant is a question for your tax advisor and depends on more than just the software you use. We deliberately do NOT advertise “GoBD certification” because no such certification mechanism exists in Germany.

Can I delete invoices?

You can mark invoices as paid or disputed. Physically deleting invoices in WordPress is intentionally not exposed in the UI to protect the integrity of the hash chain. If you have a legal reason to delete (e.g. erroneous double-upload), please use direct database access and document the deletion in your retention log.

What about the upload size limit?

The plugin uses the WordPress / PHP upload size limit (upload_max_filesize, post_max_size). XRechnung files are typically well below 1 MB; ZUGFeRD PDFs can reach a few MB. If you need higher limits, increase them in your php.ini or .htaccess.

Does this work behind nginx?

Yes. The protected upload directory uses both .htaccess (Apache/LiteSpeed) and a randomized directory name so that path guessing fails. File downloads always go through a capability-and-nonce-checked endpoint, never via a direct URL — so the front-end web server’s authorization model is irrelevant for the file path security.

Why no WP-Cron / IMAP / DATEV export?

These are paid features in the Pro version. The free version focuses on the core legal requirement — receiving and archiving incoming e-invoices — and keeps the dependency surface small to make security review easy.

Reviews

There are no reviews for this plugin.

Contributors & Developers

“itdatex E-Invoice Intake” is open source software. The following people have contributed to this plugin.

Contributors

Changelog

0.6.5

  • First public release on wp.org. XRechnung and ZUGFeRD parsing (UBL 2.1, UN/CEFACT CII, PDF/A-3 with embedded XML), KoSIT-based field validation, secure server-side storage with a tamper-evident hash chain, upload UI, invoice inbox, single-invoice detail view, secure download endpoint, and a full audit log. WP-CLI commands for headless ingest.

0.6.4

  • Replaced the single-line phpcs:ignore around the duplicate-check query in IngestService::ingest() with a phpcs:disable/phpcs:enable block so the sniff annotation also covers the interpolated SQL literal on the following line. No behaviour change.

0.6.3

  • Playground Plugin Check compliance pass: rename lexical include-scoped variables to the reing_ prefix in uninstall.php and the bootstrap file so the sniff no longer flags them; wrap the three admin view files (page-inbox.php, page-invoice.php, page-upload.php) with a phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound block explaining that the vars are template-locals, not globals. Annotated the read-only $_GET accesses in Admin\Pages\Invoice and Admin\Pages\Inbox with phpcs:ignore WordPress.Security.NonceVerification.Recommended (display-only, all writes go through nonce-protected admin-post endpoints). Annotated the duplicate-check $wpdb->get_var() in IngestService (table-name accessor, no user input). Gated the error_log() call in the same file behind WP_DEBUG. Annotated $_FILES['invoice_file'] in UploadHandler (cannot be sanitized like a string; validated by Parser + Validator downstream). Rewrote the uninstall DROP TABLE loop with a phpcs:ignore + rationale for uninstall-time schema removal.

0.6.2

  • wp.org Plugin Review round 2: distribution ZIP no longer ships the schema assets (*.xslt, *.sch, *.xmp) from the bundled horstoeko/zugferd library nor the Sphinx docs from jms/serializer — they are not used at runtime by the free plugin (validation runs against KoSIT in the optional Pro backend). Removed the unused, outdated transitive setasign/fpdf 1.9 dependency entirely. Annotated the two remaining static SQL statements in InvoiceRepository::lastChainHash() and countInvoices() with rationale.

0.6.1

  • Plugin Check compliance pass: escape interpolated exception messages (FormatDetector, Parser, Storage, InvoiceRepository), replace is_writable() with wp_is_writable(), unlink() with wp_delete_file(), rmdir() with WP_Filesystem::rmdir(), drop best-effort chmod() on stored invoices, inline SQL in listOpenInvoices() to satisfy the prepared-SQL sniff, annotate the dynamic listForExport query and the streaming readfile() in the download endpoint. No behaviour change.

0.6.0

  • New API: InvoiceRepository::listOpenInvoices() and summarizeOpenInvoices() for due-date reporting and aggregation by bucket (overdue / this week / this month / later / no date). Used by the optional Pro dashboard.

0.5.0

  • New API: InvoiceRepository::listForExport($from, $to, $status, $limit) with safe date range and status filter for CSV/DATEV exporters. Used by the optional Pro export module.

0.4.0

  • New service class IngestService::ingest($path, $name, $source, $actor) encapsulating the parse validate store audit pipeline. UploadHandler refactored to use it. Enables add-ons (e.g. Pro IMAP import) to reuse the exact same processing chain that the browser upload uses, including the existing hooks.

0.3.0

  • New filter reing_applyable_fields and action reing_apply_invoice_fields($id, $fields, $source) to allow add-ons to update invoice fields with type-safe sanitisation. Adds InvoiceRepository::applyableFields() and updateFields() with date / amount / currency normalisation. Sets extracted_by = 'ai_draft' and writes a structured audit entry.

0.2.0

  • Add-on integration hooks: reing_after_validate($tmpPath, $report, $invoiceData), reing_after_invoice_insert($id, $invoiceData, $report) and reing_invoice_view_after_validation($invoice, $reportData) allow optional Pro extensions to plug in deep validation, AI explanations and extra UI cards without modifying the free core. Includes a small backup autoloader for the prefixed Smalot/PdfParser library that the Strauss-generated PSR-0 mapping does not resolve correctly.

0.1.0

  • Initial release: parsing, validation, storage with hash chain, upload, inbox and single-invoice views, secure download endpoint, audit log.