Skip to content

3D secure check gets stuck on Android when using sessions. #651

@todibbang

Description

@todibbang

Describe the bug
I have moved away from the "Advanced flow: three API requests" and to the session protocol as this is the suggested method for making 3D secure checks work with the app (according to Adyen - Build your integration ) and this appear to works for iOS. But for Android I've experienced a weird interaction between the Adyen library and the App "MitID" that most payment providers in Denmark use to perform the 3D secure check.
On Android the MitID app appears to be opened inside my own app rather than redirected to, and it is not closed after the payment has been accepted, effectively hijacking my app.

Below is a screenshot to illustrate the issue, I've had to gray out the content for privacy purposes but I hope it still makes sense. The body of "My App" is the exact same as that of the "MitID App" and there is no way to navigating back to the real "My App" so I end up with two instances of the MitID App running, one as it's own app and one inside my app. The only way to "fix" it is to close "My App" but this breaks the payment flow.

Image

The implementation
In package.json:
"@adyen/react-native": "^2.7.2"
The Adyen payment components looks like this:

export const AdyenPayment = (props: {
  adyenCheckoutData?: AdyenCheckoutData
  orderId: string
  onCancel: () => void
  onComplete: () => void
  status: OrderStatus | undefined
  countryCode: string | undefined
  paymentAmount: {
    value: number
    currency: string
  }
  showStorePaymentField: boolean
}) => {

  return (
    <AdyenCheckout
      config={{
        clientKey: props.clientId,
        environment: props.live ? 'live-eu' : 'test',
        returnUrl: adyenReturnUrl,
        countryCode: props.countryCode,
        amount: props.paymentAmount,
        applepay: {
          merchantID: props.appleMerchantId,
          merchantName: props.appDisplayName,
        },
        card: {
          showStorePaymentField: props.showStorePaymentField,
          holderNameRequired: true,
        },
        locale: globalLocale,
      }}
      session={props.session}
      onError={(payload: AdyenError, nativeComponent: AdyenComponent) => {
        // ...
      }}
      onComplete={(result: string, nativeComponent: AdyenComponent) => {
        // ...
      }}
    >
      <Inner />
    </AdyenCheckout>
  )
}

const Inner = () => {
  const [started, setStarted] = useState<boolean>(false)
  const { start, paymentMethods } = useAdyenCheckout()

  useEffect(() => {
    if (paymentMethods?.paymentMethods == undefined) return
    setStarted(true)
    if (start && !started) {
      start('dropIn')
    }
  }, [start, paymentMethods?.paymentMethods])

  return <ActivityIndicator />
}

MainActivity.kt looks like this:


import android.os.Bundle

class MainActivity : ReactActivity() {

...
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(null)
    AdyenCheckout.setLauncherActivity(this)
  }
}

It is not clear to me how the returnUrl should be filled out in this case, and maybe this is causing the issue? The documentation for the returnURL says:
"Custom URL scheme of your iOS app. This value is overridden for Android by AdyenCheckout. You can also send this property from your backend.".
According to the documentation then filling out <data android:scheme="myapp" android:path="/payment" /> is only necessary "For standalone components", so I've not done that.

Summary
I realise that this might be hard to reproduce, but I hope that the nature of the issue is clear. I don't know if it's common for apps to open each other in this way, and maybe this protocol is used by other 3D secure apps other than MitID. It might be a result of how the Android implementation handles 3D verification. According to this post Stack Overflow embedded web views are no longer supported for MitID on Android and the login flow must use Chrome Custom Tabs (or an external browser) - I'm not sure what the Android implementation does in this case.

I'll look forward to your reply, thank you in advance :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions