horstoeko/zugferd
A PHP library for creating, reading, and validating ZUGFeRD and Factur-X electronic invoices, including XML data and PDF/A-3 hybrid invoice documents for compliant e-invoicing workflows.
Architecture fit. horstoeko/zugferd is a pure-PHP domain library distributed via Composer that generates and parses ZUGFeRD, Factur-X, and XRechnung documents. It is not a framework-coupled package — it sits naturally at the boundary between order/accounting data and outbound compliant invoice artifacts. In a Laravel codebase this maps cleanly to a dedicated "InvoicingCompliance" or "Billing" bounded context, with the library consumed behind a thin service wrapper so vendor types never leak into Eloquent models or controllers. It does not own persistence, queuing, or transport, so it composes well with existing Laravel conventions (jobs, events, storage disks).
Integration feasibility. Composer install with PSR-4 autoloading and likely Laravel package auto-discovery. The public surface is a builder-style API (invoice header, seller/buyer parties, line items, tax breakdown, payment terms) plus a reader for inbound documents. The major integration variable is output format: XRechnung is standalone XML (CII or UBL) with no PDF dependency, whereas ZUGFeRD/Factur-X require PDF/A-3 embedding, which pulls in a PDF renderer (mPDF/TCPDF/Dompdf) and possibly Ghostscript and an ICC profile. That dependency chain is the main feasibility question, not the library itself.
Technical risk.
Key questions.
Stack fit. Target PHP 8.1+ and Laravel 10–12. Add as a Composer dependency, register the service provider (auto-discovery if available), and wrap the library in a ComplianceInvoiceService that accepts domain DTOs and returns a persisted artifact record (XML path, PDF path, profile, schema version, hash). Keep the library out of controllers entirely.
Migration path. Start narrow and low-risk: generate XRechnung XML only (no PDF) for the German B2G/public-sector segment. This validates the data model, tax semantics, and receiver acceptance with the smallest dependency footprint. Only after that is stable, add ZUGFeRD/Factur-X PDF/A-3 embedding for B2B scenarios. Persist every generated document as an immutable artifact with a hash and the library/schema version used, so audit and re-issuance are possible.
Compatibility. Verify: PHP minor version support, PDF renderer compatibility (mPDF and TCPDF have different PHP 8.x support stories), whether the library emits both CII and UBL, and whether Laravel auto-discovery works or manual registration is needed. Confirm behavior when optional fields (discounts, surcharges, multiple tax rates, reverse charge) are present — these are the common schema-validation breakers.
Sequencing.
Maintenance. Pin to a tested minor version; track upstream releases and KoSIT/ZUGFeRD publication calendars. Budget a quarterly review of schema versions and a defined upgrade playbook. Store the library version and schema version on every generated artifact so historical documents remain reproducible.
Support. Community support via GitHub issues; no commercial SLA. Mitigate with an internal test corpus, a documented fallback export path (manual invoice generation), and a fork strategy that keeps the wrapper interface stable so swapping implementations is a contained change.
Scaling. XML generation is CPU-light and trivially queueable. PDF/A-3 rendering is the heavier operation — offload to a dedicated queue with concurrency limits to avoid starving request workers. Storage grows meaningfully: German and French retention rules imply 8–10 year retention of PDFs, so plan object-storage lifecycle policies and per-profile document sizes early.
Failure modes. Schema-validation failures on edge cases (zero-rated lines, multiple tax categories, rounding and discount rules); PDF/A-3 font/ICC/metadata embedding failures; receiver-side rejections that local validation did not catch; silent schema drift when a new KoSIT release lands; and builder misuse producing structurally valid but semantically wrong invoices (wrong tax category code, wrong profile). The last is the most dangerous because it passes validation but is rejected downstream.
Ramp-up. Any PHP developer can be productive with the builder API in days; the real learning curve is e-invoicing domain knowledge — profiles, tax category codes, Peppol vs. XRechnung semantics, and PDF/A-3 constraints. Pair engineering with a compliance/finance owner, and use the package's examples plus the CI regression corpus as the living documentation.
How can I help you explore Laravel packages today?