目录
昨天,2026年6月30日,是一个悄然重塑沙特商业格局的截止日期。ZATCA第二阶段电子发票推行的第24批次正式生效——这是首个覆盖到年应税营收低至37.5万里亚尔的企业的批次,而这一数字恰好也是增值税强制注册的门槛本身。实际上,这意味着沙特几乎所有已注册增值税的企业如今都被要求与Fatoora平台完成集成。此前允许企业无经济后果地修正入网错误的罚款豁免窗口,也在同一天关闭。截至今日,ZATCA的电子发票强制执行实际上已覆盖全国。
如果您为沙特市场开发或维护POS、ERP或计费系统,那么每张收据上那个小小的黑白方块早已不再是可有可无的“课外作业”——它是您软件产出的最直观合规证明。本指南将说明二维码究竟包含哪些内容、ZATCA为何要这样设计这一项目、第一阶段与第二阶段的真实区别、B2B与B2C发票如何分化、买方实际如何申报增值税抵扣,以及最常导致二维码验证失败的错误。文末附有一个免费的客户端生成器,方便您逐个标签地亲自构建并检查一个合规的二维码。
什么是ZATCA电子发票,为何存在?
ZATCA——即Zakat、税务与海关总局——是沙特政府负责征收增值税、天课(Zakat)、关税并执行电子发票合规工作的机构。它于2021年由天课与所得税总局(GAZT)与海关总局合并而成,将税务管理统一到同一屋檐下。
沙特阿拉伯于2018年1月1日引入了5%的增值税,作为海湾合作委员会范围内统一部署的一部分。2020年7月1日,面对石油收入骤降与新冠疫情带来的财政冲击,政府将税率提高两倍至15%,并延续至今。如此规模的税种施加于整个经济体,其有效性完全取决于政府能否核实税款确实被征收并上缴——而纸质发票、手写收据和电子表格生成的账单,都极易被低报甚至干脆不予开具。向客户征收的增值税与实际向国家申报的增值税之间的这一缺口,正是名为Fatoora的电子发票项目所要弥合的。
二维码正是这一体系中肉眼可见的部分。它将每一张收据都转化为一条机器可读、可独立验证的记录,使顾客、审计人员或ZATCA自身的系统都能确认发票的真实性,而无需依赖印在纸上的内容本身。该项目按官方定义分两个阶段推行:
- 2021年12月4日——第一阶段(生成阶段):所有已注册增值税的企业都必须停止手写或电子表格生成的发票,改用能够生成并存储带TLV二维码的电子发票的合规电子系统。
- 自2023年1月1日起——第二阶段(集成阶段):企业需将其电子发票系统直接连接到ZATCA的Fatoora平台,以进行实时清关或报告。由于同时接入所有企业在操作上并不现实,ZATCA按年度应税营收分组,以连续的“批次”方式推进,每批次至少提前六个月公布截止日期。第1批次(营业额超过30亿里亚尔)已于2023年1月1日生效;第24批次(营业额超过37.5万里亚尔)已于昨日生效。
截至本文撰写之时,尚未有单独宣布的“第三阶段”——该项目官方仅分为两个阶段,而第二阶段本身仍在通过后续批次不断扩大,ZATCA正逐步下沉至规模更小的纳税人,并最终形成覆盖面更广的体系,其中包括用于预填增值税申报表的电子发票。任何提及独立“第三阶段”的内容,都应视为对未来某批次的非正式说法,而非官方名称。
ZATCA二维码实际是如何运作的
ZATCA的二维码并不是一个链接。用普通二维码App扫描它,您不会跳转到任何网站——只会得到一段Base64文本。这段文本是ZATCA自身《电子发票安全特性实施标准》中所定义的三阶段特定流程的输出结果:
- 构建TLV结构。每个字段——卖方名称、增值税号、时间戳等——都编码为“标签+长度+值”:1字节的标签编号,1字节的长度(该值的字节长度,而非字符数),以及以UTF-8字节表示的值本身。所有字段依次拼接成一个连续的字节数组。
- 将字节数组编码为Base64。整个TLV结构以原始字节形式转换为单一的Base64字符串。ZATCA将该字符串长度上限设为700个字符。
- 将Base64字符串渲染为二维码。只有在这最后一步,文本才真正变成印在收据上的黑白方块图案。
以下是这套逻辑用JavaScript实现的核心代码——正是驱动本页下方生成器的那同一个函数:
function buildTLV(tag, value) {
const bytes = new TextEncoder().encode(value); // never value.length
const out = new Uint8Array(2 + bytes.length);
out[0] = tag;
out[1] = bytes.length; // byte length — critical for Arabic text
out.set(bytes, 2);
return out;
}
// tags 1-5, concatenated, then Base64-encoded
const tlv = concat([buildTLV(1, sellerName), buildTLV(2, vatNumber),
buildTLV(3, timestamp), buildTLV(4, total), buildTLV(5, vatAmount)]);
const qrPayload = base64Encode(tlv);
其中那一行注释——never value.length——值得多加留意。JavaScript字符串的.length属性统计的是UTF-16码元数,而不是字节数。“Bobs Records”这个例子恰好在纯ASCII下字符数与字节数相同,所以一个偷懒的实现在测试阶段能顺利通过,却会在生产环境中悄悄损坏每一张带有阿拉伯语卖方名称的发票,因为阿拉伯字符在UTF-8下每个占用2字节。我们会在常见错误部分再次回到这个问题,因为它是导致二维码被拒的最常见实际原因之一。
第一阶段 vs 第二阶段:究竟改变了什么
很容易把第二阶段简单理解为“第一阶段再加几个字段”。但实际上,这是一种完全不同的架构。第一阶段要求你生成一份正确的文档;第二阶段要求你生成一份正确的文档,并且要实时向ZATCA证明这一点,且这一切都绑定在硬件或软件层面的加密身份之上。
| 方面 | 第一阶段——生成 | 第二阶段——集成 |
|---|---|---|
| 生效时间 | 2021年12月4日——所有纳税人同时生效 | 2023年1月1日——按批次分阶段推行(第24批次自2026年6月30日起生效) |
| 发票格式 | 任何合规的电子系统均可;不允许手写或电子表格生成的发票 | UBL 2.1 XML,或内嵌XML的PDF/A-3格式——其余格式一律不合规 |
| 二维码内容 | 5个TLV标签:卖方名称、增值税号、时间戳、总额、增值税金额 | 9个TLV标签:在上述5项基础上,再加上XML哈希值、ECDSA签名、公钥和加密戳 |
| 系统连接 | 独立运行——可完全离线运作 | 必须与ZATCA的Fatoora平台建立实时API连接 |
| 政府验证 | 无——仅自行生成并自行保存 | B2B:在到达买方之前由ZATCA完成清关。B2C:需在24小时内向ZATCA报告 |
| 发票链式关联 | 不要求 | 要求:需要一个连续的发票计数值(ICV)以及前一张发票的哈希值(PIH),以确保任何发票都无法被悄悄删除或插入 |
| 加密身份 | 无 | 要求:由ZATCA向您的开票解决方案签发一个加密戳标识符(CSID) |
B2B与B2C:哪些规则适用于你
ZATCA法规认可两种发票类型,而混淆二者是导致企业不合规——或对买方而言,无法追回本以为可以申报的增值税——的最快途径之一。
标准税务发票(B2B / B2G):用于两个已注册增值税的主体之间。必须显示卖方和买方双方的名称与增值税号、逐项明细,以及每一项的增值税金额。在第二阶段下,它遵循清关模式:您的系统将发票提交至ZATCA的Fatoora平台,并必须在发票合法送达买方之前获得批准——包括一个加密戳。标准发票上的二维码在大多数情况下是可选的,尽管许多ERP系统还是会默认加上。
简化税务发票(B2C):用于零售终端,通常适用于买方未注册增值税或在销售时身份未知的情况——零售小票就是典型例子。它遵循报告模式:发票立即开具给顾客,随后您的系统需在24小时内向ZATCA报告。每张简化发票都必须含有二维码,这也是大多数人说“ZATCA二维码”时所指的版本。
有两个门槛值得了解:只要B2B供应超过1000里亚尔,就在法律上强制要求使用标准税务发票(低于此金额,即使在两家企业之间也可使用简化发票);如果发票总价值低于1000里亚尔,简化发票上甚至可以完全省略卖方的增值税号。
这一区分远不止是格式问题。正如下文增值税申报部分所述,只有标准税务发票才能支持进项税抵扣申请——无论简化发票上的二维码格式多么完美,一般都无法支持这一点。
全部9个TLV标签详解
ZATCA可能要求二维码包含的每个字段都有固定的标签编号。标签1至5自第一阶段起即为强制要求;标签6至9是为第二阶段新增的。
| 标签 | 字段 | 要求生效时间 | 备注 |
|---|---|---|---|
| 1 | 卖方名称 | Phase 1 | 必须在发票本身以阿拉伯语显示;双语名称也可接受 |
| 2 | 卖方增值税号 | Phase 1 | 注册时由ZATCA签发的、恰好15位数字 |
| 3 | 发票时间戳 | Phase 1 | ISO 8601格式,例如 2026-06-30T14:05:00Z |
| 4 | 发票总额(含增值税) | Phase 1 | 客户实际支付的最终金额 |
| 5 | 增值税总额 | Phase 1 | 上述总额中所含的增值税部分 |
| 6 | 发票XML哈希值 | Phase 2 | 已签署的发票XML的SHA-256哈希值 |
| 7 | ECDSA签名 | Phase 2 | 基于该哈希值、使用纳税人私钥生成的数字签名 |
| 8 | ECDSA公钥 | Phase 2 | 与您的CSID证书关联的密钥对中的公钥部分 |
| 9 | 加密戳签名 | Phase 2 | 仅限简化发票——由ZATCA自身的技术CA在报告后签发 |
生成顺序很重要。请先构建并对XML发票进行加密签名,然后才计算哈希值、提取签名并组装二维码。若在签名前生成二维码,会导致第6至9项标签为空或过期——这是一个出人意料常见的错误,会导致立即被拒。
企业主实际需要做什么
抛开各种缩写,合规其实可以归结为五个阶段。以下就是从“尚未注册”到“Fatoora正式上线”的完整路径。
1. 完成增值税注册
一旦您的年度应税供应额超过37.5万里亚尔,注册即为强制要求。在18.75万里亚尔到该门槛之间,注册为自愿性质——通常也值得一做,因为这样您就能就自身采购申报进项税抵扣。凡在沙特境内提供应税供应的非居民企业,无论营业额多少都必须注册。
2. 获取符合第一阶段要求的系统,然后确认所属批次
如今所有已注册增值税的企业都已需要具备第一阶段的生成能力。第二阶段则按计划分批到来:ZATCA按年度应税营收将纳税人分组,并在每组截止日期前至少六个月发出通知。门槛值一直在快速收紧——第1批次覆盖营业额超过30亿里亚尔的企业;而自昨日起生效的第24批次,覆盖营业额超过37.5万里亚尔的企业。如果您尚未收到通知,最好直接向ZATCA核实,而不要想当然地认为自己不在范围之内。
3. 在Fatoora门户完成CSID入网
这是第二阶段的技术核心所在,遵循一套固定的五步流程:
- 登录Fatoora门户,通过您的ZATCA纳税人账户使用单点登录。
- 为每台需要入网的设备或解决方案单元生成一次性密码(OTP)。
- 连同OTP一并提交证书签名请求(CSR),获取一个合规CSID——这是一个沙盒证书。
- 通过合规性检查:在沙盒环境中提交标准和简化发票样本,供ZATCA验证。
- 获取您的生产CSID——有效期约一年,到期前可续期——然后正式对接真实的Fatoora接口投入生产。
4. 在截止日期前进行全流程测试
ZATCA专门提供了一个Fatoora模拟门户,供您在不触碰生产数据的情况下演练入网、清关和报告流程。业内的通行做法是至少在所属批次截止日期前一个月完成这项工作,因为证书问题和被拒的样本发票,在执行开始前修复要比之后修复便宜得多。
5. 保存记录——时间比你想象的更长
发票、票据及相关支持记录必须自相关纳税期间结束之日起至少保存6年——涉及不动产的内容则延长至11年。记录须以阿拉伯语保存(双语版本也可),并存放在沙特阿拉伯境内。
不合规实际会付出的代价
ZATCA的处罚框架会随违规情节而分级,且累犯罚款会加重。已公布的数据包括:
| 违规行为 | 罚款 |
|---|---|
| 增值税逾期注册 | 10,000里亚尔 |
| 未开具或存档合规的电子发票 | 5,000里亚尔起 |
| 二维码缺失或不合规 | 每张发票最高10,000里亚尔 |
| 发票开具后予以删除或修改 | 10,000里亚尔起 |
| 实时清关/报告集成不合规 | 每次违规5,000至50,000里亚尔 |
以上数字截至2026年年中,取自ZATCA公布的处罚结构及第三方合规摘要;由于处罚标准会定期修订,请务必直接在zatca.gov.sa上确认当前金额。
验证二维码,以及增值税实际是如何申报抵扣的
验证二维码
由于二维码的负载只是普通的Base64文本,任何通用二维码扫描器在技术上都能读取它——但“能读取”不等于“能验证”。要真正确认一张发票的真实性,需要解码TLV结构,并将其加密戳与ZATCA的证书链进行比对,为此应使用ZATCA自己的增值税App(提供iOS和Android版本)或zatca.gov.sa上的电子发票验证服务。正因如此,一个在屏幕上“看起来没问题”的二维码,仍可能在真正的扫描验证中失败——这一点在测试自己的输出结果时值得牢记。
企业实际如何申报增值税抵扣
这是一般性说明通常会略过的部分,也是我们被问得最多的问题的答案:发票上有二维码是否就意味着我可以申报增值税抵扣?答案是:不一定,也并非总能。
沙特增值税采用发票抵扣制:已注册增值税的企业对其销售收取销项税,并可用其自身采购所支付的进项税进行抵扣,只将差额上缴ZATCA。要行使这一抵扣权,实施条例(第53(5)条)要求企业持有有效的税务发票——具体而言是一张标准税务发票,须显示双方的增值税号、日期、供应描述以及增值税金额。简化发票(B2C类型),即便带有二维码等全部要素,通常也无法支持进项税抵扣申请,因为它本就不要求识别买方身份。
在第二阶段下,还存在一道额外门槛:根据ZATCA的电子发票实施决议,一份电子发票必须已实际经ZATCA清关或已向其报告,才能作为进项税抵扣的凭证——供应商生成但从未提交至Fatoora的发票不算数,无论其表面看起来多么正确。
关于买方一侧的一些实用规则:
- 时间点:抵扣权产生于收到供应品并开具税务发票的那个纳税期间,而不是付款或消费货物之时。
- 申报周期:年营业额超过4000万里亚尔的企业须按月申报增值税;其余企业按季度申报。
- 保存期限:发票须保存6年(与不动产相关的供应为11年)——ZATCA可能在很久之后的审计中要求提供。
- 语言:发票必须以阿拉伯语载明所需信息。如果供应商的发票不完整,ZATCA可自行决定是否接受替代证明,但供应商仍有义务开具规范的阿拉伯语税务发票。
简而言之:二维码证明的是收据的真实性。至于其中的增值税是否可以申报抵扣,则是一个独立的问题,答案取决于发票的类型,而不在于它是否带有二维码。
常见二维码错误及修复方法
大多数“二维码无效”的报告,都可以追溯到一小组反复出现的实现错误。按出现频率大致排序如下:
- 使用字符长度而非字节长度。长度标签必须是该值以UTF-8编码的字节长度。阿拉伯语及任何非ASCII文本占用的字节数都会多于字符数——一旦搞错,随之而来的每一个阿拉伯语卖方名称都会悄悄损坏发票。
- 在签署XML之前生成二维码。标签6至9依赖于最终已签署的文档。若先构建二维码,这些标签最终会是空的、过期的,或基于一个已不再匹配ZATCA实际收到的发票的哈希值。
- 仅使用ASCII编码。部分老旧库默认使用Latin-1或Windows-1252编码。ZATCA要求全程严格使用UTF-8——一旦某个值包含阿拉伯字符、弯引号或某些符号,其他编码方式都会出错。
- 遗漏阿拉伯语卖方名称。仅使用英文商号名对国际品牌来说是常见的捷径,但打印出的发票——进而其背后的数据——都需要包含阿拉伯语名称。
- 数值超过255字节。长度字节只能表示0至255。异常长的法律实体名称或意外冗长的字段可能会导致溢出——请在编码前而不是二维码扫描失败后验证字段长度。
- 混淆发票类型。标签9(ZATCA自身的加密戳)适用于事后报告的简化发票;标准发票则通过不同的流程完成清关。将一种发票类型的标签结构套用到另一种上,会生成一个看似合理但验证失败的二维码。
- 误以为“看起来像二维码”就意味着有效。格式错误的TLV结构仍可能渲染为一个可扫描、视觉上正常的二维码——判断其是否正确的唯一方法是解码并检查各字段,或使用ZATCA自己的验证App进行扫描。
立即体验:免费的ZATCA二维码生成器
在下方填写字段,即可实时查看TLV结构、Base64负载和二维码的更新。全部过程都以JavaScript在您的浏览器中运行——您输入的任何内容都不会被发送到任何地方。页面已预加载示例数据(包含一个阿拉伯语卖方名称,用以直观展示前文所述的UTF-8字节长度处理方式),让您可以立即看到一个可正常运作的二维码。