flutter-stripe / flutter_stripe

Flutter SDK for Stripe.
https://pub.dev/packages/flutter_stripe
948 stars 524 forks source link

Unable to provide server side failures (payment intent creation) in deferred payment sheet #1766

Open Cabba opened 5 months ago

Cabba commented 5 months ago

Describe the bug Using deferred payment sheet Stripe.instance.intentCreationCallback inside confirmHandler in initPaymentSheet never returns even if error is provided and clientSecret is not provided. Throwing exception in the confirmHandler results in "forever loading" state of the payment sheet.

As consequence if a payment method, that fails server side or network side, is provided the payment sheet reports correctly an error. After that if a correct payment method is provided the payment sheet complete the payment but an error is presented to the user. Multiple tap on the pay button results in multiple payments made.

To Reproduce Code in the deferred payment sheet example.

Expected behavior intentCreationCallback should return if an error is provided.

Smartphone / tablet All devices

remonh87 commented 5 months ago

I think the name is a bit confusing. If I read the docs of the sdk the current behavior is how stripe intent to work:

 /*
intentCreationCallback: Call this with the `client_secret` of the PaymentIntent or SetupIntent created by your server or the error that occurred. If you're using customFlow: false (default), the error's localizedMessage will be displayed to the customer in the sheet. If you're using customFlow: true, the `confirm` method fails with the error.
  */

For example I can call the intent with the StripeException:

 await Stripe.instance.intentCreationCallback(IntentCreationCallbackParams(
        error: StripeException(
            error: LocalizedErrorMessage(code: FailureCode.Failed))));
Cabba commented 5 months ago

Thank you for the reply.

Probably I'm doing something wrong but I'm a bit confused on how to handle possible failures inside the confirmHandler method, if I throw an exception the integration gets stuck until the presentPaymentSheet timeout (if any) expires.

If I call the intentCreationCallback with a StripeException with an error code and a localized message only a generic error message appears on the stripe modal and the intentCreationCallback does not resolve the future, but at the same time confirmHandlercan be retriggered by the user (clicking on pay button) leaving the payment sheet in an inconsistent state.

Cabba commented 4 months ago

Any suggestion?

SaddarTuri commented 3 months ago

Hi @Cabba, Have you found a solution for the issue? I'm experiencing the same problem on the Android side, where it only displays a "Something went wrong" message. Could you please provide guidance on how to display the specific error thrown by the server on the PaymentSheet?

Cabba commented 3 months ago

Hi @SaddarTuri, we have solved the issue going back to the standard payment sheet (non deferred) since we changed the app payment flow and this solution was more straightforward.

On our side I think the issue with the deferred payment sheet was caused by not using the same payment intent across multiple intentCreationCallback calls. We were creating a new payment intent on every callback call.

I've not closed the issue since I think the flutter_stripe integration (or the react native foundational package) has some problem in dealing with exceptions in intentCreationCallback.

Hope this helps!

SaddarTuri commented 3 months ago

Hi @Cabba, Thank you for your assistance. However, I am still unable to display localized errors on the Payment Sheet when using deferred payment. The intentCreationCallback does not seem to work with errors thrown by the server, as it only shows a generic Something went wrong message.