If I understand correctly, for 3DS version 1, the Stripe android sdk displays the bank page inside a WebView. (I know this isn't an issue for version 3DS2, which uses a native activity instead of Webview)
Even though an app integrating this sdk may promise to behave well, and not capture data the user inputs, webviews are inherently insecure, from what I understand.
Here are a few examples/references:
Is there any plan for the Stripe SDK to move to a more secure way for the user to enter the 3DS version 1 code, say with Chrome Custom Tabs?
Of course, if I've misunderstood anything, and somehow webview security is less of a problem for 3DS than for other sensitive information like oauth, please do let me know!
Also: I realize this is only a temporary issue, as 3DS2 will eventually replace 3DS1. But unfortunately, the rollout of v2 is very slow and v1 is still being used nearly everywhere, from what I understand.
@calvarez-ov thanks for filing this detailed ticket. We'll investigate this issue and get back to you soon.
Any input on this? We are concerned about the security of our customers, and want them to be confident the payment system we use is secure, beyond just "take our word for it". :)
@calvarez-ov sorry for the delay in responding to you. We're continuing to investigate this issue internally, including exploring a solution using Chrome Custom Tabs.
For the time being, if you wish to avoid using WebViews for security concerns, you can handle the payment authentication by doing something like the code below. You would also need to set up your app to handle the return URL.
private suspend fun confirmPaymentIntent(
paymentMethodId: String,
clientSecret: String
) {
val paymentIntent = stripe.confirmPaymentIntentSynchronous(
ConfirmPaymentIntentParams.createWithPaymentMethodId(
paymentMethodId = paymentMethodId,
clientSecret = clientSecret,
returnUrl = "app://return_url"
)
)
withContext(Dispatchers.Main) {
if (paymentIntent != null && paymentIntent.requiresAction()) {
when (val nextActionData = paymentIntent.nextActionData) {
is StripeIntent.NextActionData.RedirectToUrl -> {
// launch the payment authentication URL
nextActionData.url
}
is StripeIntent.NextActionData.SdkData.Use3DS1 -> {
// launch the payment authentication URL
nextActionData.url
}
else -> {
// ignore
}
}
}
}
}
Thanks for the reply @mshafrir !
I seem to missing a piece of the puzzle: once my app is reopened again thanks to the returnUrl, how can I obtain the PaymentResult?
@calvarez-ov the returnUrl will have query parameters including the client_secret. You can re-fetch the PaymentIntent using the client secret and check its status to determine if user actions were successfully resolved.
Let me know if that makes sense!
If it's not too much trouble, could you point me in the direction of the api used to refetch the PaymentIntent?
@calvarez-ov sure:
Thanks! This has been a big help to get started 馃憤
@calvarez-ov I'm happy to hear that. I'll close this issue but feel free to reopen if you need further assistance.
We've got a POC with custom tabs basically working.
It's a lot of code changes for us though. (We were previously using the basic integration.) So I'm not sure if it's worth it to continue in this direction, or to wait for the stripe sdk to have custom tabs support.
To help us decide, could you please provide whatever information you can at this point for the following questions?
Thanks!
@calvarez-ov we will investigate adding Custom Tabs support sometime in the future, but unfortunately I can't provide any timeline or guarantees at this time. I would recommend implementing this functionality yourself if you need it.
@calvarez-ov we are starting work on moving to Custom Tabs in #3596. Thanks for flagging this issue last year.
@calvarez-ov our next release, 16.7.0, adds support for 3DS1 authentication via Custom Tabs. Custom Tabs will be used when the customer's device supports Custom Tabs and when the PaymentIntent/SetupIntent is confirmed without a custom return_url (i.e. value is null). Otherwise, we'll fall back to WebView. In a future release we'll add support for authentication through the device's browser.
Let me know if you have any questions.
Great news! We'll be testing this out in the coming weeks. Thanks so much 馃檹
This is now available in 16.7.1
https://github.com/stripe/stripe-android/releases/tag/v16.7.1
I can't seem to find test card numbers for 3DS v1. I tried a few sources:
In this PR I see screenshots with buttons to choose between v1 and v2.
But I don't see this option when using 4000 0000 0000 3063
Could you kindly point me to a document I may be have missed?
Thanks! 馃檹
The screenshots in that PR are from the example app.
Are you setting a return_url value? Custom Tabs requires no return_url set in ConfirmPaymentIntentParams.
Yes we were indeed 馃槃
If I remove this return url, I now see custom tabs with 4000 0000 0000 3063
Thanks!