flutter_stripe icon indicating copy to clipboard operation
flutter_stripe copied to clipboard

No Exception thrown when user cancel presentPaymentSheet

Open Vichet97 opened this issue 2 years ago • 11 comments

Describe the bug There's no exception thrown to flutter side as expected when calling Stripe.instance.presentPaymentSheet() and customFlow: true then user cancel the intent by simply click on the x sign.

Instead this Error is logged in the console Unhandled Exception: StripeException D/Error (13230): com.stripe.android.paymentsheet.PaymentOptionResult$Canceled cannot be cast to com.stripe.android.view.AddPaymentMethodActivityStarter$Result which mean there's a type casting error when trying to pass the exception

Expected behavior StripeException should be thrown in this case

flutter_stripe: v2.4.0

Vichet97 avatar Mar 25 '22 17:03 Vichet97

Thanks for reporting! It is currently tracked on https://github.com/stripe/stripe-react-native/issues/723 - we'll integrate a fix when there is one

jonasbark avatar Mar 26 '22 09:03 jonasbark

Good day sirs. Any updates on this? I checked this ticket https://github.com/stripe/stripe-react-native/issues/723 and i think it was already merged and fixed. Thanks!

matthew-codev avatar Jul 22 '22 05:07 matthew-codev

Thanks for notifying this one is indeed fixed

remonh87 avatar Jul 22 '22 07:07 remonh87

Hi @remonh87 , I tried testing this feature if it was fixed with

Flutter v3.0.5 flutter_stripe 4.0.0

and it seems like we still cannot catch the cancelled event with StripeException.

I am also using customFlow:true

Here is my flutter doctor -v [✓] Flutter (Channel stable, 3.0.5, on macOS 12.4 21F79 darwin-x64, locale en-PH) • Flutter version 3.0.5 at /Users/.../fvm/versions/3.0.5 • Upstream repository https://github.com/flutter/flutter.git • Framework revision f1875d570e (12 days ago), 2022-07-13 11:24:16 -0700 • Engine revision e85ea0e79c • Dart version 2.17.6 • DevTools version 2.12.2

[✓] Android toolchain - develop for Android devices (Android SDK version 32.0.0) • Android SDK at /Users/.../Library/Android/sdk • Platform android-33, build-tools 32.0.0 • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 11.0.11+0-b60-7590822) • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 13.3.1) • Xcode at /Applications/Xcode.app/Contents/Developer • CocoaPods version 1.11.3

[✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2021.1) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 11.0.11+0-b60-7590822)

[✓] VS Code (version 1.69.2) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.44.0

This is my current code

try {
     await Stripe.instance.presentPaymentSheet();
} on StripeException {
     return;
}

I can still see this log

D/Error   (20613): com.stripe.android.paymentsheet.PaymentOptionResult$Canceled cannot be cast to com.stripe.android.view.AddPaymentMethodActivityStarter$Result

matthew-codev avatar Jul 26 '22 06:07 matthew-codev

@matthew-codev the log entry can safely be ignored.

I'm able to reproduce the missing 'user cancel' exception but I would think that it's the correct behavior. In my case when I open the payment sheet with the custom flow the first payment method is pre-selected. If I dismiss the dialog then the result is that exact payment method.

What we (cc @remonh87) should do is adjust the presentPaymentSheet call to no longer return void but the information provided: image

jonasbark avatar Jul 26 '22 07:07 jonasbark

Thanks @jonasbark for reopening again.

I would also agree that the presentPaymentSheet should return the information when the user cancels the payment sheet.

But when I click on the X button on the upper left of the payment sheet and hit close, it should throw a StripeException or return with any object you guys are comfortable with.

matthew-codev avatar Jul 26 '22 07:07 matthew-codev

@jonasbark @matthew-codev I did some research today and to be honest the Stripe sdk provides different data for the presentPaymentSheet. The data shown in the screen shot of jonas is very useless and provides only a localized label and an image blob but no information if something is cancceled. Also I cannot return this because in the "normal flow" it would return nothing and thus can confuse users. If the native SDK would provide a exception like they do in the normal flow it would be automatically parsed in the dart sdk.

That said I spent some time reproducing the issue and what the paymentsheet is doing now (tested on version 5.0.0) is preselect a payment and when the user press the x it will move to confirm anyway using the prefilled payment. I am not convinced if this is good UX but not something we can change here. If you press the x there it will throw an exception. @jonasbark I am inclined to reopen the ticket on react native side again because it looks like there is some regression there.

remonh87 avatar Sep 12 '22 20:09 remonh87

Really great package you've made. Though I have encountered this same issue and was also quite confused by what was going on. I know you've already deduced this, but I'll leave my message here anyway for the sake of helping anyone.

When you use initPaymentSheet() with customFlow: true, then run presentPaymentSheet(), submitting payment information works well. But if the user cancels the sheet, the package is not throwing a StripeException with FailureCode.canceled as would be expected (though not clearly documented anyway). Instead the app will assume a successful submission of payment information and the user will be charged using confirmPaymentSheet(). This is pretty unexpected to me.

Luckily in my case I realised I didn't actually need customFlow: true, so I was able to remove confirmPaymentSheet() and rely on just presentPaymentSheet(), which now properly handles submit and throws an exception on cancel.

From my perspective using this package, it was hard to know if the process is just not clearly documented, or actually a bug.

But either way, now that it's working for me, I'm very grateful that you've made this package, thank you!

jaween avatar Jan 06 '23 05:01 jaween

Any Update? Still having this issue! 😥

Versions:

flutter_stripe: ^9.2.0
flutter: 3.10.1

NOTE: If I remove customFlow: true from SetupPaymentSheetParameters in initPaymentSheet it works.

kishan-dhankecha avatar May 26 '23 05:05 kishan-dhankecha

Request

Remove label :blocked: Add Label :bug:

kishan-dhankecha avatar May 26 '23 05:05 kishan-dhankecha

Created a pr to provide a better result object but still there are inconsistencies between iOS and Android see: https://github.com/stripe/stripe-react-native/issues/1419

remonh87 avatar Jun 26 '23 20:06 remonh87

Closed for now we improved the result object in a better way. We depend on stripe to improve further.

remonh87 avatar Apr 14 '24 14:04 remonh87