beliq / woocommerce-beliq
Generate EN 16931 e-invoices from WooCommerce orders through the beliq API.
Package info
github.com/beliq-eu/woocommerce-beliq
Type:wordpress-plugin
pkg:composer/beliq/woocommerce-beliq
Requires
- php: >=8.2
- ext-json: *
- composer/installers: ^2.0
Requires (Dev)
- ext-curl: *
- dealerdirect/phpcodesniffer-composer-installer: ^1.0
- php-stubs/woocommerce-stubs: ^11.2
- phpstan/phpstan: ^2.3
- phpunit/phpunit: ^11.0
- squizlabs/php_codesniffer: ^3.11
- szepeviktor/phpstan-wordpress: ^2.0
- wp-coding-standards/wpcs: ^3.1
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-11-05 18:13:18 UTC
README
A WooCommerce plugin that turns store orders into EN 16931 e-invoices (XRechnung, ZUGFeRD, Factur-X, Peppol BIS) through the beliq API. It generates and validates the documents; it does not send, file, or submit them anywhere.
Status
Version 0.1.0 is on Packagist as beliq/woocommerce-beliq, built from the tag v0.1.0. It has no WordPress.org listing yet. What is built:
- The plugin boots as a WordPress plugin, declares HPOS compatibility, exposes a settings screen under WooCommerce > Settings > Integration, generates a document when an order reaches the configured status, and stores it for a capability-checked download from the order screen.
- The live smoke in
smoke/drives a real WordPress + WooCommerce store through the whole order-to-document path. On 2026-11-05 it passed 38 of 38 checks against the production beliq API on WordPress 7.1.4 and WooCommerce 11.2.2. - The official wp.org Plugin Check runs on the distribution in CI (
plugin-check/run.sh --ignore-calendar, which fails on any error) and weekly with the calendar-driven check included (.github/workflows/wporg-currency.yml).
Next is the WordPress.org submission.
Install
With Composer, from the directory that holds your WordPress project's composer.json:
composer require beliq/woocommerce-beliq
wp plugin activate woocommerce-beliq
The package requires composer/installers, which puts the plugin in wp-content/plugins/woocommerce-beliq/, or wherever the project's installer-paths sends type:wordpress-plugin (Bedrock uses web/app/plugins/). Composer asks once whether to allow the composer/installers plugin; allow it, or run composer config allow-plugins.composer/installers true first. WooCommerce must be active. The settings are under WooCommerce > Settings > Integration.
How it works
- Settings live in a
WC_Integration(src/Integration/InvoiceIntegration.php);WooPluginConfigProviderreads them into the typedPluginConfig, coercing WooCommerce'syes/nocheckbox values. OrderStatusTriggerfires onwoocommerce_order_status_changed; when the order reaches the configured status it runsInvoiceGenerator, and it never lets a failure break the transition (errors go to the WooCommerce log, sourcebeliq).WcOrderData/WcLineDatawrap aWC_Orderbehind theOrderData/LineDataseam (line net fromget_total(), rate fromWC_Tax, buyer VAT and reference from the configured meta keys), soWooOrderAdaptermaps against plain data.InvoiceGeneratormaps the order, applies the business-only gate, calls beliq, and hands the bytes toDocumentStore, which writes them to a protected uploads subdirectory and records the location in order meta.OrderMetaboxshows the status and a download button;OrderActionsserves the capability-checked download and a manual (re)generate, and adds the native WooCommerce order-action entry.
Development
composer test # PHPUnit (offline: mapper, client, config, provider, adapter)
composer phpcs # WordPress security + i18n sniffs over the runtime code, src/Core included
composer phpstan # PHPStan at level 8 over the plugin file and src/, against the WordPress and WooCommerce stubs
composer scrub:check # no em-dash
composer archive:check # git archive HEAD (what Packagist ships) = the wp.org distribution + composer.json, README.md, CHANGELOG.md
The offline suite needs no WordPress: the runtime classes reference WooCommerce symbols only inside method bodies, so the tests that exercise the pure logic (PluginConfig, WooPluginConfigProvider, the adapter, the mapper, the client) never load them. A live smoke against the beliq API is gated on BELIQ_API_KEY.