flutter_stripe
flutter_stripe copied to clipboard
Closing 3DS secure window on Android causes 'Cancelled' event even when authentication is marked complete
Describe the bug I've recently had to ensure we handle 3DS for all payments. Calling nextAction brings up an in-app browser flow to handle the 3DS. Once the process is finished, when no returnUrl is set in the backend stripe call, the browser shows a Authentication Complete message and you can now close this window. On iOS this responds fine and I can then continue the payment (confirm), but on Android, it triggers a cancel event and throws an exception - I never received a response back from the nextAction request so I cannot continue the request.
This is tested on real Android device, but only running from within local development , not via Google Play
To Reproduce Steps to reproduce the behavior:
-
Using Android and 3DS enabled on Stripe, enter a card number that requires 3DS authentcation: 4000000000003063 (test card) note, using the default test card of 4242424242424242 will give an immediate Authentication Compelte screen
-
Create a payment intent on the server using the payment method id from the added card and manual confirmation
Client call to bespoke server payment API
_result = await PurchaseService.makePayment(_processingOptions.purchaseRequest);
Server request to Stripe within the bespoke payment API
await Stripe.paymentIntents.create({
amount: amountPayable,
currency: "usd",
customer: stripeCustomerId,
payment_method: paymentMethodId,
payment_method_types: ["card"],
confirm: true,
confirmation_method: isLegacy ? 'automatic' : 'manual',
use_stripe_sdk: true,
error_on_requires_action: isLegacy,
// return_url: <using universal links here doesn't work on iOS because of use of in-app browser :-( >
}, {
idempotencyKey: requestId,
});
- On client, handle the response to trigger next action and listen for response
if (_result!.isDone && _result!.data != null) {
final data = _result!.data!;
if (data.requiresAction) {
try {
final stripeResponse = await Stripe.instance.handleNextAction(data.clientSecret!);
_processingOptions.purchaseRequest.setToConfirmation(stripeResponse.id);
_result = await PurchaseService.makePayment(_processingOptions.purchaseRequest);
} on StripeException catch (error) {
_result = DataRequest.error(error.error.localizedMessage);
} catch (error) {
_result = DataRequest.error(null);
}
}
}
- On Android, when the message from Stripe is Authentication Complete, close this window - press Close. A StripeException will be thrown instead of a success response.
Expected behavior When clicking close on a succesful authentication, I expect handleNextAction to return a success response so the payment can be confirmed on the server. This works for iOS but not Android
Smartphone
- Device: Samsung S9
- OS: Android 10
- Package version: 3.0.0 / 3.3.0
- Flutter version 3.0.0
Additional context Setting the returnUrl fixes the problem on Android however, cannot use universal links as opens the website on iOS due to not using native browser for the 3DS, and running into a current issue using application scheme not working on iOS (not sure why on that yet - have yet to find time to resolve, return link generated by Stripe works fine when accessed by say iOS notes or any external process!)
+1
I am also getting same issue
Same issue here with v4.0.0 as well. This is a very serious issue as it breaks the payment on the Android platform.
Temporary I solved it like put condition before doing paymentIntent.create to check if app is running on Android device or IOS device. if its running in Android then I am passing return url while paymentIntent.create and if its IOS then no need to pass return url. this way it works in both and returns success for Android and IOS both
Temporary I solved it like put condition before doing paymentIntent.create to check if app is running on Android device or IOS device. if its running in Android then I am passing return url while paymentIntent.create and if its IOS then no need to pass return url. this way it works in both and returns success for Android and IOS both
This was a great solution. The 3DS auth screen closes automatically after the authentication completes. Thank you @hiteshtank :)
How did you get this working? @hiteshtank @musthafa1996
@jonasbark @hiteshtank For 3DS cards verification Stripe Displays a popup on the web and webview on the mobile. I have not provided the return_url but it's returning me back to My App/website. Question is: Do I need to provide return_url OR is there any chance it will take me outside the app and move to another app/website and will return to my app using return_url?
should be fixed in the latest releases of our sdk library. If this is not the case feel free to reopen it