Adyen / adyen-android

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

Localization is working partially #1768

Open kacpr opened 2 weeks ago

kacpr commented 2 weeks ago

Description

Strings in dropin are translated partially. When shopperLocale is set to:

Backend uses sessions integration flow. Backend set shopperLocale to "pl_PL". Android app receives CheckoutSession with SessionSetupResponse.shopperLocale set to "pl_PL".

Since strings in dropin are partially translated, I believe there are multiple call sites and methods that try to obtain locale and this flow isn't bulletproof.

Expected behavior (possible solutions):

Steps to Reproduce

  1. I am able to consistently reproduce this issue: Yes
  2. Steps to reproduce the issue:
    1. Get CheckoutSession from SessionSetupResponse.createSession()
    2. Create copy of returned CheckoutSession from step i with overwritten SessionSetupResponse.shopperLocale ("pl_PL")
    3. Start payment:
      DropIn.startPayment(
          dropInLauncher = dropInLauncher,
          checkoutSession = checkoutSession,
      )
  3. Screenshots: "pl_PL" (check Blik z kodem and Karta bankowa):
screen_1_pl_PL screen_2_pl_PL screen_3_pl_PL screen_4_pl_PL

"pl-PL":

screen_1_pl-PL screen_2_pl-PL screen_3_pl-PL screen_4_pl-PL

Code Snippets

Maybe this will be helpful: during debugging I found that those methods weren't using / returning correct locale:

checkout-core:5.6.0
LocaleUtil
    fun fromLanguageTag(tag: String): Locale {
        return Locale.forLanguageTag(tag)
    }
checkout-core:5.6.0
LocaleProvider
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
class LocaleProvider {

    fun getLocale(context: Context): Locale {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            context.resources.configuration.locales[0]
        } else {
            @Suppress("DEPRECATION")
            context.resources.configuration.locale
        }
    }
}
components-core:5.6.0
ContextExtensions:
fun Context.createLocalizedContext(locale: Locale): Context {
    val configuration = resources.configuration
    val newConfig = Configuration(configuration)
    newConfig.setLocale(locale)

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        val localeList = LocaleList(locale)
        LocaleList.setDefault(localeList)
        newConfig.setLocales(localeList)
    }

    return createConfigurationContext(newConfig) ?: this
}

Integration Information

  1. Server-side integration: Sessions
  2. Client-side integration: Drop-in
  3. SDK version: 5.6.0
  4. Android version(s) where issue occurs: API 34
  5. Device model(s) where issue occurs: emulator - pixel 5, google play services, API 34, arm64. System language: polish (default), english (US).

Additional Context

Related issues: https://github.com/Adyen/adyen-react-native/issues/15 https://github.com/Adyen/adyen-android/issues/1558 https://github.com/Adyen/adyen-android/issues/680

Keywords: localization, translations, language, resources

jreij commented 2 weeks ago

Hi @kacpr , thanks for reaching out and providing all the details. This is the intended behavior currently, we parse the locale based on Java's Locale forLanguageTag method, which means that pl-PL is the expected format and pl_PL will not parse properly.

Can your backend change the shopperLocale value sent in the /sessions request to pl-PL? That is also the expected format by our API and should solve the issue.

kacpr commented 2 weeks ago

Hi @jreij ! Thank you for the quick response! Yes, we've already changed it and it's WORKING, however I wanted to point out this problem, because:

These beahviors gave us false leads (mixed translations -> checking for overrides; Android vs iOS - searching for bugs in Android) and cost us some time :)

I strongly believe it's possible to fix these discrepancies (e.g. informing about invalid format; fixing mixed translations), which will probably spare some time to other teams and make the dropin more user-friendly :)

jreij commented 2 weeks ago

@kacpr good points! It makes sense that we support locales formatted with underscores if the backend and iOS do. We already raised this point internally and we're discussing the best way to solve it. But for now good to hear that using pl-PL works for you.

Thanks again for raising this, I will change this issue into an enhancement and keep it open to provide updates later when it's resolved.

kacpr commented 2 weeks ago

Awesome! Thanks @jreij