Download the PHP package dealerweb/einvoice without Composer

On this page you can find all versions of the php package dealerweb/einvoice. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package einvoice

dealerweb/einvoice

E-invoicing in pure PHP - validator, viewer and generator for XRechnung, ZUGFeRD / Factur-X and Peppol BIS, the e-invoices of EN 16931 (in Germany: E-Rechnung).

Reads electronic invoices according to EN 16931 - XRechnung, ZUGFeRD 2.x / Factur-X, Peppol BIS - as XML in both syntaxes (UBL Invoice, UBL CreditNote, UN/CEFACT CII) or as ZUGFeRD / Factur-X PDF, and visualizes them as a readable PDF or HTML page in German, English or French. It validates them with the verdict of the official tools: the XML schemas and the Schematron rules of EN 16931, XRechnung and ZUGFeRD / Factur-X, applied like the KoSIT validator does, and the rules of Peppol BIS Billing 3.0 in an own implementation with the verdicts of the official ones. And it writes them: CII documents of every ZUGFeRD / Factur-X profile, of XRechnung and of Peppol BIS Billing 3.0, UBL invoices and credit notes of EN 16931, XRechnung and Peppol BIS Billing 3.0, checked by the validator - as XML, CII also as ZUGFeRD / Factur-X PDF (PDF/A-3 with the XML embedded). One class stands for the invoice, read or built: Invoice, with every field of EN 16931, of the XRechnung extension and of ZUGFeRD / Factur-X EXTENDED under a readable name - $invoice->buyer->address->city. Pure PHP (8.2+), no Java, no XSLT processor.

Only the XML is the original invoice - anything rendered from it is a reading aid.

Installation

PHP 8.2 or later with ext-dom, ext-libxml, ext-mbstring, ext-xmlreader and ext-zlib. Composer installs dompdf for the PDF output; its CSS parser needs ext-iconv.

Usage

One class stands for the invoice: Dealerweb\EInvoice\Invoice. It is read from a file or built in PHP, written as XML or PDF, checked and shown - every field with a readable name, $invoice->buyer->address->city.

The sections below go through the four tasks: reading an invoice, creating one, checking one and showing one. Creating an invoice starts with a table of every format and its call - XRechnung, ZUGFeRD / Factur-X from your own PDF or without one, EN 16931, Peppol BIS. Runnable scripts for every format and every task, with example files to read, check and convert, are in examples/.

Reading an invoice

Creating an invoice

The invoice is built once, with the names of the model (below), and written in the format its recipient needs - each format has a script of its own in examples/create/:

Format Call
XRechnung - the format of German public buyers (their Leitweg-ID in buyerReference) $invoice->toXml(Profile::XRechnung)
XRechnung in UBL $invoice->toXml(Profile::XRechnung, Syntax::UblInvoice)
ZUGFeRD / Factur-X PDF from your own PDF - the invoice as your system prints it, with the XML embedded $invoice->toPdf(Profile::En16931, pdf: $yourPdf)
ZUGFeRD / Factur-X PDF without a PDF of your own - the package renders the invoice (de, en or fr) $invoice->toPdf(Profile::En16931, 'de')
ZUGFeRD / Factur-X as XML alone $invoice->toXml(Profile::En16931)
ZUGFeRD / Factur-X EXTENDED - more fields (profile X in MODEL.md) Profile::Extended in the three calls above
ZUGFeRD / Factur-X BASIC - fewer fields (profile B in MODEL.md) Profile::Basic in the three calls above
XRechnung in a PDF (the ZUGFeRD / Factur-X profile XRECHNUNG) $invoice->toPdf(Profile::XRechnung, pdf: $yourPdf)
EN 16931 without a national specification, in UBL (in CII it is ZUGFeRD / Factur-X EN 16931) $invoice->toXml(Profile::Core)
Peppol BIS Billing 3.0 in UBL - with electronic addresses of Peppol (see the example) $invoice->toXml(Profile::Peppol)
Peppol BIS Billing 3.0 in CII $invoice->toXml(Profile::Peppol, Syntax::Cii)

Each call writes only what its profile holds: nothing is left out silently, a value the profile has no place for stops it with the path of the value and the profiles that have it (seller.contact.name (BT-41) is not a part of the profile BASIC. It is in EN16931, EXTENDED, XRECHNUNG and PEPPOL.). And each call checks the invoice by the official rules of its profile and throws InvalidInvoice instead of returning an invalid document (see Errors). A credit note is the same invoice with a credit note type code (InvoiceTypeCode::CREDIT_NOTE, 381), written in UBL as UBL CreditNote. MINIMUM and BASIC WL (Profile::Minimum, Profile::BasicWl) hold no invoice lines: booking aids, which in Germany count as no e-invoice since 2025 (FeRD).

Every CII example of FeRD and KoSIT read and written again is the same document; every example, UBL or CII, written as CII has the same content; the valid ones stay valid, except seven EXTENDED examples whose totals rely on EXTENDED content (sub invoice lines, logistics charges). Every UBL example of KoSIT and Mustang read and written again as UBL is the same model, and a valid one stays valid. Every CII example of EN 16931 content written as UBL, and every UBL example written as CII, gives the semantic model of KoSIT of the original, and a valid one stays valid in the other syntax - except what the other syntax has no place for, which stops the generator with a message: in UBL a department next to the person of a contact, a second buyer identifier, the VAT exemption reason of a line; in CII the sub lines of the XRechnung extension, the type of a third party payment, a second preceding invoice in XRechnung. A small invoice takes about 1 ms, 20 ms with the validator.

The ZUGFeRD / Factur-X PDF (toPdf()) is the PDF of the invoice with its XML embedded, a PDF/A-3. The PDF is yours - the invoice as your system prints it, given with pdf: -, or, where you have none, the invoice rendered by the package in the language given (the layout of PdfRenderer):

Checked with veraPDF (PDF/A) and Mustang (PDF/A and the embedded invoice): the invoice of every profile and the 61 PDFs of the FeRD examples with their XML written into them pass both.

By the ids of the fields - the Factur-X field list, in UBL the business terms of EN 16931 and the XRechnung extension - an invoice is written with Generation\Generator, which also writes without the validator:

Checking an invoice

Of a ZUGFeRD / Factur-X PDF the XML it carries is checked (validatePdf(), or validate() and validateFile(), which see that it is a PDF), not the PDF itself - PDF/A-3 and the embedding are the job of a PDF validator such as veraPDF, and the report says so in its notes. A PDF that cannot be read or carries no invoice is reported (INVALID_PDF, NO_INVOICE).

The rules come from the specification identifier (BT-24):

Document Profile Schema Rules
XRechnung 3.0, its extension and CVD (UBL or CII) XRechnung UBL 2.1 / CII D16B EN 16931 (CEN) and XRechnung (KoSIT), with the message levels of KoSIT's scenario
ZUGFeRD 2.x / Factur-X MINIMUM, BASIC WL, BASIC, EXTENDED (CII) Minimum ... Extended FeRD schema of the profile FeRD rules of the profile
EN 16931 (urn:cen.eu:en16931:2017) in CII - ZUGFeRD / Factur-X EN 16931 En16931 FeRD schema EN16931 FeRD rules EN16931
EN 16931 in UBL Core UBL 2.1 EN 16931 (CEN)
Peppol BIS Billing 3.0 (UBL or CII) Peppol UBL 2.1 / CII D16B EN 16931 (CEN) and Peppol BIS Billing 3.0 - the package's own implementation of the rules of OpenPeppol (see below)
another specification based on EN 16931 (Peppol BIS Self-Billing, another CIUS, XRechnung 2.x) Core UBL 2.1 / CII D16B EN 16931 (CEN) - the report notes that the own rules of the specification are not included
anything else - - none: rejected (NO_SCENARIO), as by the KoSIT validator

A given profile decides instead - Profile::Core checks a CII document like the KoSIT validator's scenario "EN16931 (CII)", Profile::XRechnung and Profile::Peppol a document with another identifier with the rules of the profile and a note. The levels follow KoSIT's report: flag or role fatal/error is an error, warning/warn a warning, information/info an information, anything else an error. When the schema fails, the rules are not applied; a rule set that cannot be applied to the document gives a PROCESSING_ERROR - both as in the KoSIT validator.

The verdicts are those of the official tools: the rules are the official Schematron stylesheets (EN 16931 1.3.16 of CEN and XRechnung 3.0.2 of the KoSIT validator configuration of 2026-08-31, ZUGFeRD 2.5.2 / Factur-X 1.09.2 of FeRD), compiled from Saxon's execution plan and executed with Saxon's rules of evaluation, down to its errors and its comparisons of -0 and NaN; libxml checks the schemas, with the verdict of Xerces where libxml is stricter (decimals of more than 24 digits, dates and times with whitespace around them). This is proven for 2,802 documents (the official samples, the unit tests of CEN and variants made to fire every rule): every finding equals Saxon's, every schema verdict Xerces', every report the KoSIT validator's. Two things depend on the server, as they do with the official tools: a date without timezone is compared in the implicit timezone - Saxon takes the one of the JVM, the validator the one of PHP (date.timezone) -, and where the regular expression library gives up on a text (hundreds of thousands of characters), the rule set is reported as not applied (PROCESSING_ERROR) instead of deciding the rule.

The rules of Peppol BIS Billing 3.0 are the package's own implementation of the specification, not the validation artefacts of OpenPeppol - with the rule identifiers, flags and verdicts of its release 3.0.20, in UBL and in CII: in all unit tests and examples of the release (587 in UBL, 320 in CII) and in every document of the tests they find what the official rules find, at the same nodes. The rules of EN 16931 they are applied with are the package's (1.3.16; the release of Peppol brings 1.3.15).

A validation takes from a few to a few hundred milliseconds for usual invoices; large ones take about 3 ms per line (1,000 lines of XRechnung about 3 s, 1,200 lines of ZUGFeRD EXTENDED about 6 s). The memory needed is about 40 to 60 times the size of the XML.

Showing an invoice

The viewer of the package: every invoice it reads - XRechnung, ZUGFeRD / Factur-X, Peppol BIS, in UBL or CII - becomes a readable page in the layout of a German business invoice, in German, English or French.

A read invoice is shown as delivered, with everything its document holds - also what the model has no place for; an invoice built or changed is shown as the model holds it. Only the XML is the invoice, a rendering is a reading aid: to send an invoice as PDF, write it with toPdf() - a ZUGFeRD / Factur-X PDF carries the XML.

Names of fields and codes

Errors

Reading - Invoice::fromFile(), fromXml(), fromPdf() and xmlFromPdf() - throws a subclass of Dealerweb\EInvoice\Exception\EInvoiceException:

Reading does not throw for content the model has no place for, it names it in unread().

Writing - toXml(), toPdf(), Generator::xml() and Generator::pdf() - throws an InvalidArgumentException for a value that has no place in the profile or is of the wrong kind, and the message names it by its path in the model (lines.0.quantity: "1,5" is no decimal number - write it like 1234.56, with a point and without thousands separators., seller.additionalContacts: at most 1 in the profile EN16931, 2 given.) or by its field id (BT-2: "26.09.2026" is no date (YYYY-MM-DD).); InvalidInvoice (same base class as above) when the validator rejects the invoice - report() holds the report; InvalidPdf for your own PDF when it is no PDF, is damaged beyond repair, encrypted or signed. Invoice::fromArray() names an unknown property by its path (Unknown property buyer.adress.).

Attachment::content(), saveTo() and fromFile() throw InvalidAttachment (same base class) when an attached file is no valid base64, there is none to save, or a file cannot be read or is of a type EN 16931 does not allow.

The renderers throw an InvalidArgumentException for a language other than de, en or fr.

Validator::validate() does not throw for a bad document, it reports it: NOT_WELL_FORMED, DOCTYPE (refused, as by reading), NO_INVOICE, INVALID_PDF. Validator::validateFile() throws InvalidXml when the file cannot be read. Files are read from a path or a file:// URL; stream wrappers (http://, data:, php://filter, ...) are refused, reading never reaches the network. A schema of the package that cannot be read is a RuntimeException - an installation problem, not an error of the invoice.

Not included

How it works

Versioning

The package follows Semantic Versioning. Classes and methods marked @internal are not part of the public API. Changes are listed in CHANGELOG.md.

Security

Please report vulnerabilities privately, see SECURITY.md.

License

MIT (see LICENSE) - free to use, provided as is, without any warranty or liability.

This software is an application of EN 16931-1:2017 and CEN/TS 16931-2:2017; names and identifiers of the business terms are reproduced with the permission of CEN and DIN, the owners of the copyright. Third-party material keeps its own license: what is compiled from the XRechnung visualization of KoSIT (resources/compiled, Apache License 2.0), the XML schemas of the FeRD release package and what is compiled from it (resources/ferd, resources/compiled: FeRD rights of use, schemas and rules Apache License 2.0), the validator configuration of KoSIT (resources/kosit-validator: its scenarios and the rules of XRechnung Apache License 2.0; the rules of EN 16931 of CEN, compiled into resources/compiled/validation/en16931-*.php, European Union Public Licence 1.2; the schemas of OASIS UBL 2.1 and UN/CEFACT CII D16B, unchanged with their notices), the names of Unicode CLDR in the code lists (Unicode License V3) and the sRGB colour profile (resources/icc, CC0 1.0) - see NOTICE. The PDF output uses dompdf (LGPL-2.1) and the libraries it needs (LGPL and MIT); Composer installs them as separate packages, they are not part of this package.


All versions of einvoice with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
ext-dom Version *
ext-libxml Version *
ext-mbstring Version *
ext-xmlreader Version *
ext-zlib Version *
dompdf/dompdf Version ^3.1
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package dealerweb/einvoice contains the following files

Loading the files please wait ...