Real numbers from this tool, line by line.

€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.