ZATCA QR code explained: the 9 TLV fields, Phase 1 vs Phase 2, and how to check one

By Zain Abbas, Kodenova · Updated

Short answerA ZATCA QR code is a Base64 string built from TLV (tag, length, value) fields. Phase 1 needs 5 tags: seller name, VAT number, timestamp, invoice total with VAT and VAT total. Phase 2 adds the invoice hash, the ECDSA signature and public key, and for simplified (B2C) invoices a ninth tag with ZATCA's signature over the stamp. You can check one by decoding the Base64 and reading each tag.

What the QR code actually is

The QR code on a Saudi e-invoice is not a link and not a picture of the invoice. It is a short block of data, encoded in Base64, that a phone can read without going online.

The data inside uses a format called TLV: Tag, Length, Value. Every field is written as three parts, one after the other:

  • Tag: one byte that says which field this is (1 for seller name, 2 for VAT number, and so on).
  • Length: one byte that says how many bytes the value takes.
  • Value: the field itself, encoded in UTF-8.

All fields are joined with no spaces or separators, and the whole byte string is then Base64 encoded. ZATCA’s technical guideline sets a limit of 700 characters for the final Base64 string.

The 9 TLV fields

TagFieldExample valuePhase
1Seller nameAl Noor TradingPhase 1 and 2
2Seller VAT registration number300000000000003Phase 1 and 2
3Invoice timestamp (date and time)2026-10-16T10:15:00ZPhase 1 and 2
4Invoice total with VAT1150.00Phase 1 and 2
5VAT total150.00Phase 1 and 2
6Hash of the XML invoiceSHA-256 hashPhase 2
7ECDSA signature of the hashcryptographic valuePhase 2
8ECDSA public keycryptographic valuePhase 2
9ZATCA’s signature over the stamp’s public keycryptographic valuePhase 2, simplified invoices and their notes only

Tags 1 to 5 are plain text you can read. Tags 6 to 9 are cryptographic data, so a decoder shows them as encoded strings, not words.

The invoice hash in tag 6 is a SHA-256 hash of the XML invoice. ZATCA’s security standard explains that the hash excludes the UBL extensions, the signature block and the QR element itself, which makes sense: the QR cannot contain a hash of itself.

Phase 1 vs Phase 2

ZATCA rolled out e-invoicing in two phases, and the QR code changed with them.

Phase 1 (generation) started on 4 December 2021. Invoices had to be produced by a compliant system, and simplified tax invoices (B2C) had to carry a QR code with the five basic fields. ZATCA’s Detailed Guidelines say plainly that a QR code was not mandated on standard tax invoices (B2B) in this phase.

Phase 2 (integration) started on 1 January 2023 and is being applied in waves. Taxpayers are brought in by revenue threshold. If your company is in the latest group, see our note on Wave 25 for SAP Business One. In Phase 2 the QR code gains tags 6 to 9, and the rules depend on the invoice type:

Standard tax invoice (B2B)Simplified tax invoice (B2C)
ZATCA flowClearance, before the invoice goes to the buyerReporting, within 24 hours of issue
Who stamps the invoiceZATCA, during clearanceYour system, with its own CSID
QR codeAdded or updated by ZATCA in the clearance responseGenerated by your system with all 9 tags
Tag 9Not usedRequired

The practical point for B2B: your printed or PDF invoice should use the QR code that comes back from ZATCA after clearance, not one your system made before sending. For B2C, your system builds the full QR itself at the moment of sale.

A worked example

Here is a Phase 1 style QR string for an invoice of SAR 1,000 plus 15% VAT, built from the example values in the table above:

AQ9BbCBOb29yIFRyYWRpbmcCDzMwMDAwMDAwMDAwMDAwMwMUMjAyNi0xMC0xNlQxMDoxNTowMFoEBzExNTAuMDAFBjE1MC4wMA==

If you decode the first bytes you see 01 0F followed by the seller name. 01 is tag 1. 0F is 15 in hex, the number of bytes in “Al Noor Trading”. Then comes 02 0F and the 15-digit VAT number, and so on through tag 5.

Paste that string into our free ZATCA QR code decoder and you will see the five fields laid out one by one.

How to check a QR code on your invoice

Use this when a customer complains that their scanner shows “invalid QR”, or when you test a new invoice layout.

  1. Get the raw string. Scan the printed QR with any scanner app, or copy the value stored on the invoice record in your ERP.
  2. Decode it. Run it through a TLV decoder. If the decoder fails at once, the string is probably not Base64, or extra characters were added (spaces, line breaks, a URL prefix).
  3. Compare tags 1 to 5 with the invoice. Seller name and VAT number must match your VAT registration. Tag 4 must equal the invoice total including VAT. Tag 5 must equal the total VAT on the invoice.
  4. Check the timestamp. Tag 3 should match the invoice issue date and time. A timestamp from a different day usually means the QR was built from the wrong field.
  5. Count the tags. A Phase 2 simplified invoice should show 9 tags. A cleared standard invoice should carry the QR returned by ZATCA. If you see only 5 tags on a Phase 2 invoice, your layout is printing an old Phase 1 value.
  6. Check the length. The Base64 string should be at most 700 characters.

Decoding confirms the structure and the readable fields. It does not prove that the signature in tags 7 and 9 is genuine. That check needs the signed XML and ZATCA’s own validation, which is done in the SDK or by the platform during clearance and reporting.

Common QR mistakes

ZATCA’s technical guideline lists a few errors that come up again and again. We see the same ones when we review invoice layouts:

  • Arabic seller name not in UTF-8. The name scans as question marks or broken characters.
  • Length counted in characters, not bytes. An Arabic name of 10 letters is about 20 bytes. If the length byte says 10, every tag after it is read wrong.
  • Separators between fields. Commas, spaces or padding between TLV sets break the decode. There must be none.
  • Amounts that do not match the invoice. Often the QR is built from the subtotal, or from figures before a document-level discount.
  • Printing the wrong QR on B2B invoices. In Phase 2, the cleared QR from ZATCA should be the one on the document.

In SAP Business One, the QR value is normally stored on the A/R invoice (in a user-defined field or the e-document data) and printed through Crystal Reports or the Print Layout Designer as a barcode or image. When the printed code fails, check the stored value first with a TLV decoder. If the stored value is correct, the problem is in the layout, not the integration.

Where this fits in Phase 2

The QR code is the visible end of a longer process: UBL 2.1 XML, hashing, signing with your CSID, and clearance or reporting through ZATCA’s APIs. If any of those steps is wrong, the QR is usually wrong too. Our ZATCA e-invoicing guide covers the full flow, and the Saudi VAT calculator helps when you need to double-check tags 4 and 5 by hand.

If your SAP Business One invoices print a QR code that customers or ZATCA reject, send us a sample and we will tell you which part is failing.

Sources

Related services

FAQ

Frequently asked questions

How many fields are in a ZATCA QR code?

Up to nine. Tags 1 to 5 hold the seller name, seller VAT number, invoice timestamp, total with VAT and VAT total. Tags 6 to 8 hold the XML invoice hash, the ECDSA signature and the ECDSA public key. Tag 9 is only for simplified invoices and their notes.

Is a QR code required on B2B (standard) tax invoices?

In Phase 1 (generation) it was required only on simplified tax invoices. In Phase 2 (integration), standard tax invoices get their QR code during clearance, when ZATCA's platform stamps the invoice and returns it with the QR code.

What is the maximum length of a ZATCA QR code?

ZATCA's technical guideline says the QR code is encoded in Base64 with up to 700 characters. Each TLV value also has a one-byte length, so a single field cannot be longer than 255 bytes.

Why does my ZATCA QR code show broken Arabic text when scanned?

Usually the seller name was not encoded in UTF-8 before building the TLV, or the length byte was calculated on characters instead of bytes. Arabic letters take two bytes each in UTF-8, so the length must count bytes.

Can a QR scanner app tell me if the invoice is valid?

A normal scanner only shows the Base64 text. A TLV decoder shows the fields so you can compare them with the invoice. Proving the signature is genuine needs the signed XML and ZATCA's validation tools, not the QR code alone.

Ready to get started?

Tell us what you need. You get a clear technical answer, a fixed scope and a price, usually within 24 hours.