Please note that this documentation is for the most recent version of this extension. It may not be relevant for older versions. Related documentation can be found in the documentation directory of the extension.
Create PDF/A and ZUGFeRD invoices in TYPO3 with Fluid-FPDF
The TYPO3 extension Fluid-FPDF (fluid_fpdf) lets you generate PDF documents directly from Fluid templates. This example demonstrates a PDF/A-3b document with embedded invoice XML as the foundation for a hybrid electronic invoice in ZUGFeRD / Factur-X format.
You will learn how to register FPDF fonts, attach an XML file and validate the resulting PDF for invoice data, file embedding and PDF/A conformance.
Embedding an XML file does not, by itself, make a PDF a valid ZUGFeRD invoice. Invoice data, the selected profile, PDF metadata and attachment structure must agree. Validate the actual generated file before using it in production.
PDF, PDF/A-3b, ZUGFeRD and XRechnung explained
| Term | Relevance to your TYPO3 integration |
|---|---|
| A visual document format for layout, text and graphics. An ordinary PDF invoice does not automatically contain structured invoice data. | |
| PDF/A-3b | A PDF format for long-term preservation that permits embedded files. Conformance level “b” addresses visual reproducibility. |
| ZUGFeRD / Factur-X | A hybrid invoice format combining a human-readable PDF/A-3 document with embedded invoice data in XML. |
| EN 16931 | The European standard defining the semantic data model and business rules for an electronic invoice. |
| CII / UBL | XML syntaxes for structured invoice data: UN/CEFACT Cross Industry Invoice and Universal Business Language. ZUGFeRD / Factur-X uses CII. |
| XRechnung | A German specification based on EN 16931 with additional requirements, available in UBL and CII. An XRechnung does not inherently require a PDF container. |
See FeRD's ZUGFeRD documentation for the hybrid format. The European Commission explains the EN 16931 data model and the UBL and CII XML syntaxes.
Requirements for PDF generation
For this Fluid template, you need:
- A configured TYPO3 installation with Fluid-FPDF and the
fpdfnamespace. - Font definitions that Fluid-FPDF can load and embed in the PDF.
- An existing invoice XML file using your chosen format and profile.
- An XML file path readable by the PHP process.
The example covers PDF output and XML embedding, rather than generating structured invoice data. Prepare that data in your application, for example in a PHP service within your TYPO3 extension. Use the same data source for the visible invoice PDF and its XML so that line items, taxes and totals agree.
Fluid template: PDF/A-3b with an XML attachment
<html xmlns="http://www.w3.org/1999/xhtml" lang="en"
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"
xmlns:fpdf="http://typo3.org/ns/CodingMs/FluidFpdf/ViewHelpers"
data-namespace-typo3-fluid="true">
<fpdf:pdfA>
<fpdf:addPage>
<fpdf:addFont family="Monospace" style="N" filename="ubuntumono_n.php" />
<fpdf:addFont family="Monospace" style="B" filename="ubuntumono_b.php" />
<fpdf:addFont family="Monospace" style="I" filename="ubuntumono_i.php" />
<fpdf:addFont family="Monospace" style="BI" filename="ubuntumono_bi.php" />
<fpdf:setFont family="Monospace" style="B" size="16" />
<fpdf:cell width="40" height="10" text="Hello World!" />
<fpdf:setXmlFile file="EXT:fluid_fpdf/Resources/Private/Php/zugferd/factur-x.xml" />
</fpdf:addPage>
</fpdf:pdfA>
</html>
What do the ViewHelpers do?
| ViewHelper | Purpose in this example |
|---|---|
fpdf:pdfA |
Uses the PDF/A output provided by Fluid-FPDF. |
fpdf:addPage |
Adds a PDF page. |
fpdf:addFont |
Registers the font variants to embed. |
fpdf:setFont |
Selects the font family, style and size. |
fpdf:cell |
Outputs the sample text “Hello World!”. |
fpdf:setXmlFile |
Provides the existing XML file for embedding in the PDF. |
The path EXT:fluid_fpdf/Resources/Private/Php/zugferd/factur-x.xml refers to a sample file. For real invoices, replace it with the XML belonging to the specific invoice. Replace the visible sample text with your complete invoice layout as well.
The variants registered with fpdf:addFont represent normal (N), bold (B), italic (I) and bold italic (BI). Embed every font variant used in your PDF, including headers, footers and supplementary text.
Prepare ZUGFeRD and Factur-X correctly
Choose the format version and profile before generating the PDF. Profile names such as MINIMUM, BASIC WL, BASIC, EN 16931 and EXTENDED represent different data scopes and validation rules. Passing validation for a reduced profile does not automatically confirm full EN 16931 compliance.
Pay particular attention to:
- BT-24 profile identifier: The specification identifier in the XML must match the profile you actually generate.
- XMP metadata: The PDF/A declaration and ZUGFeRD / Factur-X metadata must match the document.
- XML embedding: The filename, MIME type,
AFRelationshipand association through/AFmust meet the requirements of the selected version and profile. - Matching invoice data: Invoice number, date, currency, line items, tax amounts and totals must agree between PDF and XML.
Renaming the XML file or replacing BT-24 does not convert an invoice into another format. XRechnung and Peppol BIS have their own additional requirements; an EN 16931 validation result does not automatically confirm these.
Validate PDF and electronic invoices: useful tools
For the ZUGFeRD PDF in this example, BillingEngine is a suitable first check because, according to its provider, it validates both invoice XML and selected PDF container properties. Add veraPDF to check PDF/A conformance. A single successful result does not necessarily cover every validation layer.
1. BillingEngine: validate invoice XML and the PDF container
According to its provider, the BillingEngine e-invoice validator accepts UBL and CII XML as well as ZUGFeRD and Factur-X PDFs. It checks XML schemas and business rules using Schematron. Additional XRechnung rules apply when the invoice identifies itself as XRechnung through BT-24.
For PDFs, its checks also include XMP metadata, the PDF/A-3 declaration, Output Intent, XML attachment names, MIME type, AFRelationship and /AF. It compares the profile declared in PDF metadata with the XML identifier. The results page identifies the detected profile and the rules applied.
Useful for: An initial technical check of a ZUGFeRD / Factur-X file generated with Fluid-FPDF, particularly XML embedding and profile consistency.
Limitations reported by the provider: No full PDF/A validation, no ZUGFeRD 1.0 support, no Peppol-specific rules, a 2 MB file limit and no downloadable validation report. Validation requires no registration and runs on a server in Frankfurt. Temporary files are deleted after the request, and contents and filenames are not logged.
These details are based on information supplied by the provider in September 2026, rather than independent certification. Check the validation scope stated on the results page.
2. veraPDF: validate PDF/A conformance
veraPDF is an open-source validator for PDF/A and PDF/UA. For this example, use PDF/A-3b validation. It checks PDF/A requirements, including embedded fonts, colour spaces and document structure, complementing invoice validation.
Useful for: Technical verification of the generated PDF/A document and local file-format validation in development or CI workflows.
Limitation: Passing PDF/A validation does not establish that the embedded invoice meets EN 16931, ZUGFeRD profile or XRechnung business rules.
3. E-Rechnungs-Checker: validate and visualise invoice XML
E-Rechnungs-Checker provides electronic invoice validation and a readable presentation of invoice data. It accepts PDF and XML files and supports formats including ZUGFeRD, Factur-X, XRechnung, CII and UBL. Its presentation of XML data helps you manually compare structured content with the visible invoice PDF.
Useful for: An additional check and inspection of structured invoice data without reading raw XML.
Limitations: Visualisation does not automatically prove that PDF and XML contain identical information. Perform full PDF/A validation separately. According to the website, uploaded files and results are deleted after 30 minutes; the upload limit is 10 MB (as of September 2026).
4. service-bw: an additional check for XRechnung XML
The service-bw e-invoice validator provides an additional option for checking XRechnung XML. Use it when specifically generating XRechnung, and check the versions and validation rules indicated in the application.
Useful for: An additional XML check within an XRechnung workflow.
Limitation: Do not interpret an XML validation result as proof of PDF/A conformance or correct XML embedding in a ZUGFeRD PDF.
Recommended testing workflow for TYPO3 and FPDF
- Generate invoice XML: Use realistic data structures with anonymised test data and an explicitly selected profile.
- Validate the XML: Check the XML schema (XSD), required fields and Schematron business rules. Fix errors before embedding the file.
- Generate the PDF from Fluid: Render the invoice layout with embedded fonts and the corresponding XML file.
- Validate the final file: Check XML, profile metadata and the container together, then validate PDF/A-3b using veraPDF.
- Compare PDF and XML: Pay particular attention to rounding, discounts, multiple tax rates, tax exemptions and credit notes where supported by your application.
- Detect regressions: Repeat validation after changes to TYPO3, Fluid-FPDF, fonts or templates. Record dates, versions and validation results.
Prefer anonymised test invoices when using online validators. For automated tests in GitLab CI or other CI/CD pipelines, use suitable locally executable validators and keep track of the validation rule versions used.
Common errors and solutions
“All fonts must be embedded in PDF/A”
If you encounter this error:
if($font['type']=='Core') $this->Error('All fonts must be embedded in PDF/A');
a non-embedded PDF standard font is being used. Register the required fonts with fpdf:addFont, then select the registered family with fpdf:setFont. Also check bold and italic text, headers and footers.
The XML file cannot be found
Check the path passed to fpdf:setXmlFile, file permissions and whether the XML was generated before rendering. When invoices are processed concurrently, each invoice needs its own file to prevent another invoice's data from being embedded.
The PDF opens but fails validation
A PDF viewer does not perform complete PDF/A or e-invoice validation. First identify the relevant layer: PDF structure, XML schema, business rules or profile metadata. Correct the underlying issue, regenerate the file and validate it again.
Frequently asked questions about PDF/A and TYPO3 e-invoices
Does FPDF automatically create a ZUGFeRD invoice?
No. Ordinary FPDF output is not sufficient. This Fluid-FPDF example uses PDF/A output and an existing XML file. The invoice layout, structured data and required metadata must also agree.
Does fpdf:setXmlFile generate the invoice XML?
In this workflow, you provide an existing XML file. Preparing invoice data and generating XML belong in the preceding application logic.
Is valid PDF/A-3b sufficient for a valid e-invoice?
No. PDF/A concerns the document format. XML schemas, business rules and profile requirements require additional validation. Checking agreement between visible and structured invoice data is also part of quality assurance.
Which validator is most useful for this example?
For a ZUGFeRD / Factur-X PDF, start with BillingEngine's combined XML and container checks and add veraPDF for PDF/A-3b. E-Rechnungs-Checker provides a readable view of XML data; service-bw offers an additional check for XRechnung XML.
