Application Development and Automation Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
Firoz_Ashraf
Contributor
66,100
As per Zakat, Tax and Customs Authority (ZATCA) of Saudi Arabia, one of the main requirements is the implementation of QR codes on tax invoices in the e-invoicing project (Fatoora), which will be mandatory starting December 4, 2021

As per the ZATCA instructions(Page No. 23), the minimum requirements that must be shown after scanning a QR code are the following fields, which should be represented in form of based64 encoding:

  1. Seller’s name.

  2. VAT registration number of the seller.

  3. Time stamp of the invoice (date and time).

  4. Invoice total (with VAT).

  5. VAT total.


In this blog,  I will show how to encode the QR data in base64 format using ABAP and then using it in SAPScript/SmartForms to print QR code on Invoice layouts.

1st Step is to prepare each of the five values in TLV (Tag-Length-Value) structure

Tag is fixed (1 for Seller's name, 2 for VAT No......5 for VAT Total)

Length is the size of the value field in bytes (it’s not the count of characters but how many bytes the value represents)

Value is the data against each of the five fields.

Let's take an example to clarify TLV



    1. Seller name; for example, “Firoz Ashraf

      • Tag      = 1 (1 as a type represents the seller name)

      • Length = 12 (The number of the bytes in “Firoz Ashraf” word)

      • Value   = Firoz Ashraf



    2. VAT Number; for example, 1234567891

      • Tag      = 2 (2 as a type represents the VAT number)

      • Length = 10

      • Value   = 1234567891



    3. Time Stamp; for example, 2021-11-17 08:30:00

      • Tag      = 3 (3 as a type represents invoice time stamp)

      • Length = 19

      • Value   = 2021-11-17 08:30:00



    4. Invoice Total; for example, 100.00

      • Tag      = 4 (4 as a type represents the invoice amount)

      • Length = 6

      • Value   = 100.00



    5. VAT Total; for example, 15.00

      • Tag      = 5 (5 as a type represents the tax amount)

      • Length = 5

      • Value   = 15.00






 

2nd Step is to convert 'Tag' and 'Length' to Hexadecimal and then to string. Then concatenate these two strings with 'Value' (stored as string)

concatenate all the five TLVs into one string

'##Firoz Ashraf##1234567891##2021-11-17 08:30:00##115.00##15.00'

 

3rd Step is to convert the concatenated string to Base64 format

From the above example we get the following Base64 encoded value

AQxGaXJveiBBc2hyYWYCCjEyMzQ1Njc4OTEDEzIwMjEtMTEtMTcgMDg6MzA6MDAEBjExNS4wMAUFMTUuMDA=

Now let's see how we can do this in ABAP

To get the 'Length' in the TLV structure, we will use the Function Module SCMS_STRING_TO_XSTRING to convert the text to xString and then we will use xstrlen to get the length.
FORM tag_length  USING    p_string
CHANGING p_length.
DATA: v_xstr TYPE xstring.
*First Convert string to xString
CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
EXPORTING
text = p_string
* MIMETYPE = ' '
* ENCODING =
IMPORTING
buffer = v_xstr
EXCEPTIONS
failed = 1
OTHERS = 2.
IF sy-subrc <> 0.
* Implement suitable error handling here
ELSE.
p_length = xstrlen( v_xstr ).
ENDIF.

ENDFORM.

To convert the string to Base64 we have two ways in ABAP:

The first one is using Class CL_HTTP_UTILITY method ENCODE_BASE64

The second one is using Function Module SCMS_STRING_TO_XSTRING to Convert String to Xstring and the using another Function Module SCMS_BASE64_ENCODE_STR to Convert the Xstring to Base64.

You can choose either of the ways (either Class or FM)

I have used the Class method to convert string to Base64.

To start with, I created a custom FM which takes invoice number as input and gives QR code values in text as well as in Base64.

I use this FM in SAPScript/SmartForms to print the QR Code.
FUNCTION z_einvoice_base64_qrcode_value.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" REFERENCE(INVOICE_NO) TYPE VBELN_VF
*" EXPORTING
*" REFERENCE(QRCODE_STRING) TYPE STRING
*" REFERENCE(QRCODE_BASE64) TYPE STRING
*" EXCEPTIONS
*" NO_INVOICE
*" XSTR_ERROR
*"----------------------------------------------------------------------
*-----------------------------------------------------------------------
* The QR code fields shall be encoded in Tag-Length-Value (TLV) format
* The TLV encoding shall be as follows:
* Tag : the tag value (1 to 5) stored in one byte
* Length : the length of the byte array resulted from the UTF8 encoding of the field value.
* Value : the byte array resulting from the UTF8 encoding of the field value.
*----------------------------------------------------------------------
DATA: wa_vbrk TYPE vbrk,

v_t1_cname TYPE string,
v_t2_vatno TYPE string, v_date(10), v_time(8),
v_t3_tstmp TYPE string,
v_t4_invamt TYPE vbrk-netwr, v_t4_invamx TYPE string,
v_t5_vatamt TYPE vbrk-netwr, v_t5_vatamx TYPE string,

v_t1_len TYPE i,v_t2_len TYPE i,v_t3_len TYPE i,
v_t4_len TYPE i,v_t5_len TYPE i,

v_t1_lenx TYPE xstring,v_t2_lenx TYPE xstring,v_t3_lenx TYPE xstring,
v_t4_lenx TYPE xstring,v_t5_lenx TYPE xstring,

v_t1_lent TYPE string,v_t2_lent TYPE string,v_t3_lent TYPE string,
v_t4_lent TYPE string,v_t5_lent TYPE string,

v_t1_tag TYPE string, v_t2_tag TYPE string, v_t3_tag TYPE string,
v_t4_tag TYPE string, v_t5_tag TYPE string.

SELECT SINGLE * FROM vbrk INTO wa_vbrk
WHERE vbeln = invoice_no.
IF sy-subrc = 0.
* Company Name & VAT No.
SELECT SINGLE butxt stceg FROM t001 INTO ( v_t1_cname, v_t2_vatno )
WHERE bukrs = wa_vbrk-bukrs.
* Invoice Time Stamp
CONCATENATE wa_vbrk-fkdat(4) '-' wa_vbrk-fkdat+4(2) '-' wa_vbrk-fkdat+6(2)
INTO v_date.
CONCATENATE wa_vbrk-erzet(2) ':' wa_vbrk-erzet+2(2) ':' wa_vbrk-erzet+4(2)
INTO v_time.
CONCATENATE v_date v_time INTO v_t3_tstmp SEPARATED BY space.
* Invoice Total (with VAT)
v_t4_invamt = wa_vbrk-netwr + wa_vbrk-mwsbk.
v_t4_invamx = v_t4_invamt. CONDENSE v_t4_invamx.
* VAT Total
v_t5_vatamt = wa_vbrk-mwsbk.
v_t5_vatamx = v_t5_vatamt. CONDENSE v_t5_vatamx.

**********Tag & Length (T&L from TLV) should be first converted to
* Hexadecimal format then it should be converted to string.
* Finally these two strings should be concatenated with 'Value' (of TLV).
* Since tags are 1 to 5. We take the hexa values as 01 to 05

PERFORM convert_hex_to_str USING '01' CHANGING v_t1_tag.
PERFORM convert_hex_to_str USING '02' CHANGING v_t2_tag.
PERFORM convert_hex_to_str USING '03' CHANGING v_t3_tag.
PERFORM convert_hex_to_str USING '04' CHANGING v_t4_tag.
PERFORM convert_hex_to_str USING '05' CHANGING v_t5_tag.

PERFORM tag_length USING v_t1_cname CHANGING v_t1_len.
v_t1_lenx = v_t1_len. " Convert to hexadecial value
PERFORM convert_hex_to_str USING v_t1_lenx CHANGING v_t1_lent.

PERFORM tag_length USING v_t2_vatno CHANGING v_t2_len.
v_t2_lenx = v_t2_len.
PERFORM convert_hex_to_str USING v_t2_lenx CHANGING v_t2_lent.

PERFORM tag_length USING v_t3_tstmp CHANGING v_t3_len.
v_t3_lenx = v_t3_len.
PERFORM convert_hex_to_str USING v_t3_lenx CHANGING v_t3_lent.

PERFORM tag_length USING v_t4_invamx CHANGING v_t4_len.
v_t4_lenx = v_t4_len.
PERFORM convert_hex_to_str USING v_t4_lenx CHANGING v_t4_lent.

PERFORM tag_length USING v_t5_vatamx CHANGING v_t5_len.
v_t5_lenx = v_t5_len.
PERFORM convert_hex_to_str USING v_t5_lenx CHANGING v_t5_lent.

***************Concatenate all TLV data********************
CONCATENATE v_t1_tag v_t1_lent v_t1_cname
v_t2_tag v_t2_lent v_t2_vatno
v_t3_tag v_t3_lent v_t3_tstmp
v_t4_tag v_t4_lent v_t4_invamx
v_t5_tag v_t5_lent v_t5_vatamx
INTO qrcode_string.

***************Encode String to Base64*********************
CALL METHOD cl_http_utility=>if_http_utility~encode_base64
EXPORTING
unencoded = qrcode_string
RECEIVING
encoded = qrcode_base64.
ELSE.
RAISE no_invoice.
ENDIF.

ENDFUNCTION.

 

PERFORM convert_hex_to_str
*&---------------------------------------------------------------------*
*& Form CONVERT_HEX_TO_STR
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->P_HEX text
* <--P_STR text
*----------------------------------------------------------------------*
FORM convert_hex_to_str USING p_hex
CHANGING p_str.
* CALL FUNCTION 'HR_RU_CONVERT_HEX_TO_STRING'
* EXPORTING
* xstring = p_hex
* IMPORTING
* cstring = p_str.

**Note: Above FM was sometimes not giving correct **
** conversion. Hence we have changed it to **
** class based explicitly using UTF-8 **

DATA: loc_conv TYPE REF TO cl_abap_conv_in_ce.

CALL METHOD cl_abap_conv_in_ce=>create
EXPORTING
input = p_hex
encoding = 'UTF-8'
replacement = '?'
ignore_cerr = abap_true
RECEIVING
conv = loc_conv.

TRY.
CALL METHOD loc_conv->read
IMPORTING
data = p_str.
CATCH cx_sy_conversion_codepage.
*-- Should ignore errors in code conversions
CATCH cx_sy_codepage_converter_init.
*-- Should ignore errors in code conversions
CATCH cx_parameter_invalid_type.
CATCH cx_parameter_invalid_range.
ENDTRY.ENDFORM.

Setting up the QR Code font 

Using SE73, create a new 'System Bar Code'


Once this is done, create a Character format say QR in your SAPScript using the Bar Code (QR Code) created above.


You can then use this in your Window


Here I am calling the subroutine ZEDOC_KSA_QRBASE64 in ABAP program ZSDLINCLUDE which actually has our custom FM Z_EINVOICE_BASE64_QRCODE_VALUE

Note that a single text variable in SAPScript has a capacity to hold 80 characters and our QR code value is more than 80 hence I had to spilt the values in two variables V_QRCODE1 & V_QRCODE2.
FORM zedoc_ksa_qrbase64 TABLES in_tab STRUCTURE itcsy
out_tab STRUCTURE itcsy.
DATA: v_vbeln TYPE vbeln,
v_qrb64 TYPE string,
v_len TYPE i,
v_rem TYPE i.

READ TABLE in_tab INDEX 1.
IF sy-subrc = 0.
v_vbeln = in_tab-value.
CALL FUNCTION 'Z_EINVOICE_BASE64_QRCODE_VALUE'
EXPORTING
invoice_no = v_vbeln
IMPORTING
* QRCODE_STRING =
qrcode_base64 = v_qrb64
EXCEPTIONS
no_invoice = 1
xstr_error = 2
OTHERS = 3.
IF sy-subrc <> 0.
* Implement suitable error handling here
ELSE.
v_len = strlen( v_qrb64 ).

READ TABLE out_tab INDEX 1.
IF sy-subrc = 0.
IF v_len GT 80. "Split into two variables
out_tab-value = v_qrb64(80).
v_rem = v_len - 80.
MODIFY out_tab INDEX 1.CLEAR out_tab.
READ TABLE out_tab INDEX 2.
IF sy-subrc = 0.
out_tab-value = v_qrb64+80(v_rem).
MODIFY out_tab INDEX 2.CLEAR out_tab.
ENDIF.
ELSE.
out_tab-value = v_qrb64.
MODIFY out_tab INDEX 1.CLEAR out_tab.
ENDIF.
ENDIF.
ENDIF.
ENDIF.
ENDFORM.

After doing this when you call the layout you will get the QR Code


If you scan this QR code then you will get the the following Base64 coded text

AQxGaXJveiBBc2hyYWYCCjEyMzQ1Njc4OTEDEzIwMjEtMTEtMTcgMDg6MzA6MDAEBjExNS4wMAUFMTUuMDA=

When decoded this will give the following text value (as shown below )


You may go through the following blogs and links which were quite helpful in getting the pieces together.

  1. https://blogs.sap.com/2019/03/29/base64-function-modules-in-sap-abap/

  2. https://sapintegrationhub.com/abap/base64/base64-encoding-and-decoding-in-sap-abap/

  3. https://blogs.sap.com/2020/10/12/display-qr-code-for-gst-india-e-invoicing-on-script-and-smartform/

  4. https://salla.dev/blog/qr-code-fatoora-e-invoicing-zatca/

  5. https://www.textencode.com/decoder/decodeBase64


Note: if you have set up EDOC_COCKPIT then you can directly get the QR code data in base64 encoding without bothering about TLV conversion. You may follow my another blog where I have explained how you can use the data stored in field QR_CODE from table EDOSAINV.

Enjoy coding !!

Firoz Ashraf.

 
112 Comments
ido_millet
Active Contributor
0 Likes

Nice job. If you use Crystal Reports, my CUT Light UFL (User Function Library) provides a uflZatcaEncode() function, allowing you to generate the encoding and pass it to a uflBBarcodeQR() function to generate the QR Code (without a dependency on special fonts):

Nawazuddin
Explorer
0 Likes
Brother Ashraf,

 

using the above code I am unable to  print  QR code with  arabic text "الجواهري العربي"   my base64 is comming like this.

 

Base64>AR3Yp9mE2KzZiNin2YfYsdmKINin2YTYudix2KjZigIPMzEwMTIyMzkzNTAwMDAzAxMyMDIxLTExLTE3IDA4OjMwOjAwBAcxMDAwLjAwBQYxNTAuMDA=

after decode:الجواهري العربي3101223935000032021-11-17 08:30:001000.00150.00

and Adobe not generating QR code   with english text every thing  fine.

 

Thanks in advance for your support and help.

 

 

 

 
Sandra_Rossi
Active Contributor
0 Likes
mnawazuddin FWIW, the base 64 which you indicate is fully valid (whatever it's generated by code from blog post or by code from alternative I proposed with subroutine TLV, both produce the exact same code), the error is probably only an issue in your Adobe form. You'd better ask a question in the Adobe forum, with all details (no need to indicate the ABAP code you used to generate, just indicate the final xstring or base 64 of the QR code).
Sandra_Rossi
Active Contributor
0 Likes
firoz.ashraf2 whatever it's generated by code from your blog post or by code from alternative I proposed with subroutine TLV, both produce the exact same xstring or base 64, both are fully valid.
Sandra_Rossi
Active Contributor
0 Likes
mdishaantabish For your information, the character # is only a replacement character for characters which are not displayable. Depending on the tool you choose to display the contents, it may appear with # or any other way, or even be invisible. The ABAP debugger tools show it in various ways.

For information, all five pairs of ## characters have the same meaning. In each pair, the first # character is the Tag part of TLV (Tag-Length-Value), which contains a value between binary 1 and 5 represented with one byte, the length is also represented in binary on one byte.

If you display the contents with the hexadecimal viewer of the ABAP debugger, you will see the actual content of these "#" characters.
Nawazuddin
Explorer
0 Likes
Brother,

 

kindly can you generate base64 with this values  , if possible try to generate QRCODE also .

 

v_t1_cname 'الجواهري العربي'.
v_t2_vatno '310122393500003'.
v_t3_tstmp '2022-04-25T15:30:00Z'.
v_t4_invamx '1000.00'.
v_t5_vatamx '150.00'.

 

Thanks,

Nawazuddin.

 
Firoz_Ashraf
Contributor
AR3Yp9mE2KzZiNin2YfYsdmKINin2YTYudix2KjZigIPMzEwMTIyMzkzNTAwMDAzAxQyMDIyLTA0LTI1VDE1OjMwOjAwWgQHMTAwMC4wMAUGMTUwLjAw

Nawazuddin
Explorer
0 Likes

Brother AShraf,

 

kindly can you send me the code for this from  which you generated.

 

Thanks,

 

Firoz_Ashraf
Contributor
0 Likes
DATA:   v_t1_cname  TYPE string,
v_t2_vatno TYPE string,
v_t3_tstmp TYPE string,
v_t4_invamx TYPE string,
v_t5_vatamx TYPE string.

DATA: v_tlv_1 TYPE xstring,
v_tlv_2 TYPE xstring,
v_tlv_3 TYPE xstring,
v_tlv_4 TYPE xstring,
v_tlv_5 TYPE xstring.

DATA: qrcode_xstring TYPE xstring,
qrcode_base64 TYPE string.

PERFORM tlv USING 1 v_t1_cname CHANGING v_tlv_1.
PERFORM tlv USING 2 v_t2_vatno CHANGING v_tlv_2.
PERFORM tlv USING 3 v_t3_tstmp CHANGING v_tlv_3.
PERFORM tlv USING 4 v_t4_invamx CHANGING v_tlv_4.
PERFORM tlv USING 5 v_t5_vatamx CHANGING v_tlv_5.

***************Concatenate all TLV data********************
CONCATENATE v_tlv_1 v_tlv_2 v_tlv_3 v_tlv_4 v_tlv_5
INTO qrcode_xstring IN BYTE MODE.

***************Encode xString to Base64*********************
CALL METHOD cl_http_utility=>if_http_utility~encode_x_base64
EXPORTING
unencoded = qrcode_xstring
RECEIVING
encoded = qrcode_base64.

 
FORM tlv  USING    p_tag   TYPE i
p_value TYPE string
CHANGING p_tlv TYPE xstring.

DATA: v_tag_byte TYPE x LENGTH 1,
v_utf8 TYPE xstring,
v_length TYPE x LENGTH 1.

v_tag_byte = p_tag.
v_utf8 = cl_abap_codepage=>convert_to( p_value ).
v_length = xstrlen( v_utf8 ).
CONCATENATE v_tag_byte v_length v_utf8 INTO p_tlv IN BYTE MODE.

ENDFORM.
Nawazuddin
Explorer
0 Likes

Thanks brother Ashraf its working now..

 

 

Sandra_Rossi
Active Contributor
0 Likes
mnawazuddin As I said, I think your issue is more about how to generate the QR code in Adobe with Arabic text (for whatever reason I don't understand, because QR code deals only with bytes, not fonts). Your issue is not about the content of the QR code.

FYI, I get a different decode from your Base64>AR3Yp9mE2KzZiNin2YfYsdmKINin2YTYudix2KjZigIPMzEwMTIyMzkzNTAwMDAzAxMyMDIxLTExLTE3IDA4OjMwOjAwBAcxMDAwLjAwBQYxNTAuMDA=

but I guess it's just a matter of rendering texts from right-to-left or left-to-right.

your decode:الجواهري العربي3101223935000032021-11-17 08:30:001000.00150.00

my decode (from tag 1 at the top, to tag 5 at the bottom):
الجواهري العربي
310122393500003
2021-11-17 08:30:00
1000.00
150.00
former_member779544
Discoverer
0 Likes
hello sir,

I want to ask how to implement this method using opencart for the invoice? appreciate your answer, thank you
0 Likes
hello, dear
m_Ashraf, can you contact me in private, send me a message or a way to communicate
Thank you
Firoz_Ashraf
Contributor
0 Likes
The above solution is in ABAP to be used in layouts generated from SAP.
Firoz_Ashraf
Contributor
0 Likes
Dear Nawazuddin,

As Sandra said your issue is not with the QR code content. It seems more to do with the generation of QR code in Adobe form.
former_member502176
Discoverer
0 Likes
Hello Froez Ashraf, I followed the content and I worked on a simple sample in the .NET language
    Private Function GetHexString(Source As String) As String
Dim b As Byte() = System.Text.Encoding.UTF8.GetBytes(Source)
Return BitConverter.ToString(b).Replace("-", "")
End Function

    Dim valaa As String
valaa = "##Firoz Ashraf##1234567891##2021-11-17 08:30:00##115.00##15.00"
TextBox1.Text = (GetHexString(valaa))
TextBox2.Text = Convert.ToBase64String(Encoding.UTF8.GetBytes(valaa))

 

hex encryption :

23234669726F7A204173687261662323313233343536373839312323323032312D31312D31372030383A33303A303023233131352E3030232331352E3030

Base64 :

IyNGaXJveiBBc2hyYWYjIzEyMzQ1Njc4OTEjIzIwMjEtMTEtMTcgMDg6MzA6MDAjIzExNS4wMCMjMTUuMDA=

I have a problem, I can't read the code correctly

It seems that the problem of "TAG" = ##

Thanks

 

 

 
Sandra_Rossi
Active Contributor
0 Likes
In this blog post, # is used to represent any non-displayable (non-printable) "character". # could be U+0001, U+0002, etc. (see Unicode Characters in the 'Other, Control' Category (fileformat.info))

You should not confuse with the hash character U+0023 (Unicode Character 'NUMBER SIGN' (U+0023) (fileformat.info))
Firoz_Ashraf
Contributor
Dear Fahad,

Don' t just take the single string

"##Firoz Ashraf##1234567891##2021-11-17 08:30:00##115.00##15.00"

and convert it to hex & then to Base64

For each tag first convert it to hexa, then concatenate the hexa value into one string. Use this single string to convert to base64.

For example,

Tag1: convert 1, 12 (length of 'Firoz Ashraf') & 'Firoz Ashraf' itself to hexa. Store this in variable tlv1

(01 for 1, 0C for 12, 4669726F7A20417368726166 for Firoz Ashraf)

So the hexa value in tlv1 will be 010C4669726F7A20417368726166

 

Tag2: convert 2, 10 (length of '1234567891') & '1234567891' itself to hexa. Store this in variable tlv2

(02 for 2, 0A for 10, 31323334353637383931 for 1234567891)

So the hexa value in tlv2 will be 020A31323334353637383931 

 

Do this for remaining tags. Then concatenate tlv1 tlv2 tlv3 tlv4 tlv5 into a single variable say qrcode_xstring

As per above example the value in variable qrcode_xstring will be

010C4669726F7A20417368726166020A313233343536373839310313323032312D31312D31372030383A33303A303004063131352E3030050531352E3030

Now convert this to base64, which will become(for the value above)

AQxGaXJveiBBc2hyYWYCCjEyMzQ1Njc4OTEDEzIwMjEtMTEtMTcgMDg6MzA6MDAEBjExNS4wMAUFMTUuMDA=

 

Hope this helps.

Regards,

 
former_member502176
Discoverer
0 Likes
hi Firoz Ashraf
Thanks for the clarification
I would like to point out that I applied all the above and succeeded in converting the string correctly


see the picture





010C4669726F7A20417368726166020A313233343536373839310313323032312D31312D31372030383A33303A303004063131352E3030050531352E3030


Here everything is good


But when I convert to 'Base64' 


MDEwQzQ2Njk3MjZGN0EyMDQxNzM2ODcyNjE2NjAyMEEzMTMyMzMzNDM1MzYzNzM4MzkzMTAzMTMzMjMwMzIzMTJEMzEzMTJEMzEzNzIwMzAzODNBMzMzMDNBMzAzMDA0MDYzMTMxMzUyRTMwMzAwNTA1MzEzNTJFMzAzMA==


1 - Hex conversion has no problem

2 - The problem lies in converting to 'Base64' 


I could not identify the problem because of the lack of experience. There is a bug that I did not understand what it is .




I tested it here on this site and it works fine https://tomeko.net/online_tools/hex_to_base64.php


AQxGaXJveiBBc2hyYWYCCjEyMzQ1Njc4OTEDEzIwMjEtMTEtMTcgMDg6MzA6MDAEBjExNS4wMAUFMTUuMDA=


Is there a problem with my conversion?


Thanksfiroz.ashraf2



Firoz_Ashraf
Contributor
0 Likes
Hi Fahad,

I haven't tried my hands much on .NET

However, I have used the following code in excel to convert hexa to base64.
Function Hex2Base64(ByVal sHex)
Static oNode As Object
Dim a() As Byte

If Len(sHex) Mod 2 <> 0 Then
sHex = Left(sHex, Len(sHex) - 1) & "0" & Right(sHex, 1)
End If
If oNode Is Nothing Then
Set oNode = CreateObject("MSXML2.DOMDocument").createElement("Node")
End If
With oNode
.text = ""
.DataType = "bin.hex"
.text = sHex
a = .nodeTypedValue
.DataType = "bin.base64"
.nodeTypedValue = a
Hex2Base64 = .text
End With
End Function
madhavang
Discoverer
0 Likes
Hi Ashraf,

 

Please help me for the base64 string

 

AQxGaXJveiBBc2hyYWYCCjEyMzQ1Njc4OTEDEzIwMjEtMTEtMTcgMDg6MzA6MDAEBjExNS4wMAUFMTUuMDA=

 

the above value is not getting for the string

 

Dim str As String = "010C4669726F7A20417368726166020A313233343536373839310313323032312D31312D31372030383A33303A303004063131352E3030050531352E3030"
' Dim byt1 As Byte() = System.Text.Encoding.UTF8.GetBytes("")
txtCode.Text = Convert.ToBase64String(Encoding.UTF8.GetBytes(str))
madhavang
Discoverer
0 Likes
HI ASHRAF,

 

STRING TO HEX AS TLV BELOW

 

010C4669726F7A20417368726166
020B2031323334353637383931
031420323032312D31312D31372030383A33303A30300407203131352E3030050531352E3030

COULD YOU PLEASE HELP ME ON THE STEP HEXADECIMAL TO BASE64 STRING

IN .NET ITS NOT RETURNING THE DIFFRENT STRING

 

MDEwQzQ2Njk3MjZGN0EyMDQxNzM2ODcyNjE2NjAyMEEzMTMyMzMzNDM1MzYzNzM4MzkzMTAzMTMzMjMwMzIzMTJEMzEzMTJEMzEzNzIwMzAzODNBMzMzMDNBMzAzMDA0MDYzMTMxMzUyRTMwMzAwNTA1MzEzNTJFMzAzMA==
Sandra_Rossi
Active Contributor
0 Likes
The comments turned your ABAP blog post into questions about programming languages - next comments will be for Python, Javascript, Perl and so on. Good luck! 😄
Firoz_Ashraf
Contributor
0 Likes
Hello firoz sir.

Is there any code available for qr code ksa in c#.net

 
0 Likes
Private Function EncodeBase64(ByRef arrData() As Byte) As String

Dim objXML As MSXML2.DOMDocument
Dim objNode As MSXML2.IXMLDOMElement

'Dim objXML As Variant
'Dim objNode As Variant

Set objXML = CreateObject("MSXML2.DOMDocument")
Set objNode = objXML.createElement("b64")

objNode.DataType = "bin.base64"
objNode.nodeTypedValue = arrData
EncodeBase64 = objNode.text

 

Set objNode = Nothing
Set objXML = Nothing

 

End Function

 

There must be refence to XML 3.0 

and you must use the below function to get results

 

Puublic Sub Main()

Base64Data = EncodeBase64(StrConv(strData, vbFromUnicode))

End sub

 

where strdata is the string you are passing to get base64 encoding

 
madhavang
Discoverer
Hi Firoz,

 

I got the result to make the conversion in the other language c# than I build as a dll.

 

thanks for your support and the suggestion.
former_member780578
Discoverer
0 Likes

static string gethexstring(Int32 TagNo, string TagValue)
{

string decString = TagValue;
byte[] bytes = Encoding.UTF8.GetBytes(decString);
string hexString = BitConverter.ToString(bytes);

string StrTagNo = String.Format("0{0:X}", TagNo);
String TagNoVal = StrTagNo.Substring(StrTagNo.Length - 2, 2);

string StrTagValue_Length = String.Format("0{0:X}", bytes.Length);
String TagValue_LengthVal = StrTagValue_Length.Substring(StrTagValue_Length.Length - 2, 2);

hexString = TagNoVal + TagValue_LengthVal + hexString.Replace("-", "");
return hexString;
}

former_member780578
Discoverer
0 Likes
QR code Arabic in Base64 encoding for KSA E-Invoicing
former_member780578
Discoverer
0 Likes
static string gethexstring(Int32 TagNo, string TagValue)
{

string decString = TagValue;
byte[] bytes = Encoding.UTF8.GetBytes(decString);
string hexString = BitConverter.ToString(bytes);

string StrTagNo = String.Format("0{0:X}", TagNo);
String TagNoVal = StrTagNo.Substring(StrTagNo.Length - 2, 2);

string StrTagValue_Length = String.Format("0{0:X}", bytes.Length);
String TagValue_LengthVal = StrTagValue_Length.Substring(StrTagValue_Length.Length - 2, 2);

hexString = TagNoVal + TagValue_LengthVal + hexString.Replace("-", "");
return hexString;
}
Sandra_Rossi
Active Contributor
0 Likes
Please edit your comment, indicate what programming language it is, and format your code using the {;} button. Thank you.
0 Likes
Dear Firoz

Have a good day!

Waiting for your help.

As a matter of fact, once serial TAG 1,2,3,4,5 is used to identify columns, why length tag is required.

What is the standard set by GAZT to read information from QR Code.

As per their training videos, information shall be readable from any QR Code reader.

Why this shall be compatible with e-invoice reader developed by third party only?

 

Best regards.
Firoz_Ashraf
Contributor
You may convert all the tags into hexa and directly convert the hexa to base64 (without converting first to string and then to base64).

Kindly follow the code mentioned below.

https://blogs.sap.com/2021/11/18/qr-code-in-base64-encoding-for-ksa-e-invoicing/comment-page-1/#comm...

As per ZATCA the QR code should be in base64 format. Any QR code reader can read it (which will not be understandable since it is coded). Hence you need a special QR code application (not a general QR code reader)  which can decode the base64 and displays the data in text format.

Please find below link of "Guide to develop ZATCA compliant QR code"

https://zatca.gov.sa/en/E-Invoicing/SystemsDevelopers/Documents/QRCodeCreation.pdf
former_member780578
Discoverer
C# .Net

QR code Arabic in Base64 encoding for KSA E-Invoicing
0 Likes
Dear Firoz

Good Afternoon,

 

Thank you very much. After you sent

https://zatca.gov.sa/en/E-Invoicing/SystemsDevelopers/Documents/QRCodeCreation.pdf

Now this is more clear to formulate and construct QR Code.

 

Best regards

 
0 Likes
alktab

 

I was facing same problme in vba. I solved the problem today in VBA.

Do you want to discuss this problem or problem is already solved for you.
0 Likes
Can you help me to do this in JAVA ? i am unable to find any source  / help to generate this thing in java. thanks in advance
0 Likes
Can you pleaes help me out to write in java ? any code or git repo ?
0 Likes
QRCodeCreation.pdf (zatca.gov.sa)

 

Please check page no 11 of the pdf file provided by ZATCA

There is already code and example available for Java NodeJS.

You must have NodeJS installed on your computer.

Using Visual Studio Code.

 

Below Image is only for reference


 

We shall have any kind of zoom, MS-Teams meeting to work practically and to understand whole procedure as many drawbacks/mis leading information found in all documentations.

As reading and writing makes confusion for everything.

I can arrange a zoom meeting, if we all are agreed. 
0 Likes
Or we will request Mr. Firoz to have a zoom meeting.
0 Likes
https://www.rapidtables.com/convert/number/ascii-hex-bin-dec-converter.html

Excellent Site for conversion and verification purpose only.
0 Likes
tried in Angular Typescript but unable to convert.
basically i am using java to create base64 string and jasper report to convert that string into image (QR).

 

so that i am unable to find any way to conclude
0 Likes
Hexa string is done in JAVA that is same as you have firoz.ashraf2

but when i convert it to base64 string, base64 string is different from your base64 converted.

 

can anybody help me out what is special in conversion of base64? using BTOA javascript string is also different from Ashraf's string.
0 Likes
Final Code in Java:

 

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;

import java.nio.charset.StandardCharsets;

public class TestMain {

public static void main(String args[]) throws DecoderException {
String tag1 = getHexString(1, "Irfan Nasim");
String tag2 = getHexString(2, "1234567891");
String tag3 = getHexString(3, "2021-11-17");
String tag4 = getHexString(4, "300.00");
String tag5 = getHexString(5, "75.00");

String finalString = tag1 + tag2 + tag3 + tag4 + tag5;
byte[] decodedHex = Hex.decodeHex(finalString.toCharArray());
String result = Base64.encodeBase64String(decodedHex);
System.out.println("==> " + result);

}

static String getHexString(int tagNo, String tagValue) {
String tagNumLengthHexString = Integer.toHexString(tagNo);

int tagValueLength = tagValue.length();
String tagValueLengthHexString = Integer.toHexString(tagValueLength);

byte[] tagValueBytes = tagValue.getBytes(StandardCharsets.UTF_8);
String tagValueHexString = Hex.encodeHexString(tagValueBytes);

return (0 + tagNumLengthHexString) + (0 + tagValueLengthHexString) + tagValueHexString;
}
}
haseebashraf
Discoverer
0 Likes
Hello every one,

Is there any way to convert the arabic string to Hexadecimal in DOT NET?
0 Likes
Hello,

Can you also help me generate base64 and QR Code with the this info?

v_t1_cname = ‘مجمع عيادات جاما لطب الأسنان’

v_t2_vatno = '300056403300003’
v_t3_tstmp = '22/12/2021 04:25:03'
v_t4_invamx = '10000.00'
v_t5_vatamx = '1500.00'
0 Likes
Hello,

I am using oracle 11g and reports 6i

is there a way To do this simply?

I already have the qr but doesn’t comply with zatco

thank you
0 Likes
Dear Firoz

Good Day!

What is the next step after completeing QR Code? How to do next step?

Best regards
former_member808493
Discoverer
0 Likes
Are you Completed ZATCA 2nd Phase QR? We want to integrate 2nd phase .