mvallim / emv-qrcode

Java Based EMV QR Code Generator and Parser (MPM, CPM)
https://mvallim.github.io/emv-qrcode/
Apache License 2.0
98 stars 48 forks source link

RTL languages does not work #11

Closed Julia94 closed 3 years ago

Julia94 commented 3 years ago

RTL languages (for example, Arabic) do not work correctly because of directionality. Usage

   val additionalData = AdditionalDataField()
    additionalData.setReferenceLabel("test")
    additionalData.setPurposeTransaction("يكلمنسعفصقرشتثخ")

I think it can help: https://stackoverflow.com/questions/6177294/string-concatenation-containing-arabic-and-western-characters

Julia94 commented 3 years ago

Dear @mvallim, sorry for this issue! I was expecting from your lib incorrect behavior... I'll explain why i think that my issue should be rejected.

When we place RTL value to any field, we receive string that looks incorrect (at first glance). In this example Merchant Name field (tag "59") have some Arabic value. And in system-out I receive string with "6013" moved to the right side of Arabic string. (6013 is the next tag identifier, tag "60" (MerchantCity), length "13") screenshot_30-11-2020_ 18-39-24

But when I checked it deeper I found out that string is fully correct (bytes are in expected order): screenshot_30-11-2020_ 18-49-28

So exactly the string from MerchantPresentedMode.toString() should be used as a Payload. I have placed directionality unicode symbols to payload and found out that QR TLV parsers just do not work with this modified value. It looks better, yes, but it is incorrect approach.

Sample of my code (in Kotlin):

    @Test
    fun `test for check payload`() = runBlocking {
        val emvco = MerchantPresentedMode()
        emvco.setPayloadFormatIndicator("01")
        emvco.setPointOfInitiationMethod("10")
        emvco.setMerchantCategoryCode("0000")
        emvco.setTransactionCurrency("10")
        emvco.setTransactionAmount("810")

        val merchantAccountInfoTemplate = MerchantAccountInformationTemplate("30")
        merchantAccountInfoTemplate.addPaymentNetworkSpecific("00", "ABC")
        merchantAccountInfoTemplate.addPaymentNetworkSpecific("01", "TEST")
        emvco.addMerchantAccountInformation(merchantAccountInfoTemplate)

        emvco.setCountryCode("RU")
        emvco.setMerchantName("يكلمنسعفصقرشتثخ")
        emvco.setMerchantCity("MERCHANT_CITY")

        val payload = emvco.toString()

        println(payload)
    }

So it works perfectly well, you should not fix it )) BTW, thank you for this lib! :)

mvallim commented 3 years ago

Thanks @Julia94 !