ZUGFeRD 電子發票範例(Enterprise)¶
需求套件:nextpdf/enterprise 難度:進階
先決條件¶
ZUGFeRD 設定檔說明¶
| 設定檔 | 適用場景 | XML 欄位數量 |
|---|---|---|
| MINIMUM | 最基本(僅供 B2C) | 少 |
| BASIC | 標準 B2B | 中等 |
| EN-16931 | 歐盟標準(推薦) | 完整 |
| XRECHNUNG | 德國政府採購 | 完整(特定格式) |
完整程式碼¶
<?php
declare(strict_types=1);
use NextPDF\Enterprise\EInvoice\ZugferdBuilder;
use NextPDF\Enterprise\EInvoice\ValueObjects\ZugferdProfile;
use NextPDF\Enterprise\EInvoice\ValueObjects\TradeParty;
use NextPDF\Enterprise\EInvoice\ValueObjects\Address;
use NextPDF\Enterprise\EInvoice\ValueObjects\TaxRegistration;
use NextPDF\Enterprise\EInvoice\ValueObjects\LineItem;
use NextPDF\Enterprise\EInvoice\ValueObjects\Tax;
use NextPDF\Enterprise\EInvoice\ValueObjects\PaymentTerms;
use NextPDF\Enterprise\EInvoice\ValueObjects\BankAccount;
use NextPDF\Core\Document;
use NextPDF\Core\ValueObjects\PageSize;
use NextPDF\Core\ValueObjects\Margin;
// ─── 發票資料 ─────────────────────────────────────────────────
$invoiceNumber = 'INV-2024-DE-001';
$issueDate = new DateTimeImmutable('2024-03-15');
$dueDate = new DateTimeImmutable('2024-04-14');
// ─── 賣方資訊 ─────────────────────────────────────────────────
$seller = TradeParty::create(
name: 'NextPDF Technology GmbH',
address: Address::create(
street: 'Musterstraße 42',
city: 'Berlin',
postalCode: '10115',
country: 'DE',
),
taxId: TaxRegistration::vatId('DE123456789'),
globalId: '4012345678901', // GLN(可選)
contactEmail: 'billing@nextpdf.dev',
contactPhone: '+49 30 12345678',
);
// ─── 買方資訊 ─────────────────────────────────────────────────
$buyer = TradeParty::create(
name: 'Musterkunde AG',
address: Address::create(
street: 'Hauptstraße 100',
city: 'München',
postalCode: '80331',
country: 'DE',
),
taxId: TaxRegistration::vatId('DE987654321'),
buyerReference: 'PO-2024-0042', // Leitweg-ID(德國政府採購必填)
);
// ─── 發票明細 ─────────────────────────────────────────────────
$lineItems = [
LineItem::create(
id: '1',
name: 'NextPDF Enterprise Annual License',
description: 'Full year enterprise PDF generation license (PDF 2.0, PAdES B-LTA, PDF/A-4)',
quantity: 1.0,
unitCode: 'C62', // UN/ECE Unit Code: piece
unitPrice: 4_990.00,
tax: Tax::create(rate: 19.0, categoryCode: 'S'), // Standard rate
),
LineItem::create(
id: '2',
name: 'Technical Support Package (10h)',
description: 'Premium technical support, 10 hours, valid 12 months',
quantity: 10.0,
unitCode: 'HUR', // Hours
unitPrice: 150.00,
tax: Tax::create(rate: 19.0, categoryCode: 'S'),
),
LineItem::create(
id: '3',
name: 'CJK Font Bundle License',
description: 'Commercial license for CJK font package (TC, SC, JP, KR)',
quantity: 1.0,
unitCode: 'C62',
unitPrice: 299.00,
tax: Tax::create(rate: 19.0, categoryCode: 'S'),
),
];
// ─── 建立 ZUGFeRD 文件 ────────────────────────────────────────
$builder = ZugferdBuilder::create(
profile: ZugferdProfile::EN16931, // EN 16931(COMFORT)設定檔
);
$zugferd = $builder->build(
invoiceNumber: $invoiceNumber,
issueDate: $issueDate,
dueDate: $dueDate,
seller: $seller,
buyer: $buyer,
lineItems: $lineItems,
paymentTerms: PaymentTerms::create(
description: 'Zahlbar innerhalb von 30 Tagen netto.',
bankAccount: BankAccount::create(
iban: 'DE89370400440532013000',
bic: 'COBADEFFXXX',
),
),
note: 'Vielen Dank für Ihr Vertrauen in NextPDF!',
currency: 'EUR',
buyerOrderReference: 'PO-2024-0042',
);
// ─── 生成 PDF/A-3 視覺 PDF(可視為發票外觀)───────────────────
$pdfDocument = Document::createStandalone(
pageSize: PageSize::A4,
margin: Margin::symmetric(vertical: 20.0, horizontal: 25.0),
);
$page = $pdfDocument->pages()->add();
// 渲染視覺發票(使用 Core API)
// ... (與 invoice.zh-TW.md 範例相同的視覺渲染程式碼)...
// ─── 嵌入 ZUGFeRD XML 並轉換為 PDF/A-3 ──────────────────────
$finalDocument = $zugferd->embedInto(
document: $pdfDocument,
conformance: 'PDF/A-3B', // ZUGFeRD 要求 PDF/A-3B 或更高
xmlFilename: 'factur-x.xml',
);
$finalDocument->save('/output/invoice-zugferd-' . $invoiceNumber . '.pdf');
// ─── 驗證輸出 ─────────────────────────────────────────────────
$validator = $zugferd->validator();
$result = $validator->validateFile('/output/invoice-zugferd-' . $invoiceNumber . '.pdf');
if (!$result->isValid()) {
foreach ($result->errors() as $error) {
error_log("ZUGFeRD Validation Error: {$error->code()} — {$error->message()}");
}
throw new RuntimeException('ZUGFeRD validation failed: ' . $result->errorSummary());
}
echo "ZUGFeRD invoice generated successfully.\n";
echo "Profile: {$result->profile()}\n";
echo "Conformance: {$result->conformance()}\n";
程式碼說明¶
驗證工具¶
延伸閱讀¶
- Enterprise API — ZUGFeRD 完整 API
- 無障礙指南 — PDF/A 與 PDF/UA 雙重合規
- 數位簽章指南 — 為電子發票加上 PAdES 簽章