ZUGFeRD 電子發票¶
ZUGFeRD(Zentraler User Guide des Forums elektronische Rechnung Deutschland)是歐洲主流的混合型電子發票標準,將人類可讀的 PDF 與機器可讀的 XML(EN 16931 格式)合併在同一份 PDF/A-4f 文件中。
NextPDF Enterprise 提供完整的 ZUGFeRD 2.x 生成管線,包含 XML 建構、Schema 驗證、PDF/A-4f 嵌入,以及 Factur-X 相容性。
支援 Profile¶
| Profile | 用途 | XML 複雜度 | 強制欄位 |
|---|---|---|---|
| MINIMUM | 最小基礎資訊(Factur-X 相容) | 極低 | 發票號、日期、金額、VAT |
| BASIC WL | 基礎行次明細 | 低 | + 行次說明 |
| BASIC | 完整 EN 16931 必要資訊 | 中 | + 稅務分類、付款條件 |
| COMFORT | 推薦商業用途(EN 16931 全集) | 中高 | + 買賣方完整資訊、多稅率 |
| EXTENDED | 進階行次與物流資訊 | 高 | + 交付資訊、允許自定義擴充 |
| XRECHNUNG | 德國政府 B2G 採購專用 | 中高 | 符合 XRechnung 2.3 |
核心 API¶
ZugferdBuilder¶
use NextPDF\Enterprise\Invoice\ZugferdBuilder;
use NextPDF\Enterprise\Invoice\ZugferdProfile;
use NextPDF\Enterprise\Invoice\InvoiceParty;
use NextPDF\Enterprise\Invoice\InvoiceLine;
use NextPDF\Enterprise\Invoice\TaxCategory;
use NextPDF\Enterprise\Invoice\MonetaryAmount;
$invoice = ZugferdBuilder::create(ZugferdProfile::Comfort)
->withInvoiceNumber('INV-2025-001234')
->withInvoiceDate(new DateTimeImmutable('2025-01-15'))
->withDueDate(new DateTimeImmutable('2025-02-14'))
->withCurrency('EUR')
->withSeller(
InvoiceParty::create(
name: 'ACME GmbH',
vatId: 'DE123456789',
address: InvoiceAddress::create(
line1: 'Musterstraße 42',
city: 'Berlin',
postCode: '10115',
countryCode: 'DE',
),
contact: InvoiceContact::create(
name: 'Hans Müller',
email: 'billing@acme.de',
phone: '+49 30 12345678',
),
)
)
->withBuyer(
InvoiceParty::create(
name: 'Widget AG',
vatId: 'CHE-123.456.789',
address: InvoiceAddress::create(
line1: 'Bahnhofstrasse 1',
city: 'Zürich',
postCode: '8001',
countryCode: 'CH',
),
)
)
->addLine(
InvoiceLine::create(
id: '1',
description: 'Professional Services — Q4 2024',
quantity: MonetaryAmount::units(8.0),
unitCode: 'HUR', // UN/ECE Rec 20: Hours
unitPrice: MonetaryAmount::eur(125.00),
taxCategory: TaxCategory::Standard,
taxPercent: 19.0,
)
)
->addLine(
InvoiceLine::create(
id: '2',
description: 'Software License — Annual',
quantity: MonetaryAmount::units(1.0),
unitCode: 'C62', // Each
unitPrice: MonetaryAmount::eur(2400.00),
taxCategory: TaxCategory::Standard,
taxPercent: 19.0,
)
)
->withPaymentTerms('30 days net')
->withPaymentMeans(
PaymentMeans::sepa(
iban: 'DE89370400440532013000',
bic: 'COBADEFFXXX',
)
);
// 產生 ZUGFeRD XML
$xml = $invoice->buildXml();
// 產生 PDF/A-4f 發票(XML 嵌入為關聯檔案)
$pdfInvoice = $invoice->buildPdf(
visualTemplate: $invoicePdfTemplate,
);
PHP Compatibility
This example uses PHP 8.5 syntax. If your environment runs PHP 8.1 or 7.4, use NextPDF Backport for a backward-compatible build.
XML 驗證¶
use NextPDF\Enterprise\Invoice\ZugferdValidator;
use NextPDF\Enterprise\Invoice\ValidationLevel;
$validator = new ZugferdValidator();
// 多層次驗證
$result = $validator->validate(
xmlContent: $xml,
profile: ZugferdProfile::Comfort,
level: ValidationLevel::Full, // Schema + Schematron + EN 16931 semantic rules
);
if (!$result->isValid()) {
foreach ($result->errors() as $error) {
echo sprintf(
'[%s] %s (xpath: %s)',
$error->severity()->name, // ERROR | WARNING | INFO
$error->message(),
$error->xpath(),
);
}
}
PDF/A-4f 整合¶
ZUGFeRD 強制要求 PDF/A-4f 容器格式:
use NextPDF\Enterprise\Invoice\ZugferdPdfEmitter;
use NextPDF\Enterprise\Compliance\PdfA\PdfA4Builder;
use NextPDF\Enterprise\Compliance\PdfA\PdfA4Subset;
// ZugferdPdfEmitter 自動處理 PDF/A-4f 嵌入
$emitter = new ZugferdPdfEmitter(
pdfBuilder: PdfA4Builder::forSubset(PdfA4Subset::PdfA4f),
);
$invoicePdf = $emitter->emit(
invoiceXml: $xml,
visualPdf: $renderedInvoicePdf,
filename: 'factur-x.xml', // ZUGFeRD 標準要求此確切檔名
);
// 或直接從 ZugferdBuilder 一步完成
$invoicePdf = $invoice->buildPdf(visualTemplate: $template);
稅務計算¶
use NextPDF\Enterprise\Invoice\TaxCalculator;
use NextPDF\Enterprise\Invoice\VatRoundingMode;
$calculator = new TaxCalculator(
roundingMode: VatRoundingMode::HalfUp,
precision: 2,
);
// 自動計算行次小計、VAT、發票總計
$totals = $calculator->calculateTotals($invoiceLines);
echo $totals->netAmount(); // 未稅金額
echo $totals->taxAmount(); // 稅額
echo $totals->grossAmount(); // 含稅總計
echo $totals->taxBreakdown(); // 各稅率分項(多稅率支援)
Factur-X 相容性¶
ZUGFeRD 2.x 與法法共同定義的 Factur-X 1.0 完全相容:
use NextPDF\Enterprise\Invoice\FacturXBuilder;
// Factur-X 使用相同 API,僅 profile 命名不同
$invoice = FacturXBuilder::create(FacturXProfile::En16931)
// ... 相同建構方法
->buildPdf(visualTemplate: $template);