Developer Hub & Compliance

The Developer’s Guide to ZATCA Phase 2
QR Codes & Base64 QA Testing

How systems architects in Saudi Arabia are navigating the complex transition from Phase 1 TLV encoding to Phase 2 cryptographic hashes, and how to QA test FATOORA strings securely.

Sohail Ahmad
Sohail Ahmad Technical Guide • 12 Min Read

Let’s clear up a massive misconception immediately: You cannot generate an official Saudi e-invoice simply by typing data into an online QR code generator.

Building an offline ERP or POS system that complies with Saudi Arabia's Zakat, Tax and Customs Authority (ZATCA) is a complex software engineering endeavor. As a Systems Architect based in Riyadh who recently engineered technical solutions for offline POS systems bridging Phase 1 to Phase 2, I can tell you that the true challenge isn't rendering the QR graphic—it's the strict cryptographic logic required to generate the underlying string.

The Reality of ZATCA Compliance

If a customer scans your printed receipt with the official ZATCA mobile app and it throws an "Invalid QR Code" error, the problem is not your printer. The problem is your codebase.

ZATCA requires your ERP to take specific invoice data (Company Name, VAT Number, Timestamp, Total Amount, and VAT Amount), encode it into a precise byte array using the Tag-Length-Value (TLV) method, hash it, sign it, and finally convert that entire byte array into a Base64 string. Only then is that Base64 string converted into a QR code.

The Anatomy of TLV Encoding

In Phase 1, the requirement was relatively straightforward. You had to construct a byte array mapping 5 core tags. TLV works exactly as it sounds:

  • Tag (1 byte): The identifier (e.g., 01 for Seller Name).
  • Length (1 byte): The length of the value in bytes (e.g., 0F for 15 bytes).
  • Value (Variable): The actual UTF-8 encoded data (e.g., Mahwar KSA).
# Example Python Logic for Phase 1 TLV Encoding
def get_tlv_hex(tag: int, value: str) -> str:
    val_bytes = value.encode('utf-8')
    tag_hex = f"{tag:02x}"
    length_hex = f"{len(val_bytes):02x}"
    val_hex = val_bytes.hex()
    return tag_hex + length_hex + val_hex

The Cryptographic Shift in Phase 2 (Integration)

Phase 2 (the Integration Phase) connects your ERP directly to the FATOORA portal. The QR code generation rules became exponentially more difficult. ZATCA now requires additional tags (Tags 6-9) to guarantee the authenticity and sequence of the invoice:

  1. Tag 6 (XML Invoice Hash): A SHA-256 hash of the generated XML invoice.
  2. Tag 7 (ECDSA Signature): A cryptographic signature generated using the taxpayer's private key.
  3. Tag 8 (ECDSA Public Key): The public key corresponding to the private key used to sign the invoice.
  4. Tag 9 (Cryptographic Stamp Signature): Provided by ZATCA itself upon successful API clearance.

If your byte array is off by a single character, or if you attempt to encode the string using standard ASCII instead of strict UTF-8 hex conversions, the resulting Base64 string will be rejected by the ZATCA scanner app.

The Developer QA Testing Dilemma

When you are writing the backend logic in Odoo, Salla, or a custom Python wrapper, you will generate hundreds of test Base64 strings. To ensure your cryptography is correct, you must physically scan the resulting QR codes with the official ZATCA mobile app. But how do you rapidly test 500 Base64 strings without building your own front-end rendering tool from scratch?

Batch Testing Base64 Strings Locally

This is exactly where the BulkBarcode Generator acts as a critical sandbox for Saudi developers.

We did not build this tool to make invoices. We built it so that software engineers can rapidly QA test their ERP's output. By using our client-side workspace, your development team can bypass the hassle of writing local rendering scripts and focus purely on fixing their cryptography.

The Secure Testing Workflow:

  1. Extract the Hashes: Query your ERP database and pull a list of 500 test Base64 strings that your backend generated.
  2. Paste & Render: Paste that list directly into our "Paste SKUs" workspace. Because our engine runs entirely on WebAssembly within your browser, your proprietary hashes and internal testing data never leave your computer.
  3. Scan & Verify: The workspace instantly renders 500 high-resolution QR codes on your screen. You can take your mobile phone, open the official ZATCA app, and scan them straight off the monitor to verify your Python/JS TLV encoding is flawless.

Once your software clears QA testing, your ERP will handle the ZATCA e-invoicing automatically at the POS terminal. You can then reserve the BulkBarcode workspace for what it does best: formatting physical warehouse racking labels, GS1 tracking tags, and cold-chain logistics routing.

QA Test Your Base64 Hashes

Paste your ERP's Base64 output into our secure, client-side rendering engine to instantly generate scannable QR codes for FATOORA testing.

6. 仓库贴标常见问题解答

Can I use this tool to generate official ZATCA invoices?
No. ZATCA compliance requires an integrated ERP/POS system to cryptographically sign the XML invoice and push it to the FATOORA portal. Our tool is designed for developers to securely batch-render and QA test the resulting Base64 strings to ensure their encoding logic is readable by the official ZATCA scanner app.
Why does the official ZATCA app say my QR code is invalid?
This usually indicates a flaw in your TLV (Tag-Length-Value) encoding logic or a failure to correctly convert the byte array into a Base64 string before generating the QR code. Pay special attention to your hex conversions.
Is it secure to paste my invoice hashes into an online generator?
Using standard online generators is risky. However, our BulkBarcode workspace utilizes a 100% Client-Side WebAssembly rendering engine. Your Base64 hashes and proprietary TLV data never leave your local browser, making it completely secure for enterprise testing.
Sohail Ahmad

Sohail Ahmad

首席系统架构师与高级平面设计师

Operating out of Riyadh, Saudi Arabia, Sohail bridges the critical gap between digital software architecture and physical logistics. He specializes in full-scale e-commerce automation, offline POS compliance, and engineering B2B generation workflows for international brands and regional 3PLs.

Need help? Chat with Burt 👋