Skip to Content
Technical Articles
Author's profile photo S M Firoz Ashraf

QR Code in Base64 encoding for KSA E-Invoicing

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’

SE73%20QR%20Code%20Font%20Creation

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

SE71%20Character%20Format%20QR

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.

 

Assigned Tags

      111 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo MUHZIN MUHAMMED
      MUHZIN MUHAMMED

      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
       

       

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      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.

       

       

       

       

      Author's profile photo Mohammad Nawazuddin
      Mohammad Nawazuddin

      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.

       

       

      Author's profile photo Abdul Mateen
      Abdul Mateen

      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

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      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 '#'

      Author's profile photo ahmed aledrisi
      ahmed aledrisi

      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

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      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.

      Author's profile photo Solanki Vishal Himmatlal
      Solanki Vishal Himmatlal

      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.

      S M Firoz Ashraf

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

       

      Regards,

      Vishal Solanki

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      Try with Mode  'U'

      Author's profile photo Solanki Vishal Himmatlal
      Solanki Vishal Himmatlal

      Hi Firoz,

      Done the same setting but still error remains same.

       

      Barcode

      Barcode

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      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.

      Author's profile photo Mohammad Aamir Khan
      Mohammad Aamir Khan

      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 '.'  ?

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      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.

      Author's profile photo Mohammad Aamir Khan
      Mohammad Aamir Khan

      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.

       

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      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/

      Author's profile photo Mohammad Aamir Khan
      Mohammad Aamir Khan

      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

      issue

      Original

      Original

      dots_removed

      dots_removed

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      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.

      Author's profile photo Mohammad Aamir Khan
      Mohammad Aamir Khan

      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

      Author's profile photo saud mohammed
      saud mohammed

      Mr. Firoz,

      Really it is appreciated, and was very helpful. First Phase was very Smooth we completed.

      As of now QRCODE is taking 256 Character and in Second phase we have to add more Strings,

      How we can achieve it.

       

      Author's profile photo tarek taha
      tarek taha

      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?

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      Hi Taha,

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

      Regards,

      Firoz.

      Author's profile photo Murty Maganti
      Murty Maganti

      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_Security_Features_Implementation_Standards_vShared.pdf

      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?

       

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      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.

      Author's profile photo Murty Maganti
      Murty Maganti

      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

      Author's profile photo Javed Parvez
      Javed Parvez

      Thanks, It is working fine and also, validated it using ZATCA QR scanner

      Author's profile photo Raza Hassan
      Raza Hassan

      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

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      It's   #

      Author's profile photo Raza Hassan
      Raza Hassan

      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.
      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      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.

      Author's profile photo Mohammad Nawazuddin
      Mohammad Nawazuddin

      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.

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      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,

      Author's profile photo Sandra Rossi
      Sandra Rossi

      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.
      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      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.

      Author's profile photo Eman Elgammal
      Eman Elgammal

      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

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      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.

      Author's profile photo Eman Elgammal
      Eman Elgammal

      It is Adobe form not smart form

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      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.

      Author's profile photo Mohammad Nawazuddin
      Mohammad Nawazuddin

      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.

      Author's profile photo Mohammad Nawazuddin
      Mohammad Nawazuddin

      Dear Eman,

       

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

       

      XML

      XML

       

      Thanks,

      Nawazuddin

      Author's profile photo Eman Elgammal
      Eman Elgammal

      Thanks for your replay

      It is solved

      Author's profile photo KHALID SHOKRY
      KHALID SHOKRY

      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

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      For Arabic name make sure your text is converted to UTF-8 encoding

      Author's profile photo Mohammad Nawazuddin
      Mohammad Nawazuddin

      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

       

       

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      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=

      Author's profile photo Mohammad Nawazuddin
      Mohammad Nawazuddin

      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.

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      Try the code suggested in

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

      The generated base64 value is

      AR3Yp9mE2KzZiNin2YfYsdmKINin2YTYudix2KjZigIPMzEwMTIyMzkzNTAwMDAzAxMyMDIxLTEyLTAxIDEwOjIwOjMwBAcxMTUwLjAwBQYxNTAuMDA=

      Author's profile photo KHALID SHOKRY
      KHALID SHOKRY

      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)

      Author's profile photo Ishaan Tabish
      Ishaan Tabish

      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.

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      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.
      Author's profile photo Mohammad Nawazuddin
      Mohammad Nawazuddin

      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.

       

       

       

       

      Author's profile photo Sandra Rossi
      Sandra Rossi

      Mohammad Nawazuddin 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).

      Author's profile photo Sandra Rossi
      Sandra Rossi

      Mohammad Nawazuddin 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
      Author's profile photo Sandra Rossi
      Sandra Rossi

      S M Firoz Ashraf 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.

      Author's profile photo Sandra Rossi
      Sandra Rossi

      Ishaan Tabish 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.

      Author's profile photo Mohammad Nawazuddin
      Mohammad Nawazuddin

      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.

       

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      AR3Yp9mE2KzZiNin2YfYsdmKINin2YTYudix2KjZigIPMzEwMTIyMzkzNTAwMDAzAxQyMDIyLTA0LTI1VDE1OjMwOjAwWgQHMTAwMC4wMAUGMTUwLjAw

      Author's profile photo Mohammad Nawazuddin
      Mohammad Nawazuddin

      Brother AShraf,

       

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

       

      Thanks,

       

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author
      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.
      Author's profile photo Mohammad Nawazuddin
      Mohammad Nawazuddin

      Thanks brother Ashraf its working now..

       

       

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      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.

      Author's profile photo Ice Cuby
      Ice Cuby

      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'

      Author's profile photo srinivas narishetty
      srinivas narishetty

      if sometimes length is more, then QR code is not coming. In this case, please increase the width and height of QR code size.

      Author's profile photo Tanveer Zahaque
      Tanveer Zahaque

      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

      Author's profile photo Ido Millet
      Ido Millet

      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):

      Author's profile photo BE Co.
      BE Co.

      hello sir,

      I want to ask how to implement this method using opencart for the invoice? appreciate your answer, thank you

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      The above solution is in ABAP to be used in layouts generated from SAP.

      Author's profile photo mrk mrk
      mrk mrk

      hello, dear
      m_Ashraf, can you contact me in private, send me a message or a way to communicate
      Thank you

      Author's profile photo FAHAD SHAMARI
      FAHAD SHAMARI

      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

       

       

       

      Author's profile photo Sandra Rossi
      Sandra Rossi

      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))

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      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,

       

      Author's profile photo FAHAD SHAMARI
      FAHAD SHAMARI

      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?
      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      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
      Author's profile photo madhavan gandhi thevar
      madhavan gandhi thevar

      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))

      Author's profile photo XAMRIN support
      XAMRIN support

      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

       

      Author's profile photo XAMRIN support
      XAMRIN support

      Hello FAHAD SHAMARI

       

      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.

      Author's profile photo madhavan gandhi thevar
      madhavan gandhi thevar

      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==

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      You may try the code suggested in

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

       

      Author's profile photo madhavan gandhi thevar
      madhavan gandhi thevar

      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.

      Author's profile photo bassam sultan
      bassam sultan

      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;
      }

      Author's profile photo Sandra Rossi
      Sandra Rossi

      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! 😀

      Author's profile photo Abdul jaleel Jaleel
      Abdul jaleel Jaleel

      Hello firoz sir.

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

       

      Author's profile photo bassam sultan
      bassam sultan

      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;
      }

      Author's profile photo Sandra Rossi
      Sandra Rossi

      Please edit your comment, indicate what programming language it is, and format your code using the {;} button. Thank you.

      Author's profile photo bassam sultan
      bassam sultan

      C# .Net

      QR code Arabic in Base64 encoding for KSA E-Invoicing

      Author's profile photo bassam sultan
      bassam sultan

      QR code Arabic in Base64 encoding for KSA E-Invoicing

      Author's profile photo XAMRIN support
      XAMRIN support

      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.

      Author's profile photo S M Firoz Ashraf
      S M Firoz Ashraf
      Blog Post Author

      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/#comment-601842

      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

      Author's profile photo XAMRIN support
      XAMRIN support

      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

       

      Author's profile photo Irfan Nasim
      Irfan Nasim

      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

      Author's profile photo Irfan Nasim
      Irfan Nasim

      Can you pleaes help me out to write in java ? any code or git repo ?

      Author's profile photo XAMRIN support
      XAMRIN support

      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. 

      Author's profile photo Irfan Nasim
      Irfan Nasim

      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

      Author's profile photo XAMRIN support
      XAMRIN support

      Or we will request Mr. Firoz to have a zoom meeting.

      Author's profile photo XAMRIN support
      XAMRIN support

      https://www.rapidtables.com/convert/number/ascii-hex-bin-dec-converter.html

      Excellent Site for conversion and verification purpose only.

      Author's profile photo Irfan Nasim
      Irfan Nasim

      Hexa string is done in JAVA that is same as you have S M Firoz Ashraf

      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.

      Author's profile photo Irfan Nasim
      Irfan Nasim

      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;
          }
      }
      Author's profile photo Haseeb Ashraf
      Haseeb Ashraf

      Hello every one,

      Is there any way to convert the arabic string to Hexadecimal in DOT NET?

      Author's profile photo XAMRIN support
      XAMRIN support

      https://social.msdn.microsoft.com/Forums/en-US/09ef6f6b-288c-4590-a53f-1f43c31238ac/arabic-text-to-hex?forum=aspgettingstarted

      Author's profile photo Nawal Afifi
      Nawal Afifi

      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

      Author's profile photo XAMRIN support
      XAMRIN support

      Dear Firoz

      Good Day!

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

      Best regards

      Author's profile photo Harisul Islam
      Harisul Islam

      Are you Completed ZATCA 2nd Phase QR? We want to integrate 2nd phase .

      Author's profile photo Firoz Ashraf
      Firoz Ashraf

      No Harisul, haven't yet started on the 2nd phase development.

      Author's profile photo Pradeep Alex Luke
      Pradeep Alex Luke

      Dear Firoz,

      I was am able to generate QR Code as you mentioned and it is readable by E-Invoice QR Reader, First%20APP

      First APP

      But now they have introduced a new APP, In which this QR code is not readable. VAT%20App

      VAT App

       

      Couldn't find any guidelines regarding what are the changes that we need to incorporate. Not sure how to analyze what is issue is.

      Could you please help me with this regards.

      Author's profile photo Pradeep Alex Luke
      Pradeep Alex Luke

      Dear All,

       

      The above mentioned issue is resolved. It was an issue with the date format.

       

      Best Regards.

      Author's profile photo Firoz Ashraf
      Firoz Ashraf

      Good to know Pradeep

      Author's profile photo Naresh Kumar S
      Naresh Kumar S

      Hi Firoz Ashraf,

      Greetings!!

      Did you completed the ZATCA 2nd Phase QR code implementation,

      with the following tags included

      • Hash of XML invoice
      • ECDSA signature
      • ECDSA public key
      • ECDSA signature of the cryptographic stamp’s public key

      thanks.

      Author's profile photo Firoz Ashraf
      Firoz Ashraf

      Hi Naresh,

       

       

       

      Yes we have implemented the 2nd phase of ZATCA.We have purchaseed the SAP CPI and the package itself is taking care of all the integrations as well as QR code.Regards,

      Firoz

       

       

       

       

       

       

       

       

       

       

       

      Author's profile photo Mehul Bazaria
      Mehul Bazaria

      Hello Naresh,

      Did you find any Solution from Tag6 to Tag9 ?

      • Hash of XML invoice
      • ECDSA signature
      • ECDSA public key
      • ECDSA signature of the cryptographic stamp’s public key

      I have all the values above in Place for all the tag, but when trying to convert the TLV is showing error from Tag 8 and 9.

       

      Any help will be helpfull.

      Mehul.

      Author's profile photo Peter Smith
      Peter Smith

      zatca phase 2 rules and regulations will now come from January 2023,  since now in KSA e invoicing is mandatory.

      Author's profile photo XAMRIN support
      XAMRIN support

      I think extended upto June 2023.

      Firoz may confirm this.

      Author's profile photo Saraf Uddin
      Saraf Uddin

      Thanks  Firoz Ashraf You describe whole scenario smoothly. I had developed KSA e-invoice QR code in Oracle Apex 23.1.0. Hopefully this will be helpful for oracle apex developers

       

      Demo link: https://apex.oracle.com/pls/apex/r/jasmr/sarafuddin000/qr-code

      Guide link: https://github.com/Sarafuddin000/Encoded-QR