Skip to content

ZUGFeRD / Factur-X 電子請求書

人間が読み、機械が自動解析できるハイブリッドPDFであるZUGFeRD / Factur-X電子請求書を作成します。

ZUGFeRD / Factur-Xとは?

ZUGFeRD(ドイツ)とFactur-X(フランス / EU)は同一の規格を2つの名前で呼んでいます。準拠した請求書には以下が含まれます:

  1. ビジュアルPDF -- PDF/A-3(またはPDF/A-4f)としてレンダリングされた人間が読める請求書
  2. 埋め込みXML -- PDF内部に添付された、UN/CEFACT Cross Industry Invoice(CII)形式の機械可読請求書データ

これにより、経理や監査担当者にとって馴染みのあるビジュアルドキュメントを維持しながら、完全自動化処理が可能になります。

プロファイル

プロファイル一般的な用途
Minimum請求書番号、日付、合計、税金
Basic WL+ 品目、支払条件
Basic+ 詳細な品目
EN 16931(Comfort)EU公共調達準拠
Extended複数税率の複雑な請求書
XRechnungドイツ公共部門の請求

PDF/Aの要件

ZUGFeRDでは、ホストPDFがPDF/A-3またはPDF/A-4f(ISO 19005)である必要があります。「f」バリアントは埋め込みファイルを許可します。TCPDF-Nextは準拠メタデータ、アウトプットインテント、ファイル添付フラグを自動的に処理します。

完全なコードサンプル

php
<?php

declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php';

use TcpdfNext\Document;
use TcpdfNext\Enums\PdfALevel;
use TcpdfNext\Archive\OutputIntent;
use TcpdfNext\Archive\EmbeddedFile;
use TcpdfNext\Archive\AFRelationship;

// ── 1. PDF/A-4fドキュメントを作成 ──────────────────────────────────────
$pdf = Document::create()
    ->setPdfALevel(PdfALevel::A4F)
    ->setOutputIntent(OutputIntent::sRGB())
    ->setTitle('Invoice INV-2026-0042')
    ->setAuthor('Acme GmbH')
    ->setSubject('Invoice for Order PO-2026-0815');

// ── 2. ビジュアル請求書をレンダリング ───────────────────────────────────────
$invoiceHtml = <<<'HTML'
<h1 style="color:#1a2634;">INVOICE</h1>
<table style="width:100%; margin-bottom:20px;">
    <tr>
        <td><strong>Acme GmbH</strong><br>Friedrichstr. 123<br>10117 Berlin, DE</td>
        <td style="text-align:right;"><strong>INV-2026-0042</strong><br>Date: 2026-02-15<br>Due: 2026-03-17</td>
    </tr>
</table>
<table border="1" cellpadding="6" style="width:100%; border-collapse:collapse;">
    <thead>
        <tr style="background:#1a2634; color:#fff;">
            <th>#</th><th>Description</th><th style="text-align:right;">Amount</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>1</td>
            <td>Professional Services -- February 2026</td>
            <td style="text-align:right;">EUR 1,000.00</td>
        </tr>
    </tbody>
    <tfoot>
        <tr><td colspan="2" style="text-align:right;">Net</td><td style="text-align:right;">EUR 1,000.00</td></tr>
        <tr><td colspan="2" style="text-align:right;">VAT 19%</td><td style="text-align:right;">EUR 190.00</td></tr>
        <tr style="font-weight:bold;">
            <td colspan="2" style="text-align:right;">Total</td>
            <td style="text-align:right;">EUR 1,190.00</td>
        </tr>
    </tfoot>
</table>
HTML;

$pdf->addPage()
    ->setFont('helvetica', size: 10)
    ->writeHtml($invoiceHtml);

// ── 3. Factur-X XML(EN 16931プロファイル)を構築 ───────────────────────
$xml = <<<'XML'
<?xml version="1.0" encoding="UTF-8"?>
<rsm:CrossIndustryInvoice
    xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
    xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
    xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
  <rsm:ExchangedDocumentContext>
    <ram:GuidelineSpecifiedDocumentContextParameter>
      <ram:ID>urn:factur-x.eu:1p0:en16931</ram:ID>
    </ram:GuidelineSpecifiedDocumentContextParameter>
  </rsm:ExchangedDocumentContext>
  <rsm:ExchangedDocument>
    <ram:ID>INV-2026-0042</ram:ID>
    <ram:TypeCode>380</ram:TypeCode>
    <ram:IssueDateTime>
      <udt:DateTimeString format="102">20260215</udt:DateTimeString>
    </ram:IssueDateTime>
  </rsm:ExchangedDocument>
  <rsm:SupplyChainTradeTransaction>
    <ram:ApplicableHeaderTradeAgreement>
      <ram:SellerTradeParty>
        <ram:Name>Acme GmbH</ram:Name>
        <ram:SpecifiedTaxRegistration>
          <ram:ID schemeID="VA">DE123456789</ram:ID>
        </ram:SpecifiedTaxRegistration>
      </ram:SellerTradeParty>
      <ram:BuyerTradeParty>
        <ram:Name>Customer Corp</ram:Name>
      </ram:BuyerTradeParty>
    </ram:ApplicableHeaderTradeAgreement>
    <ram:ApplicableHeaderTradeSettlement>
      <ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
      <ram:SpecifiedTradeSettlementHeaderMonetarySummation>
        <ram:LineTotalAmount>1000.00</ram:LineTotalAmount>
        <ram:TaxBasisTotalAmount>1000.00</ram:TaxBasisTotalAmount>
        <ram:TaxTotalAmount currencyID="EUR">190.00</ram:TaxTotalAmount>
        <ram:GrandTotalAmount>1190.00</ram:GrandTotalAmount>
        <ram:DuePayableAmount>1190.00</ram:DuePayableAmount>
      </ram:SpecifiedTradeSettlementHeaderMonetarySummation>
    </ram:ApplicableHeaderTradeSettlement>
  </rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>
XML;

// ── 4. XMLを関連ファイルとして埋め込み ─────────────────────────────
$pdf->addEmbeddedFile(
    EmbeddedFile::create()
        ->setFilename('factur-x.xml')
        ->setMimeType('text/xml')
        ->setContent($xml)
        ->setRelationship(AFRelationship::Alternative)
        ->setDescription('Factur-X EN 16931 invoice data')
);

// ── 5. ZUGFeRD XMPメタデータを設定 ────────────────────────────────────
$pdf->getMetadata()
    ->setXmpProperty('fx:DocumentType', 'INVOICE')
    ->setXmpProperty('fx:DocumentFileName', 'factur-x.xml')
    ->setXmpProperty('fx:Version', '1.0')
    ->setXmpProperty('fx:ConformanceLevel', 'EN 16931');

// ── 6. 保存 ────────────────────────────────────────────────────────────
$pdf->save(__DIR__ . '/INV-2026-0042.pdf');

echo 'ZUGFeRD invoice created.' . PHP_EOL;

バリデーション

bash
# PDF/A準拠
verapdf --flavour 4f INV-2026-0042.pdf

# Factur-X XMLスキーマ
java -jar Mustang-CLI.jar --action validate --source INV-2026-0042.pdf

TIP

Mustangprojectは、ZUGFeRD/Factur-X請求書の無料オープンソースバリデーターです。

ワークフロー図

ERP / 請求データ
        |
        v
  TCPDF-Next 生成
        |
        v
  PDF/A-4f + 埋め込みfactur-x.xml
        |
        v
  (オプション)PAdESデジタル署名
        |
        +-------+-------+-------+
        |       |       |       |
      メール  ポータル PEPPOL  アーカイブ

さらに詳しく

LGPL-3.0-or-later ライセンスの下で公開されています。