Adyen / adyen-flutter

MIT License
23 stars 7 forks source link

Invalid Country Code Validation Error #109

Closed SaruSStar closed 9 months ago

SaruSStar commented 9 months ago

I encountered an issue when attempting to use a specific country code in your system. The system is rejecting the provided country code with the error message "'countryCode' is not valid."

To Reproduce

  final DropInConfiguration dropInConfiguration = DropInConfiguration(
    environment: Environment.test,
    clientKey: YOUR_CLIENT_KEY,
    countryCode: "NL",
    shopperLocale: "nl-NL",
    amount: Amount(
      value: 1200,
      currency: "EUR",
    ),
  );

Replace YOUR_CLIENT_KEY with your actual client key, then pass the required fields and call the AdyenCheckout.session.create(...) method. My code is given below:

    final response = await PaymentApi.getAdyenSesson(data);
    final sessionResponse = response?.session;
    if (sessionResponse == null) return;
    final SessionCheckout sessionCheckout = await AdyenCheckout.session.create(
      sessionId: sessionResponse.id ?? '',
      sessionData: sessionResponse.sessionData ?? '',
      configuration: dropInConfiguration,
    );

Describe the bug When calling the above method, the following error was thrown:

Cause: com.adyen.checkout.core.exception.HttpException: 422 , Stacktrace: com.adyen.checkout.core.exception.CheckoutException: Failed to fetch session
    at com.adyen.checkout.sessions.core.internal.CheckoutSessionInitializer$setupSession$2.invokeSuspend(CheckoutSessionInitializer.kt:49)
    at com.adyen.checkout.sessions.core.internal.CheckoutSessionInitializer$setupSession$2.invoke(Unknown Source:8)
    at com.adyen.checkout.sessions.core.internal.CheckoutSessionInitializer$setupSession$2.invoke(Unknown Source:4)
    at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:78)
    at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:167)
    at kotlinx.coroutines.BuildersKt.withContext(Unknown Source:1)
    at com.adyen.checkout.sessions.core.internal.CheckoutSessionInitializer.setupSession(CheckoutSessionInitializer.kt:35)
    at com.adyen.checkout.sessions.core.CheckoutSessionProvider.createSession(CheckoutSessionProvider.kt:35)
    at com.adyen.checkout.sessions.core.CheckoutSessionProvider.createSession$default(CheckoutSessionProvider.kt:30)
    at com.adyen.checkout.flutter.CheckoutPlatformApi$createSession$1.invokeSuspend(CheckoutPlatformApi.kt:46)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:115)
    at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:100)
    at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:697)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684)
Caused by: com.adyen.checkout.core.exception.HttpException: 422 
    at com.adyen.checkout.core.internal.data.api.OkHttpClient.executeRequest(OkHttpClient.kt:86)
    at com.adyen.checkout.core.internal.data.api.OkHttpClient.post(OkHttpClient.kt:59)
    at com.adyen.checkout.core.internal.data.api.HttpClient$DefaultImpls.post$default(HttpClient.kt:22)
    at com.adyen.checkout.core.internal.data.api.HttpClientExtKt.post(HttpClientExt.kt:68)
    at com.adyen.checkout.sessions.core.internal.data.api.SessionService$setupSession$2.invokeSuspend(SessionService.kt:39)
    at com.adyen.checkout.sessions.core.internal.data.api.SessionService$setupSession$2.invoke(Unknown Source:8)
    at com.adyen.checkout.sessions.core.internal.data.api.SessionService$setupSession$2.invoke(Unknown Source:4)
    at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:78)
    at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:167)
    at kotlinx.coroutines.BuildersKt.withContext(Unknown Source:1)
    at com.adyen.checkout.sessions.core.internal.data.api.SessionService.setupSession(SessionService.kt:38)
    at com.adyen.checkout.sessions.core.internal.data.api.SessionRepository.setupSession-0E7RQCE(SessionRepository.kt:43)
    at com.adyen.checkout.sessions.core.internal.CheckoutSessionInitializer$setupSession$2.invokeSuspend(CheckoutSessionInitializer.kt:36)
    ... 17 more

Additional Details I discovered the following details during my investigation. The details passed from the Flutter code were successfully received inside the platform message.

DropInConfigurationDTO(environment=TEST, clientKey=test_Y*****************************, countryCode=NL, amount=AmountDTO(currency=EUR, value=1200), shopperLocale=nl-NL, cardConfigurationDTO=null, applePayConfigurationDTO=null, googlePayConfigurationDTO=null, cashAppPayConfigurationDTO=null, analyticsOptionsDTO=AnalyticsOptionsDTO(enabled=true, version=0.0.1), showPreselectedStoredPaymentMethod=true, skipListWhenSinglePaymentMethod=false, isRemoveStoredPaymentMethodEnabled=false)

inside the plugin code I got below error,

ErrorResponseBody(status=422, errorCode=200, message=Field 'countryCode' is not valid. [This error message is only provided on TEST, this error will be a 500 Internal Error on LIVE.], errorType=validation)

However, when inspecting the plugin code, I found that after the conversion from DropInConfigurationDTO to DropInConfiguration, the countryCode is not present in the resulting DropInConfiguration. This might be the root cause of the issue.

Expected behavior We expected the system to accept valid ISO 3166-1 alpha-2 country codes, and the provided country code should be recognized as valid.

Screenshots Before the conversion (DropInConfigurationDTO): image After conversion (DropInConfiguration): image

Please let me know if additional information or clarification is needed. Thank you for your assistance in resolving this issue!

Robert-SD commented 9 months ago

Hi @SaruSStar,

Thank you for the detailed issue description as well as including screenshots. We will look into the bug and come back to you when we need additional information or when we have the next steps to resolve the issue.

SaruSStar commented 9 months ago

Hi @Robert-SD,

Thank you for your prompt response and acknowledgement of the issue. I appreciate your attention to the matter.

I'm glad to hear that the information provided was helpful. Please feel free to reach out if there are any additional details or clarification required from my end.

Thank you!

Robert-SD commented 9 months ago

Hey @SaruSStar,

your welcome! I might have identified the root cause for the issue and now need your help for confirming the solution.

Could you check your API integration where you call the /sessions endpoint for fetching a session and verify that the country code is valid? I assume the integration takes place in PaymentApi.getAdyenSesson(data). The reason for asking is that your request contains UK as the country code. The correct country code should be GB.

By using your session id I was able to trace the request body and the provided country code (UK) could be the cause for the error inside our SDK. I also checked that our endpoint currently accepts unsupported country codes like UK. That's why the API request is successful. But the Flutter SDK only allows ISO 3166-1 alpha-2 country codes.

The reason for not having a country code inside the DropInConfiguration is that Android uses the embedded country code of the session data. The crash happens when we read the country code while conflicting with the expected values. However, the country code of the DropInConfigurationDTO is required for the iOS integration. That's why the DTO contains the field.

I hope that this short explanation helps you in resolving the problem. Please let me know if changing the country code to GB is the solution. I'm happy to provide further assistance!

SaruSStar commented 9 months ago

Hi @Robert-SD,

Thank you for your quick reply, In the course of my investigation, I tried the provided scenario using various country codes, including 'GB', 'UK', 'US', and 'NL'. The screenshot might reflect the session ID associated with the UK.

To ensure clarity, I've captured additional screenshots on both Android and iOS, but unfortunately, the outcome remains consistent.

Field 'countryCode' is not valid. [This error message is only provided on TEST, this error will be a 500 Internal Error on LIVE.]

Screenshots I am also including the session ID in the text for your convenience. It will help you check the log. session ID (Android) - CS0CAF46C4905ECCD3 As I did before, before: image And after image

session ID (iOS): CSE2C8A5750A2D3D2F image

Please let me know if you require any further details or if there are specific steps you'd like me to take. I am at your disposal to assist in resolving this matter.

For your information; This was my DropInConfiguration.

DropInConfiguration(
    environment: Environment.test,
    clientKey: YOUR_CLIENT_KEY,
    countryCode: 'GB',
    shopperLocale: 'en-GB',
    amount: Amount(
      value: 1200,
      currency: 'GBP',
    ),
  );

Looking forward to any updates or guidance you may have.

Robert-SD commented 9 months ago

Hi @SaruSStar,

thanks for providing more information. I'm happy to help to resolve the issue.

I've checked both session attempts - CS0CAF46C4905ECCD3 (Android) and CSE2C8A5750A2D3D2F (iOS). The country code in the request body for fetching the sessions in both cases is still "UK". This needs to be adjusted in your API implementation in your backend.

The DropInConfiguration looks correct and nothing needs to be changed there. But I think the issue is that "UK" is still being send as country code in the request body json when calling the /sessions endpoint.

Could you please share your request body json for fetching a session response?

SaruSStar commented 9 months ago

Thank you so much, @Robert-SD ,

Your insight was spot-on. We identified a discrepancy between the country code sent to the backend for session creation and the one used to open DropIn sessions. I really appreciate your help in pinpointing this discrepancy.

I'm pleased to share that the issue has been successfully sorted out. We appreciate your help in resolving this matter.

Let's consider this issue closed. Once again, thank you for your expertise!

Robert-SD commented 9 months ago

That's great news @SaruSStar!

I'm happy that you have resolved the issue. Only because of your detailed problem description I was able to spot the potential solution. Thanks for providing it.