To Reproduce
The embedInPdf function produces PDFs that fail ZUGFeRD/Factur-X validation. Even with a minimal blank PDF created with pdf-lib, the resulting PDF has numerous PDF/A-3 compliance issues.
Environment
Reproduction
Minimal test script:
import { zugferd } from "node-zugferd";
import { BASIC } from "node-zugferd/profile/basic";
import { writeFileSync } from "fs";
import { PDFDocument } from "pdf-lib";
async function testZugferd() {
const invoicer = zugferd({ profile: BASIC });
const data = {
number: "TEST-2024-001",
typeCode: "380",
issueDate: new Date(),
businessProcessType: "A1",
transaction: {
tradeAgreement: {
buyerReference: "N/A",
seller: {
name: "Test Firma GmbH",
postalAddress: {
countryCode: "DE",
postCode: "12345",
line1: "Teststraße 1",
city: "Berlin",
},
taxRegistration: { vatIdentifier: "DE123456789" },
},
buyer: {
name: "Kunde AG",
postalAddress: {
countryCode: "DE",
postCode: "54321",
line1: "Kundenweg 2",
city: "München",
},
},
},
tradeDelivery: {
information: { deliveryDate: new Date() },
},
tradeSettlement: {
currencyCode: "EUR",
paymentInstruction: {
typeCode: "58",
transfers: [{ paymentAccountIdentifier: "DE89370400440532013000" }],
},
vatBreakdown: [
{
calculatedAmount: 19,
typeCode: "VAT",
basisAmount: 100,
categoryCode: "S",
rateApplicablePercent: 19,
},
],
paymentTerms: {
dueDate: new Date(Date.now() + 14 * 24 * 60 * 60 * 1000),
description: "Zahlbar innerhalb von 14 Tagen",
},
monetarySummation: {
lineTotalAmount: 100,
chargeTotalAmount: 0,
allowanceTotalAmount: 0,
taxBasisTotalAmount: 100,
taxTotal: { amount: 19, currencyCode: "EUR" },
grandTotalAmount: 119,
duePayableAmount: 119,
},
},
line: [
{
identifier: "1",
tradeProduct: { name: "Testprodukt" },
tradeAgreement: { netTradePrice: { chargeAmount: 100 } },
tradeDelivery: {
billedQuantity: { amount: 1, unitMeasureCode: "H87" },
},
tradeSettlement: {
tradeTax: {
typeCode: "VAT",
categoryCode: "S",
rateApplicablePercent: 19,
},
monetarySummation: { lineTotalAmount: 100 },
},
},
],
},
includedNote: [{ content: "Testrechnung" }],
};
const invoice = invoicer.create(data);
// Create blank PDF
const blankPdf = await PDFDocument.create();
blankPdf.addPage([595.28, 841.89]);
const blankPdfBytes = await blankPdf.save();
const zugferdPdf = await invoice.embedInPdf(blankPdfBytes, {
metadata: {
title: "Test Rechnung TEST-2024-001",
author: "Test Firma GmbH",
producer: "Invoice",
creator: "Invoice",
createDate: new Date(),
},
});
writeFileSync("test-zugferd.pdf", zugferdPdf);
}
testZugferd();
Validation Errors
The generated PDF fails validation with the following errors:
PDF/A-3 Compliance Issues
- [VD-Valitool-H-018] - Document must conform to PDF/A-3 or PDF/A-4 standard
- EmbeddedFiles key error - File name dictionary must not contain EmbeddedFiles key (PDF/A-1 restriction)
- EF key error - File specification dictionary must not contain EF key (PDF/A-1 restriction)
- Xref-Streams error - Document uses Xref-Streams which are not allowed in PDF/A-1
XMP Metadata Issues
- [VD-Valitool-H-005] - Invalid XMP data
- Producer mismatch - Document Info "Producer" ≠ XMP "pdf:Producer"
- Author mismatch - Document Info "Author" ≠ XMP "dc:creator"
- Creator mismatch - Document Info "Creator" ≠ XMP "xmp:CreatorTool"
- Title mismatch - Document Info "Title" ≠ XMP "dc:title"
- Missing PDF/A identification - Metadata stream missing PDF/A Identification Extension Schema
- XMP serialization error - Metadata stream not conformant to XMP specification
ICC Profile Issues
- ICC Profile N entry - N entry in ICC profile dictionary missing or doesn't match component count
Factur-X/ZUGFeRD Specific Issues
- [VD-Valitool-H-007] - Embedded file has MIME type
application/xml but text/xml is required
- [VD-Valitool-H-008] - XMP metadata missing required ZUGFeRD/Factur-X information
- [VD-Valitool-H-013] - Namespace format in XMP not standard-conformant
- [VD-Valitool-H-015] - Namespace prefix must be
fx (since Factur-X/ZUGFeRD 2.1)
- [VD-Valitool-H-019] - DocumentType not found in XMP (should be INVOICE)
- [VD-Valitool-H-020] - DocumentType from PDF () doesn't match XML (INVOICE)
- [VD-Valitool-H-022] - ConformanceLevel from PDF () doesn't match XML (BASIC)
- [VD-Valitool-H-023] - Version value in PDF is invalid
Expected Behavior
The embedInPdf function should produce a valid PDF/A-3b document with:
- Correct PDF/A-3 structure (not PDF/A-1)
- Consistent Document Info Dictionary and XMP metadata
- Valid ICC profile with correct N entry
- Correct MIME type
text/xml for the embedded XML
- Complete Factur-X XMP extension schema with:
fx:DocumentType = "INVOICE"
fx:DocumentFileName = "factur-x.xml"
fx:Version = "1.0"
fx:ConformanceLevel = "BASIC"
Additional Context
The XML generation (toXML()) works correctly and validates. Only the PDF embedding is broken.
The validator reports the PDF as "PDF/A-1B" format, suggesting the library is not correctly setting PDF/A-3 markers.
Current vs. Expected behavior
What version of node-zugferd are you using?
0.1.0 (also tested with 0.1.1-beta.1)
Provide environment information
Which area(s) are affected? (Select all that apply)
Other
Config (if applicable)
import { zugferd } from "node-zugferd";
import { BASIC } from "node-zugferd/profile/basic";
export const invoicer = zugferd({
profile: BASIC
})
To Reproduce
The
embedInPdffunction produces PDFs that fail ZUGFeRD/Factur-X validation. Even with a minimal blank PDF created with pdf-lib, the resulting PDF has numerous PDF/A-3 compliance issues.Environment
Reproduction
Minimal test script:
Validation Errors
The generated PDF fails validation with the following errors:
PDF/A-3 Compliance Issues
XMP Metadata Issues
ICC Profile Issues
Factur-X/ZUGFeRD Specific Issues
application/xmlbuttext/xmlis requiredfx(since Factur-X/ZUGFeRD 2.1)Expected Behavior
The
embedInPdffunction should produce a valid PDF/A-3b document with:text/xmlfor the embedded XMLfx:DocumentType= "INVOICE"fx:DocumentFileName= "factur-x.xml"fx:Version= "1.0"fx:ConformanceLevel= "BASIC"Additional Context
The XML generation (
toXML()) works correctly and validates. Only the PDF embedding is broken.The validator reports the PDF as "PDF/A-1B" format, suggesting the library is not correctly setting PDF/A-3 markers.
Current vs. Expected behavior
What version of node-zugferd are you using?
0.1.0 (also tested with 0.1.1-beta.1)
Provide environment information
Which area(s) are affected? (Select all that apply)
Other
Config (if applicable)