PHP PDF library for EU VAT invoices — Art. 226 checker

For PHP developers invoicing EU business customers. Below is a German B2B draft already checked with the same 15 checks the package runs before it writes a PDF. Change any field and the verdict changes as you type.

What the 15 checks found

    Totals (Art. 226(8)–(10))

    Full version — $60 once · get the composer package
    You just checked one invoice by hand. The package runs these checks inside your PHP app on every invoice it issues and writes the PDF itself: zero dependencies, 6 languages, named exceptions. One payment, no subscription.

    Invoice preview

    Your invoice

    Supplier

    Customer

    Lines

    DescriptionQtyUnit price (excl. VAT)VAT %

    Amounts use a dot for decimals (12.5). "12,5" is refused, exactly as the package refuses it.

    Why a free PDF class is not enough

    FPDF, TCPDF or dompdf draw whatever you pass them. None of them knows that a German invoice must state the date of supply even when it equals the issue date (§14(4) no. 6 UStG), that reverse charge must read Autoliquidation on a French invoice, or that a Polish supplier invoicing in EUR must also show the VAT in PLN (Art. 230). Under Art. 178(a) your customer may deduct input VAT only when holding an invoice drawn up per Articles 220–236, so a missing field holds up their deduction until you reissue.

    composer require readystack/eu-invoice-pdf

    German domestic B2B: from 2027-01-01, suppliers with prior-year turnover above €800,000 must issue structured e-invoices (XRechnung / ZUGFeRD); a PDF then no longer counts for those sales. This checker and the package check presence and shape of the fields; they do not choose your VAT rate.

    Get the complete version $60

    This page is the working piece. The full pack has everything below.

    Pure-PHP invoice PDFs that refuse to render when an Art. 226 field is missing: 15 checks, reverse-charge wording in 6 languages, €1,900 VAT deduction caught in the worked example

    ReadyStack shelf measurement 2026-09-27 (Gumroad, paid PHP packages): the top price on this shelf is $60.

    Buy the full version — $60
    ENDEJAESPT

    Find a tool

    · ReadyStack

    Worked example

    Real numbers from this tool, line by line.

    PHP PDF Library for EU VAT Invoices (Art. 226, 2026)

    €1,900 VAT deduction at risk on this invoice, for PHP developers billing German B2B clients. This is what the package printed for a €10,000.00 net invoice at 19% sent without the supplier VAT ID and the date of supply:

    PDF refused - 2 errors, €1,900 VAT deduction at risk: Art. 226(3) Supplier VAT ID is missing (a German supplier may print its Steuernummer instead, §14(4) no. 2 UStG). Art. 226(7) Date of supply is missing - German invoices must always state it, even when it equals the issue date (§14(4) no. 6 UStG).

    Add the VAT ID and the supply date and the same call writes a one-page PDF: Nettobetrag 19 % 10.000,00 €, Umsatzsteuer 19 % 1.900,00 €, Gesamtbetrag 11.900,00 €. The invoice behind it: €8,000.00 for a shop integration plus 16 hours of consulting at €125.00.

    Article 226 of VAT Directive 2006/112/EC lists what every full VAT invoice must carry: date of issue, a sequential number, the supplier's VAT ID, the customer's VAT ID when the customer accounts for the VAT, both full names and addresses, the nature and quantity of what was supplied, the date of supply when it differs from the issue date, the taxable amount per rate with unit prices and discounts, the VAT rate, the VAT amount, the legal reference for an exemption and the words "Reverse charge" when the customer pays the VAT. Article 178(a) ties the customer's input-VAT deduction to holding such an invoice. Miss a field and your customer's deduction waits until you reissue.

    readystack/eu-invoice-pdf is a composer package with a PDF writer of its own and no dependencies. Before a single byte of PDF is written, 15 checks run. If one fails, render() throws MissingMandatoryFieldException carrying every violation with its article, and no file is produced.

    Why the supply date? Art. 226(7) only asks for it when it differs from the issue date, but German law (§14(4) no. 6 UStG) requires it on every invoice, even when it is the same day. That is one of two German rules built in; the other lets a German supplier print its Steuernummer instead of a VAT ID.

    Cross-border services are where the wording matters. The mention for reverse charge is not free text: it is Reverse charge in English, Steuerschuldnerschaft des Leistungsempfängers in German, Autoliquidation in French, Inversión del sujeto pasivo in Spanish, Inversione contabile in Italian, Btw verlegd in Dutch. The package prints it in the invoice language, together with labels, dates and amounts in that language's format. A French invoice for €1,500.00 of software maintenance comes out with Total HT 1 500,00 € and Autoliquidation under the totals.

    Currency is the third trap. Article 230 lets you invoice in any currency, but the VAT must also be shown in the supplier's national currency. A Polish supplier invoicing €100.00 at 23% must give an exchange rate; with 4.2567 the PDF adds VAT in national currency 97.90 PLN. The table covers the 27 member states plus Northern Ireland, and knows that Bulgaria uses the euro from 1 January 2026.

    What it will not do: it checks presence and shape, not which VAT rate applies to your sale. It never calls VIES or any other network service; VAT IDs are checked against the format of each of the 28 VIES prefixes. And for German domestic B2B, from 1 January 2027 suppliers with prior-year turnover above €800,000 must send structured e-invoices, so a PDF no longer counts for those sales.

    Try it on your own invoice first: the free checker on the product page runs the same 15 checks in your browser. The package is one payment, not a subscription.

    15 seconds — what it actually does

    Questions people ask

    What does this PHP PDF library do?

    It writes invoice PDFs in pure PHP with no dependencies, but first runs 15 checks mapped to Art. 226 of VAT Directive 2006/112/EC, Art. 138 and Art. 230. If a mandatory field such as the supplier VAT ID or the date of supply is missing, render() throws MissingMandatoryFieldException with every violation listed, so a non-compliant invoice never leaves your app.

    Who is it for?

    PHP developers who bill EU business customers from their own app, shop or SaaS: a German agency invoicing a French client under reverse charge, a Polish company invoicing in euros, a Dutch wholesaler shipping goods to Belgium. It prints the legal mentions in English, German, French, Spanish, Italian and Dutch and formats dates and amounts per language.

    Why not use a free PDF class like FPDF or dompdf?

    A free PDF class draws whatever you give it; it does not know that a German invoice must state the date of supply even when it equals the issue date, that reverse charge must read Autoliquidation in French, or that a Polish supplier invoicing in EUR must also show the VAT in PLN. Those rules are what this package adds on top of its own PDF writer.

    What can I do for free?

    The web checker on this page runs the same 15 checks on one invoice you type in: countries, VAT IDs, dates, treatment, lines. You see every missing field with its article, the exact legal mention for your language, and the net, VAT and gross totals. No account, no upload. The paid package runs those checks and writes the PDF inside your PHP app, on every invoice.

    How does the price compare?

    The package costs $60 once, not a subscription. On our measured Gumroad shelf for paid PHP packages, $60 is the top of the range. Writing and testing the Art. 226 checks, six languages of legal mentions and a PDF writer yourself takes days of developer time, and one wrong invoice can hold up a customer's input-VAT deduction until you reissue it.

    Ask about this tool

    One question, answered by the person who built it. Your email only if you want the answer sent.