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,102
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
former_member777295
Discoverer
Hi brother,

Can you check following encoded data.
"AQVTYWxsYQIKMTIzNDU2Nzg5MQMUMjAyMS0wNy0xMlQxNDoyNTowOVoEBjEwMC4wMAUFMTUuMDA="

Encryption method is little bit different than you mentioned.

Tags are not visible while decoding base64.

Ref. https://github.com/SallaApp/ZATCA

https://topnotepad.com/sa/qr-code-in-e-invoice

 

 
Firoz_Ashraf
Contributor
0 Likes
Yes, one conversion was missing due to which encryption was not proper. The correct base64 encoded value is

AQxGaXJveiBBc2hyYWYCCjEyMzQ1Njc4OTEDEzIwMjEtMTEtMTcgMDg6MzA6MDAEBjExNS4wMAUFMTUuMDA=

Missing Part - Conversion of 'Tag' and 'Length' to Hexadecimal and then to string.

So, the correct order is ..

Convert 'Tag' to Hexadecimal, then convert it to strings of characters with the corresponding ASCII code. Similarly convert 'Length' to Hexadecimal, and to string. Then concatenate these two strings with 'Value' (stored as string). Do this for all the TLVs and concatenate into one string. Finally this single string is to be converted to Base64 using METHOD cl_http_utility=>if_http_utility~encode_base64

I have updated my codes of the custom FM.

Thanks.

 

 

 

 
Nawazuddin
Explorer
0 Likes

Brother Asharf,

 

I am able to generate Base64 QRCODE perfectly  and scannable on screen also no issue, but when print the  invoice from VF03 using

device type ( PDFUC :pdf unicode 1:3)   printer :EPSON LQ-690 printer print(Adobe Form)   the generated QR code unable to  read

in zatca app or any QRSCANer.

 

do you have any idea  what is the issue why its not scanning , please give any input to solve this issue.

 

Thanks,

Nawazuddin.

 

 

mohammadaamir_khan
Participant
0 Likes
Hi Firoz,

I am facing issue if Seller name value is having '.' ( 'Test Co. Main Branch.') . FM HR_RU_CONVERT_HEX_TO_STRING is giving strange character when I pass value '15'.

Are you facing issue if Seller name value is having '.'  ?
Firoz_Ashraf
Contributor
0 Likes
Hi Aamir,

It is perfectly fine to get 'Strange Character' in ABAP, for example '§' when you pass the hexadecimal value 15 in the FM HR_RU_CONVERT_HEX_TO_STRING.

Please go ahead and concatenate it to the final string.

Once you convert it to base64 you will get the value as AadUZXN0IENvLiBNYWluIEJyYW5jaC4CCjEyMzQ1Njc4OTEDEzIwMjEtMTEtMjMgMTM6MDE6MDEEBjExNS4wMAUFMTUuMDA=

which can be decoded as

Test Co. Main Branch.
12345678912021-11-23 13:01:01115.0015.00

You can see that that the Seller name is 'Test Co. Main Branch.' with two dots.

 

Regards,

Firoz.
mohammadaamir_khan
Participant
0 Likes
Dear Firoz,

Below are final strings

When using Test Co. Main Branch.

ASNUZXN0IENvLiBNYWluIEJyYW5jaC4CDjMwMDI0MDg4NTgxMTExAxMyMDIxLTA3LTE1IDE2OjEwOjA4BAgxMjI2Mi40NQUHMTU5OS40NQ==

 

When using Test Co Main Branch ( removing .)

ASNUZXN0IENvIE1haW4gQnJhbmNoAg4zMDAyNDA4ODU4MTExMQMTMjAyMS0wNy0xNSAxNjoxMDowOAQIMTIyNjIuNDUFBzE1OTkuNDU=

 

QR code generated by first one is showing not compliance on E-invoice QR Reader tool, where as for second QR, it is showing as complaint.

 
Firoz_Ashraf
Contributor
0 Likes
Hello Aamir,

Which E-invoice QR Reader tool are you using?

I can see that both your code results in the same output on https://www.base64decode.org/

mohammadaamir_khan
Participant
0 Likes
Hi Firoz,

You can scan QR Code and check compliance by below ZATCA app

for Android https://play.google.com/store/apps/details?id=com.posbankbh.einvoiceqrreader

For Iphone https://apps.apple.com/us/app/e-invoice-qr-reader-ksa/id1580793042

Last time I put some wrong value ( testing with so many data). Below is where i am facing issue.

Test Co. Main Branch. ( With dots)

AadUZXN0IENvLiBNYWluIEJyYW5jaC4CDjMwMDI0MDg4NTgxMTExAxMyMDIxLTA3LTE1IDE2OjEwOjA4BAgxMjI2Mi40NQUHMTU5OS40NQ==

Test Co Main Branch

ARNUZXN0IENvIE1haW4gQnJhbmNoAg4zMDAyNDA4ODU4MTExMQMTMjAyMS0wNy0xNSAxNjoxMDowOAQIMTIyNjIuNDUFBzE1OTkuNDU=

As you see below value is slight different in case of first data. I am attaching QR code .


issue



Original



dots_removed

0 Likes
hi mr/ashraf

we do every this as yoy say

but still tag and length

can you give me exampe for first tag,first length whicj will add it in the begining of string?
Firoz_Ashraf
Contributor

Hi Aamir,

I have changed the hexadecimal conversion in my subroutine convert_hex_to_str  from FM HR_RU_CONVERT_HEX_TO_STRING to Class CL_ABAP_CONV_IN_CE explicitly utilizing UTF-8 encoding. Now the results seems to be fine.

Kindly use my updated code and create the QR code. Hopefully the ZATCA app will give you the correct result.

ARVUZXN0IENvLiBNYWluIEJyYW5jaC4CDjMwMDI0MDg4NTgxMTExAxMyMDIxLTA3LTE1IDE2OjEwOjA4BAgxMjI2Mi40NQUHMTU5OS40NQ==

Regards,

Firoz.

Firoz_Ashraf
Contributor
0 Likes
Hi Taha,

I have updated my code for hexadecimal conversion. Kindly follow it as explained.

Regards,

Firoz.
0 Likes
Hi,

It is not matching with what they specified in the document  https://zatca.gov.sa/ar/E-Invoicing/SystemsDevelopers/Documents/20210528_ZATCA_Electronic_Invoice_Se...

As per the document (section 4.1), Tag should be stored in first byte, Length is the length of the byte array of UTF8 encoded value string stored as single byte. You are converting tag and length into hex values and then to string. Which one is correct?

 
former_member778093
Discoverer
0 Likes
Dear Firoz Ashraf, I am really impress your work. I want to ask one question. When I convert TAG 1 to Hexa it is giving 1 and after that i convert it to ascci string it is giving 31. in case of len "Firoz Ashraf" len is 12 When i convert it  it is giving 3128. then concatenate the string is '313128Firoz ashraf. is it correct? if not pls guide me about this. or pls tel us the comp concatenated string
Firoz_Ashraf
Contributor
0 Likes
Hi Murty,

I believe, ABAP is taking care of  what has been specified.

Since we have to concatenate the TLV strings therefore we are doing this hexa and then string conversion.

At the end... conversion to base64 should be correct and readable by any ZATCA approved QR reader app. like this Android App or Apple App

You can build your QR code and check the result.
former_member574891
Discoverer
0 Likes
Thanks, It is working fine and also, validated it using ZATCA QR scanner
mohammadaamir_khan
Participant
0 Likes
Dear Firoz,

If you have string of length 32, then corresponding hex value is '20'. when you pass this value to your method, again this QR code will fail as method will return blank value for hex = '20'. You can verify by changing Seller name of length 32 in debug mode and scanning the generated barcode.

I done it in slight different way. We have 3 parts. TAG LENGTH and VALUE.

TAG you already giving hex value as '01' '02'....

LENGTH you are getting in hex by passing xtrlen output to variable of type xstring.

VALUE you are converting in hex by calling FM 'SCMS_STRING_TO_XSTRING'.

Now you have all 3 parts in hex. No need to convert to string, Just concatenate all in variable of type xstring using CONCATENATE INTO lv_xstring IN BYTE MODE.

Now you have hex string. Use cl_http_utility=>if_http_utility~encode_x_base64 to convert to base 64.

This is working with all length of values as we are not converting hex to str and then back to hex.

Thanks
former_member778132
Discoverer
0 Likes
Can you please share the tag length raw value for any column against the variable "
v_t1_lent

I am doing this method in Oracle but want to know what value you are returning against tag length in string. Thanks in advance.

 

Raza
Firoz_Ashraf
Contributor
0 Likes
It's   #
former_member778132
Discoverer
0 Likes
can you explain this function as example value. for example your first tag is company. and you passed the value to function "Firoz Ashraf" so first you are converting it to hex value and then to calculate the length of hex or actual string?

 
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.
Firoz_Ashraf
Contributor
0 Likes
We are passing the string 'Firoz Ashraf' to the FM which basically converts it to hexadecimal value in the variable v_xstr. Next we are calculating the length (as a number of bytes) of v_xstr using the predefined ABAP function xstrlen.
Nawazuddin
Explorer
0 Likes
Brother Asharf,

 

I am able to generate Base64 QRCODE perfectly  and scannable on screen also no issue, but when print the  invoice from VF03 using

device type ( PDFUC :pdf unicode 1:3)   printer :EPSON LQ-690 printer print(Adobe Form)   the generated QR code unable to  read

in zatca app or any QRSCANer.

 

do you have any idea  what is the issue why its not scanning , please give any input to solve this issue.

 

Thanks,

Nawazuddin.
Firoz_Ashraf
Contributor
0 Likes
Dear Nawazuddin,

For printing QR Code on DotMatrix printer EPSON LQ-690 you may try device type SWIN instead of PDFUC.

Take help of BASIS guy if needed.

Regards,
0 Likes
Hi Firoz,

Thanks for your quick response. It didn't work for me because I was including the '$' sign to the total amount. It is working now and nothing to do with hex or byte. Thanks again.

 

Murty
0 Likes
Hi S M Firoz

I am facing a problem if the name of the resource is Arabic in the base64 site is working, but through the scanner it does not work

 

ASDZhdi12YbYuSDYsdmI2LYg2KfZhNij2LXZitmEINmE2YTYqti52KjYptipINmI2KfZhNiq2LrZhNmK2YECDzMwMDc4NjMxMjcwMDAwMwMKMjAyMS8xMS8yNgQGOTIwLjAwBQYxMjAuMDA=

 

Base64

مصنع روض الأصيل للتعبئة والتغليف3007863127000032021/11/26920.00120.00

 

can you help me
Firoz_Ashraf
Contributor
0 Likes
Dear Abdul Mateen,

Hexa of 1 will be '01' and then converting it to text using METHOD cl_abap_conv_in_ce=>create and METHOD loc_conv->read will give you '#'
Firoz_Ashraf
Contributor
0 Likes

Dear Ahmed,

Try to convert the single concatenated string value into hex with UTF-8 encoding and then use this hex to finally convert to base64.

***************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.
****************************************************************
* Convert this one string to hex and then convert hex to base64
* because if there is arabic text then QR code is not readable.

loc_out_conv = cl_abap_conv_out_ce=>create( encoding = '4110' ). "UTF-8 is 4110
loc_out_conv->convert( EXPORTING data = qrcode_string IMPORTING buffer = qrcode_xstring ).
***************Encode xString to Base64*********************
CALL METHOD cl_http_utility=>if_http_utility~encode_x_base64
EXPORTING
unencoded = qrcode_xstring
RECEIVING
encoded = qrcode_base64.

Additionally, please make sure the 'Mode' of the QR Code created in SE73 is 'A' 

Regards,

Firoz.

Sandra_Rossi
Active Contributor
0 Likes

If needed, you may simplify the code a little bit, here is a test code with test data as above in the comments, which gives the exact same result, with full standard ABAP API (cl_abap_codepage for UTF-8 encoding and call transformation for transforming bytes into base64) :

REPORT.

TYPES: ty_byte TYPE x LENGTH 1.

DATA: qrcode_base64 TYPE string.
PERFORM z_einvoice_base64_qrcode_value USING
'Test Co. Main Branch.' '30024088581111' '2021-07-15 16:10:08'
'12262.45' '1599.45'
CHANGING qrcode_base64.

FORM z_einvoice_base64_qrcode_value USING
v_t1_cname TYPE string
v_t2_vatno TYPE string
v_t3_tstmp TYPE string " Invoice Time Stamp
v_t4_invamx TYPE string " Invoice Total (with VAT)
v_t5_vatamx TYPE string " VAT Total
CHANGING qrcode_base64 TYPE string.

*-----------------------------------------------------------------------
* 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, in one byte
* Value : the byte array resulting from the UTF8 encoding of the field value.
*----------------------------------------------------------------------
DATA:
qrcode_xstring TYPE xstring,
tlv_1 TYPE xstring,
tlv_2 TYPE xstring,
tlv_3 TYPE xstring,
tlv_4 TYPE xstring,
tlv_5 TYPE xstring.

PERFORM tlv USING 1 v_t1_cname CHANGING tlv_1.
PERFORM tlv USING 2 v_t2_vatno CHANGING tlv_2.
PERFORM tlv USING 3 v_t3_tstmp CHANGING tlv_3.
PERFORM tlv USING 4 v_t4_invamx CHANGING tlv_4.
PERFORM tlv USING 5 v_t5_vatamx CHANGING tlv_5.

***************Concatenate all TLV data********************
CONCATENATE tlv_1 tlv_2 tlv_3 tlv_4 tlv_5
INTO qrcode_xstring IN BYTE MODE.

***************Encode xString to Base64*********************
CALL TRANSFORMATION id SOURCE whatever = qrcode_xstring
RESULT whatever = qrcode_base64.

ENDFORM.

FORM tlv USING tag TYPE i value TYPE string
CHANGING tlv TYPE xstring.

DATA: tag_byte TYPE ty_byte,
utf8 TYPE xstring,
length TYPE ty_byte.

tag_byte = tag.
utf8 = cl_abap_codepage=>convert_to( value ).
length = xstrlen( utf8 ).
CONCATENATE tag_byte length utf8 INTO tlv IN BYTE MODE.

ENDFORM.
former_member778452
Discoverer
0 Likes
Hi

Please I write this code it is working right and tested on

https://www.base64decode.org/

My issue when I put it on Adobe form it is empty when I scanned it

Can you help me
Firoz_Ashraf
Contributor
0 Likes

Thanks for your suggestion Sandra.

Definitely it's simpler and cleaner code.

However, the base64 code resulted from CALL TRANSFORMATION is not readable from tax authority compliant app.

But when method IF_HTTP_UTILITY~ENCODE_X_BASE64 is used as shown below, the result is readable.

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

 

Regards,

Firoz.

Firoz_Ashraf
Contributor
0 Likes
Hi Eman,

If you are getting the base64 value and it's showing the result on any decoder then please check the QR Code created from SE73 which you are using on your forms.
former_member778452
Discoverer
0 Likes
It is Adobe form not smart form
Firoz_Ashraf
Contributor

you may check your data binding or the inserted QR Code type in Adobe Forms.

I tried on Adobe Forms and it is working for me.

Nawazuddin
Explorer
0 Likes
Dear Eman,

 

Increase the size of QR code it will work not only layout you need to increase  size of QRCODE in XML.

 


XML


 

Thanks,

Nawazuddin
Nawazuddin
Explorer
0 Likes
Dear AShar ,

 

Did you tried  arabic with this code , when i am passing the arabic value to this code to convert in Base64  not working.

 

 

Thanks,

Nawazuddin.
former_member778452
Discoverer
0 Likes
Thanks for your replay

It is solved
0 Likes

Hi Firoz,

I am following the same steps but still arabic text is not getting scanned. 

After concatenating into final string, called below code before base64 conversion.

****************************************************************
* Convert this one string to hex and then convert hex to base64
* because if there is arabic text then QR code is not readable.

loc_out_conv = cl_abap_conv_out_ce=>create( encoding = '4110' ). "UTF-8 is 4110
loc_out_conv->convert( EXPORTING data = qrcode_string IMPORTING buffer = qrcode_xstring ).

Also, Bar code Mode is to 'A' only.

firoz.ashraf2

Kindly help on this problem as it is very important for us to go live with this Arabic QR code.

 

Regards,

Vishal Solanki

Firoz_Ashraf
Contributor
0 Likes
Try with Mode  'U'
former_member778769
Discoverer
0 Likes

Hello  every body

Dear Firoz Ashraf  thank you very much for helping us in e invoice problem

 

I have the same problem in arabic name in seller name 

I use vb.net

0 Likes
Hi Firoz,

Done the same setting but still error remains same.

 


Barcode

Firoz_Ashraf
Contributor
0 Likes
For Arabic name make sure your text is converted to UTF-8 encoding
Firoz_Ashraf
Contributor
0 Likes

Please try to check the print preview & actual print of the QR code that you are using from SE73. See if you are getting the Arabic letters in the preview/print.


Nawazuddin
Explorer
0 Likes

Dear Ashraf,

 

I tried like this .

 

CALL METHOD cl_http_utility=>if_http_utility~encode_utf8
  EXPORTING
    unencoded v_t1_cname    " string arabic
  receiving
    encoded   v_t1_cnamex.    " xstring 

clear :v_t1_cnames.

CALL METHOD cl_http_utility=>if_http_utility~decode_utf8
EXPORTING
  encoded   v_t1_cnamex " xstring 
  RECEIVING
  unencoded v_t1_cnames. "string arabic

 

its generating string like this.

 

الجواهري العربي##310122393500003##2022-04-25T15:30:00Z##1000.00##150.00

 

arabic text comming in between.

 

Thanks,

Nawazuddin

 

 

Firoz_Ashraf
Contributor
0 Likes

Just try to generate the QR code from the base64 data that you get even if the display of arabic is at the end or in the middle.

if that does not works then use the below code

***************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.
****************************************************************
* Convert this one string to hex and then convert hex to base64
* because if there is arabic text then QR code is not readable.

loc_out_conv = cl_abap_conv_out_ce=>create( encoding = '4110' ). "UTF-8 is 4110
loc_out_conv->convert( EXPORTING data = qrcode_string IMPORTING buffer = qrcode_xstring ).
***************Encode xString to Base64*********************
CALL METHOD cl_http_utility=>if_http_utility~encode_x_base64
EXPORTING
unencoded = qrcode_xstring
RECEIVING
encoded = qrcode_base64.

I tried with your data and following is the result

QRCODE_STRING

##الجواهري العربي##310122393500003##2021-12-01 14:40:20##1150.00##150.00

QRCODE_XSTRING

011DD8A7D984D8ACD988D8A7D987D8B1D98A20D8A7D984D8B9D8B1D8A8D98A020F3331303132323339333530303030330313323032312D31322D30312031343A34303A3230040731313530

QRCODE_BASE64 AR3Yp9mE2KzZiNin2YfYsdmKINin2YTYudix2KjZigIPMzEwMTIyMzkzNTAwMDAzAxMyMDIxLTEyLTAxIDE0OjQwOjIwBAcxMTUwLjAwBQYxNTAuMDA=

0 Likes
Hi Firoz Ashraf,

Can you please explain more about 2nd step?

after step one I am getting this result

112Firoz Ashraf21012345678913192021-11-17 08:30:0046115.005515.00

how to convert this to

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

As you mentioned to convert tag and length to hexadecimal. I tried but got a different result. Please guide for the 2nd and 3rd steps. Thank You.

Firoz_Ashraf
Contributor
0 Likes

Use the following code:

**********Tag, Length & Value (TLV) all are converted to hexadecimal
* format and then concatenated into one hexa string. This
* hexa string is then transformed to base64.
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.

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.

Subroutine TLV is

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

Brother Asharaf,,

Thanks for your reply but  that generated QRCODE is not compataible with E-invoice QR Reader application   actully i am looking same like what they given QRCODE in example zatca site.

 

 

 

 

 

Thanks,

Nawazuddin.

Firoz_Ashraf
Contributor
0 Likes

Try the code suggested in

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

The generated base64 value is

AR3Yp9mE2KzZiNin2YfYsdmKINin2YTYudix2KjZigIPMzEwMTIyMzkzNTAwMDAzAxMyMDIxLTEyLTAxIDEwOjIwOjMwBAcxMTUwLjAwBQYxNTAuMDA=

former_member778769
Discoverer
0 Likes
same problem

this is my code

 

Dim qrCode As New QRCodeEncoder
qrCode.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE
qrCode.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.L

Me.PictureBox1.Image = qrCode.Encode(Me.lblQR_CODE.Text, System.Text.Encoding.UTF8)
srinivas21
Explorer
0 Likes
if sometimes length is more, then QR code is not coming. In this case, please increase the width and height of QR code size.
mtzahaque
Member
0 Likes
Mr. Firoz,

 

Thanks a lot for this wonderful blog. It really helped us reached our goal of implementing the E-Invoicing in our organization.

 

Great work. Keep it up!

 

Thanks,

TZahaque