You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter中解码符合ZATCA规范的QR码并提取对应字段?

Flutter 解析ZATCA规范二维码获取指定字段的实现方案

首先明确:ZATCA电子发票二维码采用TLV(标签-长度-值)二进制编码规则,你当前直接将base64解码后的字节转为UTF8字符串的操作无法直接拆分字段,需要直接对二进制字节数组做TLV结构解析。

1. 先定义存储发票信息的结构化类

class ZATCAInvoiceInfo {
  /// 卖家名称
  final String sellerName;
  /// 卖家VAT注册编号
  final String sellerVatNumber;
  /// 票据时间戳
  final DateTime invoiceTime;
  /// VAT总金额
  final double totalVat;
  /// 票据总金额
  final double totalInvoiceAmount;

  ZATCAInvoiceInfo({
    required this.sellerName,
    required this.sellerVatNumber,
    required this.invoiceTime,
    required this.totalVat,
    required this.totalInvoiceAmount,
  });
}

2. 编写TLV解析函数

不需要用到你之前生成的utf8data,直接处理base64解码得到的字节数组即可:

import 'dart:convert';
import 'dart:typed_data';

ZATCAInvoiceInfo parseZATCAQRCode(String qrBase64Content) {
  // 解码二维码得到的base64字符串为字节数组
  Uint8List rawBytes = base64.decode(qrBase64Content);
  int currentOffset = 0;
  Map<int, String> tlvResult = {};

  // 遍历解析TLV结构
  while (currentOffset < rawBytes.length) {
    // 读取1字节标签
    int tag = rawBytes[currentOffset];
    currentOffset += 1;
    // 读取1字节值长度
    int valueLength = rawBytes[currentOffset];
    currentOffset += 1;
    // 读取对应长度的字节转成UTF8字符串
    Uint8List valueBytes = rawBytes.sublist(currentOffset, currentOffset + valueLength);
    String value = utf8.decode(valueBytes);
    tlvResult[tag] = value;
    currentOffset += valueLength;
  }

  // 映射标签对应字段,ZATCA规范中前5个标签固定对应需求字段
  return ZATCAInvoiceInfo(
    sellerName: tlvResult[1] ?? '',
    sellerVatNumber: tlvResult[2] ?? '',
    invoiceTime: DateTime.parse(tlvResult[3] ?? ''),
    totalVat: double.tryParse(tlvResult[4] ?? '0') ?? 0.0,
    totalInvoiceAmount: double.tryParse(tlvResult[5] ?? '0') ?? 0.0,
  );
}

3. 调用示例

// qrScanResult 为你扫描二维码得到的原始base64字符串
String qrScanResult = '你的二维码扫描结果';
ZATCAInvoiceInfo invoice = parseZATCAQRCode(qrScanResult);

// 直接读取对应字段即可
debugPrint('卖家名称:${invoice.sellerName}');
debugPrint('票据总金额:${invoice.totalInvoiceAmount}');

注意事项

  • 符合ZATCA规范的合规二维码前5个标签固定为1-5,和需求字段一一对应,无需额外适配
  • 时间戳为ISO8601标准格式,可直接用DateTime.parse解析
  • 如果出现解析异常,优先检查扫描得到的base64字符串是否完整、是否为ZATCA合规发票二维码

内容的提问来源于stack exchange,提问作者mohamad kamel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 22:45:04