Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter Stripe throws StripeException when Presenting Payment Sheet

I am trying to implement a Stripe payment system in my flutter app using the stripe_payment package. In my code, I call Stripe.instance.initPaymentSheet(...), however when I try to call Stripe.instance.presentPaymentSheet(...) just a few lines later, I get this error:

flutter: StripeException(error: LocalizedErrorMessage(code: FailureCode.Failed, localizedMessage: No payment sheet has been initialized yet, message: No payment sheet has been initialized yet, stripeErrorCode: null, declineCode: null, type: null))

Here is my code:

Future<void> makePayment() async {
    final url = Uri.parse(
        '${firebaseFunction}');

    final response =
        await http.get(url, headers: {'Content-Type': 'application/json'});

    this.paymentIntentData = json.decode(response.body);

    await Stripe.instance.initPaymentSheet(
        paymentSheetParameters: SetupPaymentSheetParameters(
            paymentIntentClientSecret: paymentIntentData!['paymentIntent'],
            applePay: true,
            googlePay: true,
            style: ThemeMode.dark,
            merchantCountryCode: 'UK',
            merchantDisplayName: 'Test Payment Service'));
    setState(() {});

    print('initialised');
    try {
      await Stripe.instance.presentPaymentSheet();
      setState(() {
        paymentIntentData = null;
      });
      ScaffoldMessenger.of(context).showSnackBar(SnackBar(
        content: Text('Payment Successful!'),
      ));
    } catch (e) {
      print(e);
    }
    // await displayPaymentSheet();
  }

And here is my node.js code (accessed through url):

const functions = require("firebase-functions");

const stripe = require('stripe')(functions.config().stripe.testkey);

exports.stripePayment = functions.https.onRequest(async (req, res) => {
    const paymentIntent = await stripe.paymentIntents.create({
        amount: 170,
        currency: 'usd'
    },
    function(err, paymentIntent) {
        if (err != null) {
            console.log(err);
        } else {
            res.json({
                paymentIntent: paymentIntent.client_secret
            })
        }
    })
})

Why doesn't the Payment Sheet initialize (or stay initialized) when I try to use the presentPaymentSheet method?

like image 900
ZackHossain Avatar asked Sep 12 '21 12:09

ZackHossain


2 Answers

The Paymentsheet worked on android but did not work in iPhone for me. It took me hours to find this answer (was struggling as well). There needs to be an update in the stripe documentation but when initializing Stripe you will need to initialize Stripe.publishableKey but also initialize Stripe.merchantIdentifier

EXAMPLE

First you will need initialize Stripe in your main function. (Like shown below).

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  Stripe.publishableKey = stripePublishableKey;
  Stripe.merchantIdentifier = 'any string works';
  await Stripe.instance.applySettings();
  runApp(const App());
}

Then the paymentsheet will appear without stating No payment sheet has been initialized yet

like image 186
Daniel Kang Avatar answered Oct 13 '22 22:10

Daniel Kang


In case someone ends up here in the future and you've tried everything including adding extra settings in your main file, try also changing your customerId field in the Stripe.instance.initPaymentSheet to null or some existing Id. What I found is for android it easily works but with iOS it needs a proper customerId or null.

like image 32
mahluleli goodson Avatar answered Oct 14 '22 00:10

mahluleli goodson