Structure of the QR code For Electronic Tax Invoices
It is mandatory to generate and print QR code encoded in Base64 format with up to 700 characters that must contain the fields specified in the below table as per Annex (2) of the Controls, Requirements, Technical Specifications and Procedural Rules for Implementing the Provisions of the E-Invoicing Regulation.
The QR code fields shall be encoded in Tag-Length-Value (TLV) format with the tag values specified in the “Tag” column of the adjacent table.
The TLV encoding shall be as follows:
● Tag: The tag value as mentioned above stored in one byte.
● Length: The length of the byte array resulted from the UTF8 encoding of the field value. The length shall be stored in one byte.
● Value: The byte array resulting from the UTF8 encoding of the field value.
Field Definition for the QR Code
Description |
Tag |
Enforcement date |
Seller’s name |
1 |
December 4th, 2021 |
VAT registration number of the seller |
2 |
|
Time stamp of the invoice (date and time) |
3 |
|
Invoice total (with VAT) |
4 |
|
VAT total |
5 |
|
Hash of XML invoice |
6 |
Starting Jan 1st, 2023 in waves |
ECDSA signature |
7 |
|
ECDSA public key |
8 |
|
For Simplified Tax Invoices and their associated notes, the ECDSA signature of the cryptographic stamp’s public key by ZATCA’s technical CA |
9 |
6.1 TLV - TAG - LENGTH - VALUE construction and file format
● QR code is the base64 encoded TLV (Tag, Length, Value)
● Type/Tag-Length-Value (TLV) is an encoding scheme used in many communication protocols to encode data. A TLV-encoded message has a defined structure which consists of 3 sections/parts, see Figure (1). Those are:
● Code of the message type (T) - 1 Byte
● Message value length (L) - 1 Byte
● Message value itself. (V) - Variable
● The Tag/Type and Length are of fixed sizes of 1 bytes while the value has a variable size.
● As the general idea behind encoding is to transform abstract data into a stream of bits, using TLV, there are different sets of encoding rules that can be used according to the Abstract Syntax Notation Version 1 (ASN.1). We are using a simple version of Basic Encoding Rules (BER).
6.2 Creation of TLV QR code
Description |
Tag |
Length |
Value |
Hex |
Seller’s name |
1 |
23 |
Ahmed Mohamed AL Ahmady |
41 68 6d 65 64 20 4d 6f 68 61 6d 65 64 20 41 4c 20 41 68 6d 61 64 79 |
VAT registration number of the seller |
2 |
15 |
301121971500003 |
33 30 31 31 32 31 39 37 31 35 30 30 30 30 33 |
Time stamp of the invoice (date and time) |
3 |
20 |
2022-03-13T14:40:40Z |
32 30 32 32 2d 30 33 2d 31 33 54 31 34 3a 34 30 3a 34 30 5a |
Invoice total (with VAT) |
4 |
6 |
1108.90 |
31 31 30 38 2e 39 30 |
VAT total |
5 |
45 |
114.90 |
31 31 34 2e 39 30 |
Hash of XML invoice |
6 |
44 |
QnVEexW4nWv4CaE39a/ 66Jp/ OXO/evHQ8pDl- G7weq/4= |
51 6e 56 45 65 78 57 34 6e 57 76 34 43 61 45 33 39 61 2f 36 36 4a 70 2f 4f 58 4f 2f 65 76 48 51 38 70 44 6c 47 37 77 65 71 2f 34 3d 20 |
ECDSA signa- ture |
7 |
192 |
4d 45 55 43 49 51 44 35 7a 78 79 58 4f 42 37 4e 76 57 66 36 32 72 56 45 5a 41 59 55 37 31 6a 70 79 39 48 45 45 6e 5a 30 71 39 4f 39 36 77 72 4c 36 51 49 67 51 4a 7a 43 47 48 62 77 36 59 42 48 4c 59 56 64 4f 31 77 6e 55 68 42 67 4b 6d 38 6a 4d 54 79 76 63 6b 39 4d 2b 72 50 39 78 59 59 3d |
4d 45 55 43 49 51 44 35 7a 78 79 58 4f 42 37 4e 76 57 66 36 32 72 56 45 5a 41 59 55 37 31 6a 70 79 39 48 45 45 6e 5a 30 71 39 4f 39 36 77 72 4c 36 51 49 67 51 4a 7a 43 47 48 62 77 36 59 42 48 4c 59 56 64 4f 31 77 6e 55 68 42 67 4b 6d 38 6a 4d 54 79 76 63 6b 39 4d 2b 72 50 39 78 59 59 3d |
ECDSA public key |
8 |
48 |
30 56 30 10 06 07 2a ef bf bd 48 ef bf bd 3d 02 01 06 05 2b ef bf bd 04 |
30 56 30 10 06 07 2a ef bf bd 48 ef bf bd 3d 02 01 06 05 2b ef bf bd 04 |
For Simplified Tax Invoices and their asso- ciated notes, the ECDSA signature of the cryptographic stamp’s public key by ZATCA’s technical CA |
9 |
144 |
30 46 02 21 00 ee 61 d3 eb 28 3c e6 3b 50 19 6a 77 33 bb 4f 4f b2 64 db ec ec bd 51 c6 b3 76 d4 e5 9e d8 13 af 02 21 00 fa d1 e6 d0 6a 66 23 62 f7 5e 6e 71 63 35 fc 78 5f 87 68 a7 b2 ec 10 11 42 35 2b 0b 63 42 05 69 |
30 46 02 21 00 ee 61 d3 eb 28 3c e6 3b 50 19 6a 77 33 bb 4f 4f b2 64 db ec ec bd 51 c6 b3 76 d4 e5 9e d8 13 af 02 21 00 fa d1 e6 d0 6a 66 23 62 f7 5e 6e 71 63 35 fc 78 5f 87 68 a7 b2 ec 10 11 42 35 2b 0b 63 42 05 69 |
XML Elements for QR code:
Description |
Tag |
XML element |
Tag1 |
Seller׳s name |
/Invoice/cac:AccountingSupplierParty/ cac:Party/cac:PartyLegalEn- tity /cbc:RegistrationName |
Tag2 |
VAT registration number of the seller |
/Invoice/cac:AccountingSupplierParty /cac:Party/cac:PartyTax- Scheme/ cbc:CompanyID |
Tag3 |
Time stamp of the invoice (date and time) |
Date Xpath /Invoice/cbc:IssueDate Time xpath /Invoice/cbc:Issue- Time Issue date combination between issue date and issue time, expression sample from the invoice yyyy-MM-dd׳T׳HH:mm:ss׳Z׳ |
Tag4 |
Invoice total (with VAT) |
/Invoice/cac:LegalMonetaryTotal /cbc:TaxInclusiveAmount |
Tag5 |
VAT total |
/Invoice/cac:TaxTotal/cbc:TaxAmount |
Tag6 |
Hash of XML invoice |
Invoice/ext:UBLExtensions /ext:UBLExtension/ext:ExtensionCon- tent /sig:UBLDocumentSignatures /sac:SignatureInformation /ds:Signature/ds:SignedInfo /ds:Reference/ds:DigestValue |
Tag7 |
ECDSA signature |
/Invoice/ext:UBLExtensions/ext: UBLExtension/ext:ExtensionCon- tent /sig:UBLDocumentSignatures /sac:SignatureInformation/ds:Sig- nature /ds:SignatureValue |
Tag8 |
ECDSA public key |
/Invoice/ext:UBLExtensions/ext:UBLExtension /ext:ExtensionCon- tent /sig:UBLDocumentSignatures /sac:SignatureInformation /ds:Signature/ds:KeyInfo /ds:X509Data/ds:X509Certificate |
Tag9 |
For Simplified Tax Invoices and their associated notes, the ECDSA signature of the cryptographic stamp’s public key by ZATCA’s technical CA |
/Invoice/UBLExtensions/ UBLExtension/ExtensionContent /UBLDocumentSignatures /SignatureInformation/Signature /KeyInfo/X509Data/X509Certificate |
The hex representation: TLV
01 17 41 68 6d 65 64 20 4d 6f 68 61 6d 65 64 20 41 4c 20 41 68 6d 61 64 79 02 0f 33 30 31 31
32 31 39 37 31 35 30 30 30 30 33 03 14 32 30 32 32 2d 30 33 2d 31 33 54 31 34 3a 34 30 3a 34
30 5a 04 07 31 31 30 38 2e 39 30 05 05 31 34 34 2e 39 06 2c 51 6e 56 45 65 78 57 34 6e 57 76
34 43 61 45 33 39 61 2f 36 36 4a 70 2f 4f 58 4f 2f 65 76 48 51 38 70 44 6c 47 37 77 65 71 2f 34
3d 07 60 4d 45 55 43 49 51 44 35 7a 78 79 58 4f 42 37 4e 76 57 66 36 32 72 56 45 5a 41 59 55
37 31 6a 70 79 39 48 45 45 6e 5a 30 71 39 4f 39 36 77 72 4c 36 51 49 67 51 4a 7a 43 47 48 62 77
36 59 42 48 4c 59 56 64 4f 31 77 6e 55 68 42 67 4b 6d 38 6a 4d 54 79 76 63 6b 39 4d 2b 72 50
39 78 59 59 3d 08 58 30 56 30 10 06 07 2a 86 48 ce 3d 02 01 06 05 2b 81 04 00 0a 03 42 00
04 61 83 0c a0 e6 85 60 08 4c 3b fb 2d 7a 8b 5f 67 26 af af aa 75 d5 24 a5 c2 c2 bd 6b 39 ac 2d
8e db d5 bf 85 2e 1a 8c 02 b8 41 d9 da 87 29 ba 31 a8 a3 5f be 42 83 78 f8 69 aa 3b a2 e6 17 27
d1 09 48 30 46 02 21 00 ee 61 d3 eb 28 3c e6 3b 50 19 6a 77 33 bb 4f 4f b2 64 db ec ec bd 51 c6
b3 76 d4 e5 9e d8 13 af 02 21 00 fa d1 e6 d0 6a 66 23 62 f7 5e 6e 71 63 35 fc 78 5f 87 68 a7 b2
ec 10 11 42 35 2b 0b 63 42 05 69
Field Definition for the QR Code
ARdBaG1lZCBNb2hhbWVkIEFMIEFobWFkeQIPMzAxMTIxOTcxNTAwMDAzAxQyMDIyLT- AzLTEzVDE0OjQwOjQwWgQHMTEwOC45MAUFMTQ0LjkGLFFuVkVleFc0bld2NENhRT- M5YS82NkpwL09YTy9ldkhROHBEbEc3d2VxLzQ9B2BNRVVDSVFENXp4eVhPQj-
dOdldmNjJyVkVaQVlVNzFqcHk5SEVFblowcTlPOTZ3ckw2UUlnUUp6Q0dIYnc2WUJIT- FlWZE8xd25VaEJnS204ak1UeXZjazlNK3JQOXhZWT0IWDBWMBAGByqGSM49AgEGB-
SuBBAAKA0IABGGDDKDmhWAITDv7LXqLX2cmr6+qddUkpcLCvWs5rC2O29W/ hS4ajAK4Qdnahym6MaijX75Cg3j4aao7ouYXJ9EJSDBGAiEA7mHT6yg85jtQGWp3M7tPT7Jk2+zsv- VHGs3bU5Z7YE68CIQD60ebQamYjYvdebnFjNfx4X4dop7LsEBFCNSsLY0IFaQ==
In order to get the value for Tag9 i.e. the Digital Signature of the Certificate please follow the steps below:
- Get a hold of your device’s PCSID (You get this once you have successfully onboarded the device)
- Decode the PCSID. One available online tool is: CSR Decoder and Certificate Decoder | CSR Checker | Certificate Checker
You should get results that look like the diagram below:
- Copy the value of “Signature Algorithm: ecdsa-with-SHA256”
- Populate the value from step three as the value for Tag9 in the QR
6.3 Common mistakes in building the QR code
● Tag and Length are binary values, converted to Hex EXAMPLE: 21 should be represented as 15 in Hex, if the string is converted it becomes 32 31 (1 and 5)
● Value must also be converted to Hex before encoding to Base64
● There should be no padding or separators between the TLV sets in the resulting file
● Not using UTF8 Encoding for Arabic Text
6.4 Manual decoding a TLV QR Code
The QR code can be Extracted and Converted to Hex using publicly available tools
Step 1: Example Base64 Encode QR Code, extracted using QR Code reader (i.e. Mobile Phone):
ARVCb2JzIEJhc2VtZW50IFJlY29yZHMCDzEwMDAyNTkwNjcwMDAwMwMUMjAyMi0wN- C0yNVQxNTozMDowMFoECjIxMDAxMDAuOTkFCTMxNTAxNS4xNQ==
Step 2: Decode this to a hex representation, this can be done at the following site: cryptii
01 15 42 6f 62 73 20 42 61 73 65 6d 65 6e 74 20 52 65 63 6f 72 64 73 02 0f 31 30 30 30 32 35
39 30 36 37 30 30 30 30 33 03 14 32 30 32 32 2d 30 34 2d 32 35 54 31 35 3a 33 30 3a 30 30
5a 04 0a 32 31 30 30 31 30 30 2e 39 39 05 09 33 31 35 30 31 35 2e 31 35
Step 3: Hex Representation can be read by a TLV reader, i.e. : emvlab
Step 4: UTF8 Encoded values can be read using an online tool, i.e. : onlineutf8tools
Using a TLV Decoder to split the record shows the Hex Values, these can then be decoded using a hex to string decoder
Tag |
Hex Value |
Hex to string |
Seller׳s name |
426F627320426173656D656E7420 5265636F726473 |
Bobs Basement Records |
VAT registration number of the seller |
31303030323539303 6373030303033 |
100025906700003 |
Time stamp of the invoice (date and time) |
323032322D30342D32355431353 A33303A30305A |
2022-04-25T15:30:00Z |
Invoice total (with VAT) |
323130303130302E3939 |
2100100.99 |
VAT total |
3331353031352E3135 |
315015.15 |
6.5 Creation of QR code in JAVA - Javascript - nodeJS
This function takes in 2 args:
● tagNum: Tag Number
● tagValue: Value of Message
You do the previous steps for each of the Tags you want to add to the QR code. For example, here we have sellerName, VatReg, etc.
Dart - Use the BytesBuilder class to add each segment of each TLV message i.e. 3 per message. We repeat for each message we want to add to the QR Code
Once all messages are added to the builder, convert it into bytes (see 1) which gives you Uint8List (Darts way of byte ), then encode the list into Base64 using an instance of the Base64Encoder class (see 2).
Representation of the QR code Data Examples:
SDK validation
The QR code can be validated using SDK available on ZATCA’s website (https://zatca.gov.sa/en/E-Invoicing/SystemsDevelopers/ComplianceEnablementToolbox/Pages/DownloadSDK.aspx).
Command line | Results |
---|---|
fatoorah - v | To display (Version) |
fatoorah - h | Help window |
fatoorah validateqr -qr | Validate QR code structure |
fatoorah generate -f (Invoicename.xml) -q | Generate compliant QR code |