PDF 附件与混合发票检查
文件可以搭便车塞进一份 PDF 里,却不出现在任何一页上。这里把它们列出来 —— 而当这份 PDF 是 Factur-X 或 ZUGFeRD 发票时,先检查容器搭得对不对接收方期望的样子,再把发票本身拿去过第 226 条引擎。
🔒 你的文档不会离开浏览器。
把一个 PDF 拖到这里
一次一个 PDF · 什么都不上传
混合发票不是「一份带着 XML 的 PDF」
Factur-X 与 ZUGFeRD 把机读发票当作附件,装进一份 PDF/A-3 文件里。接收方到底找不找得到它,取决于几个打开文档时根本看不见的细节:
- 文件名是约定的一部分。接收方是按名字去找这个附件的:factur-x.xml, zugferd-invoice.xml, xrechnung.xml, order-x.xml。一个叫
invoice.xml的文件,不管内容多有效,都是找不到的。 - 关联关系必须说清这个文件是什么。PDF/A-3 用
/AFRelationship记录这件事:Alternative——XML 与页面是同一张发票的两种呈现——或者Source,这是 ZUGFeRD 2.1 对 BASIC、EN 16931 与 EXTENDED 这几个 profile 提出的要求,适用于接收方在德国境外、且 PDF 由 XML 生成的情况。 - 它必须登记两次。一次作为关联文件登记进
/AF,一次作为普通附件登记进/EmbeddedFiles—— 第二处的存在,是为了大量从未实现 PDF/A-3 关联文件特性的软件。只登记在一处,就是发送方看到一张有效发票、接收方却什么都看不到的那种失败。
然后:这张发票本身对不对?
把 XML 取出来是简单的那部分 —— 好几个免费工具都在做。这里往后发生的事才是我们的分量所在:发票被映射进发票生成器与字段检查器用的同一个模型,跑同一套规则 —— 第 226 条必载项、按增值税率分组算出来的金额而不是照抄文件里的、以及增值税号与 IBAN 的格式检查。一份自报的合计和自己的行项目对不上的文件,会在这一步露出来。
诚实的边界
读取器只按元素名取 Cross Industry Invoice 里有限的几条路径;这不是完整的 EN 16931 语义映射,读不到的一律列成「没读到」而不是猜。附件清单直接读自文档目录本身 —— 同时读 /EmbeddedFiles 名称树与 /AF 数组 —— 所以这里的关联关系一列,和 MCP server 填出来的一模一样。
本工具的全部检查项(共 8 条)
FXA-001 内嵌的发票文件没有按标准规定的名字命名
文件名是约定的一部分,不是随意选的:接收方是按名字去找这个附件的。ZUGFeRD 2.1 与 Factur-X 用 factur-x.xml,ZUGFeRD 2.0 用的是 zugferd-invoice.xml。一个叫 invoice.xml 的文件,对着规定名字去找的接收方来说是看不见的,不管它内容本身多有效。
修复: 把内嵌文件改名为 factur-x.xml,除非你是刻意在生成旧版本的 ZUGFeRD。
FXA-002 关联文件关系缺失,或者取值不是标准允许的那几个
PDF/A-3 用 /AFRelationship 记录一个文件为什么被附加进来。混合发票用 Alternative——XML 与页面是同一张发票的两种呈现——或者用 Source,这是 ZUGFeRD 2.1 对 BASIC、EN 16931 与 EXTENDED 这几个 profile 提出的要求,适用于接收方在德国境外、且 PDF 是由 XML 生成的情况。其余取值(Data、Supplement、Unspecified)都是在告诉接收方:这不是发票。
修复: 把 /AFRelationship 设为 Alternative,或者按标准指名的情形设为 Source。
FXA-003 这份 XML 是关联文件,但不是常规附件
发票 XML 必须同时出现在两个地方:作为关联文件出现在文档目录的 /AF 数组里,也作为普通附件出现在 /EmbeddedFiles 名称树里。第二处的存在是为了那些完全没实现 PDF/A-3 关联文件特性的软件——这样的软件还有不少。只出现在一处,就是发送方看到一份有效文件、接收方却什么都看不到的那种失败。
修复: 把这个附件同时登记进 /EmbeddedFiles 与 /AF。
FXA-004 XMP 元数据没有声明混合发票的扩展 schema
容器本该在 XMP 里自报家门:文档类型、内嵌 XML 的文件名、版本与 profile。接收方要靠它来决定要不要在打开任何附件之前,先去找一张发票。
修复: 把 Factur-X / ZUGFeRD 扩展 schema 块加进 XMP 包。
FXA-005 文件没有声明 PDF/A-3 合规性
混合发票是一份 PDF/A-3 文件——PDF/A 家族里允许任意附件的正是这一部分。没有这条声明,这份文档就只是一个恰好带着文件的普通 PDF,归档系统会区别对待。
FXA-006 内嵌文件不是一份可读的发票 XML
这个附件用对了名字,但解析不出 XML,或者能解析却不是 Cross Industry Invoice。一个信任文件名的接收方,拿到的是一个解析错误,而不是一张发票。
FXA-007 元数据里的 profile 与 XML 内部的 profile 对不上
profile 被声明了两次——一次在 XMP 块里,一次是 XML 内部的 guideline 参数。两者不一致时,读其中一个的接收方,套用的规则集就和读另一个的接收方不一样。
FXA-008 这份 PDF 携带了发票之外的附件
任何文件都可以搭便车塞进一份 PDF 里,附件跟着文档走,却不出现在任何一页上。这里把它们列出来,理由和元数据检查器列出文件里有什么一样:离开你手上的东西,应该是你选择要发出去的东西。
yaktool 工程说明,不是 Factur-X 规范的要求:把发票以外的附件列出来,是我们自己加的一道隐私卫生检查,与 PDF 涂黑检查器、EXIF 隐私检查器同一个思路。
关于这些规则。 每一条都有编号、严重级别和通俗解释。每个来源链接都已登记在案,并对线上页面实际复验过,而不是凭印象写上去的. 规则如何编写、测试与保持更新 →