Adyen / adyen-android

Adyen Android Drop-in and Components
https://docs.adyen.com/checkout/android
MIT License
119 stars 66 forks source link

Locale from `checkoutConfiguration` not applied #1558

Closed markosopcic closed 1 week ago

markosopcic commented 2 weeks ago

Hi everyone. I'm implementing Adyen in Compose. I wanted to implement locale switching based on my app config, but it doesn't seem to work. Here's the code I use to initialize Adyen:

LaunchedEffect(order) {
        coroutineScope.launch {
            val result = CheckoutSessionProvider.createSession(
                sessionModel = SessionModel(adyenSessionData.sessionId, adyenSessionData.sessionData),
                environment = environment,
                clientKey = adyenSessionData.config.clientKey
            )
            when (result) {
                is CheckoutSessionResult.Error -> onPaymentFailed()
                is CheckoutSessionResult.Success -> DropIn.startPayment(
                    context = context,
                    dropInLauncher = dropInLauncher,
                    checkoutSession = result.checkoutSession,
                    checkoutConfiguration = CheckoutConfiguration(
                        environment,
                        adyenSessionData.config.clientKey,
                        Locale.forLanguageTag("nl-NL")
                    )
                )
            }
        }
    }

As you can see I'm setting the locale in the CheckoutConfiguration object.

I've tried setting the Locale.forLanguageTag("nl-NL"), Locale.GERMAN, Locale.GERMANY, but nothing seems to work, the DropIn component still opens up in english.

image

I'm testing on the test environment.

Please let me know if I can provide any more information regarding this issue to help speed up the resolution, thanks.

jreij commented 2 weeks ago

Hi @markosopcic, thanks for reaching out. When using drop-in, the payment methods list is fetched and localized on the Adyen backend, which is why you need to set the shopperLocale in the /sessions request on your backend (I assume you need to pass this from your mobile app first, unless you have your user preferences saved on your backend as well). After doing that you don't need to set the shopper locale again in the CheckoutConfiguration, you can omit that parameter altogether.

However, it looks strange to me that the PAYMENT METHODS label on top of your screenshot is also in English, the value for this label is stored and localized on our side in the SDK so it should have shown in Dutch or German. But for now let's try out the first solution and see if it works.

gabrielglbh commented 2 weeks ago

Hi there @jreij, to throw some light on the matter, on my team we have the shopperLocale set on the backend as es (or any other) and also in the CheckoutConfiguration but the DropIn still opens up in english.

jreij commented 2 weeks ago

Hi @gabrielglbh, thanks for reporting this as well. Just to be sure, you and @markosopcic are not working on the same app right? šŸ˜„

I have a few questions for both of you:

gabrielglbh commented 2 weeks ago

Hi there! Nope, we are not working on the same app :)

image-2024-04-16-15-41-35-020

jreij commented 2 weeks ago

@gabrielglbh thanks for the info. I have a few more questions:

gabrielglbh commented 2 weeks ago

@jreij Thank you for the fast answers!

Yes indeed, putting (or not) the locale in the configuration does give the same result: always in english.

I think I am not helping at all šŸ„²

jreij commented 2 weeks ago

@gabrielglbh quite the opposite, you're helping a lot and quickly šŸ˜„ Unfortunately I cannot reproduce yet.

Can you try to log the value of getString(R.string.checkout_card_number_hint) while changing your device language? If you always get Card number even with other languages then we know that the translated resources are just completely being removed on build for some reason. Otherwise we'll continue investigating other areas.

gabrielglbh commented 2 weeks ago

@jreij Quick update. It seems we DO have resConfigs like this it was very well hidden:

resourceConfigurations += brandConfiguration.languageResourcesConfiguration.map { it.language }

The brandConfiguration.languageResourcesConfiguration contains a list of Locale like listOf(Locale("en", "US"), Locale("es", "ES")) or listOf(Locale("es", "ES")).

When removing that line from the gradle file, the DropIn actually translates. You had it right at the beginning!! Thank you!

My team is reporting that the resConfig worked well along previous adyen versions. Out of curiosity, why does the resConfig conflict with the translation in version 5.x?

jreij commented 2 weeks ago

@gabrielglbh glad to hear that.

why does the resConfig conflict with the translation in version 5.x?

I don't think we changed anything in v5 that affects this. However, looking at your code I can see that brandConfiguration.languageResourcesConfiguration.map { it.language } will translate into a list of languages like 'de', 'es', 'nl'.... But Android requires this attribute to exactly match the values we have on our side so it should be 'de-rDE', 'es-rES', 'nl-rNL'... because we include the region as well.

Check the full list here or in the screenshot below. Let me know if that works.

Screenshot 2024-04-17 at 17 10 15

gabrielglbh commented 2 weeks ago

@jreij That works. Thank you very much for the help, appreciate it! Now the DropIn translates at will.

markosopcic commented 2 weeks ago

My issue might be connected, however I am not experienced in resConfigs, I'd appreciate any assistance. We have the following resConfigs defined:

def RES_CONFIGS = [
        'ar', 'bg', 'cs', 'da', 'de', 'el', 'en', 'es', 'et', 'fi', 'fr', 'hi', 'he', 'hu', 'in', 'it', 'iw', 'ko', 'nb', 'lt', 'nl', 'pl',
        'pt', 'ro', 'ru', 'sk', 'sl', 'sv', 'th', 'tr', 'uk', 'vi', 'zh', 'hr', 'lv', 'sr',

        'ar-rBH', 'ar-rKW', 'ar-rSA', 'ar-rQA', 'bg-rBG', 'cs-rCZ', 'de-rCH', 'fr-rBE', 'fr-rCA', 'hu-rHU', 'en-rAU', 'en-rGB', 'en-rIN',
        'en-rNZ', 'en-rUS', 'en-rZa', 'es-rMX', 'es-rUS', 'in-rID', 'ko-rKR', 'nl-rBE', 'pt-rBR', 'pt-rPT', 'ru-rUA', 'ru-rRU', 'ro-rRO',
        'th-rTH', 'tr-rTR', 'uk-rUA', 'zh-rCN', 'zh-rHK', 'zh-rTW', 'es-rAR', 'es-rCL', 'ar-rOM', 'en-rPH', 'el-rGR', 'sk-rSK', 'sl-rSI',
        'lt-rLT', 'et-rEE', 'he-rIL', 'iw-rIL', 'hr-rHR', 'lv-rLV', 'ar-rJO', 'fr-rMU', 'zh-rMO', 'el-rCY', 'sr-rRS', 'hi-rIN'
    ] as String[]
...

defaultConfig {
        resConfigs(*RES_CONFIGS)
}

From my understanding, resConfigs defines the resource quantifiers which will not be filtered out of the packaged app. For example, in the list we have the config nl-rBE - when i set the locale to nl-BE, and log the string value you suggested above, i get the english version. I see there is no string qualifier nl-rBE in the adyen resources, so I added the following res_configs (as we need the adyen SDK to work in the Netherlands and Belgium): 'nl-rNL', 'en-rNL', 'en-rBE' After this I run the app, I set the Locale to nl-BE, and I log the same string, and now it is in Dutch. Although, when I run the adyen component, it is still in english, unless i set the shopperLocale manually. Is this expected?

Also, when I set it to fr-BE, both the log and SDK are in english, even though we have the fr-rBE res config in the list.

gabrielglbh commented 2 weeks ago

@markosopcic From my understanding, you have to (at least) include one or more languages in your resConfig list that matches with the adyen supported languages. If your language is not included in the adyen list, it will default to english. As you can see, fr-rBE is not supported in adyen therefore the english translation will show. So you might want to set it to fr-rFR.

jreij commented 2 weeks ago

From my understanding, resConfigs defines the resource quantifiers which will not be filtered out of the packaged app

@markosopcic this is correct. So the values you have inside resConfigs have to include the values we defined on our side, take a look at the screenshot below. Therefore as @gabrielglbh suggested, you need to add nl-rNL and fr-rFR to your resConfigs. And you will still be able to use nl-BE and fr-BE as your shopper locale after that.

Screenshot 2024-04-17 at 17 10 15

Although, when I run the adyen component, it is still in english, unless i set the shopperLocale manually. Is this expected?

This might be a different issue. You shouldn't need to set shopper locale in the CheckoutConfiguration if you are passing it to the /sessions API call on your backend. Can you try this and the resConfigs solution above then let us know? If it still doesn't work please share screenshots of the payment methods list screen and the card component screen.

markosopcic commented 1 week ago

Thanks. Unfortunately, our backend team can't prioritise adding the locale to the /sessions call right now, but I believe that it will resolve our issue.

Thanks for all your time and help.