Payment flow has been cancelled, code: FailureCode.Cancel, Flutter|Stripe|Firebase Cloud Functions

136 Views Asked by At

Issue Description: Hello everyone, I'm integrating Stripe for payment processing in my Flutter app, following a tutorial and I am using flutter_stripe plugin. When I click on the "Pay Now" button, the payment bottom sheet opens, and I can enter test card details. However, upon submitting the details, the app redirects to the browser briefly, showing a blank page, and then returns to the app with an error message in console saying "Payment flow has been cancelled." On the Stripe logs, the payment status is "Incomplete."

In payment Timeline, this is written: 3D Secure attempt acknowledged 3D Secure was completed, but the customer hasn't been verified because the bank does not support 3D Secure, has not set up 3D Secure for the card, or is experiencing an outage. The card network has provided proof of the attempt.

Client-Side Code:

  Future<void> initPaymentSheet(context,
      {required String email, required int amount}) async {
    try {
      // 1. create payment intent on the server
      final response = await http.post(
          Uri.parse(
              'functionEndpointUrl'),
          body: {
            'email': email,
            'amount': amount.toString(),
          });

      final jsonResponse = jsonDecode(response.body);
      log(jsonResponse.toString());

      //2. initialize the payment sheet
      await Stripe.instance.initPaymentSheet(
        paymentSheetParameters: SetupPaymentSheetParameters(
          paymentIntentClientSecret: jsonResponse['paymentIntent'],
          merchantDisplayName: 'Seller',
          customerId: jsonResponse['customer'],
          customerEphemeralKeySecret: jsonResponse['ephemeralKey'],
          style: ThemeMode.light,
        ),
      );
      await Stripe.instance.presentPaymentSheet();
      // .then((e) {
      //   Stripe.instance.confirmPaymentSheetPayment();
      // });

      // Payment was successful
      Utility.showSnack('Success', 'Payment Complete');
    } catch (e) {
      if (e is StripeException) {
        Utility.showSnack('Some Error Occured ', '${e.error.localizedMessage}');
        print('Some Error Occured ${e.error.localizedMessage}');
      } else {
        Utility.showSnack('Some error occured! ', '$e');
      }
    }
  }

index.js:

const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp(functions.config().firebase);
const stripe = require("stripe")(functions.config().stripe.secret_key);
exports.stripePaymentIntentRequest = functions.https.onRequest(async (req, res) => {
  try {
      let customerId;

      //Gets the customer who's email id matches the one sent by the client
      const customerList = await stripe.customers.list({
          email: req.body.email,
          limit: 1
      });
              
      //Checks the if the customer exists, if not creates a new customer
      if (customerList.data.length !== 0) {
          customerId = customerList.data[0].id;
      }
      else {
          const customer = await stripe.customers.create({
              email: req.body.email
          });
          customerId = customer.data.id;
      }

      //Creates a temporary secret key linked with the customer 
      const ephemeralKey = await stripe.ephemeralKeys.create(
          { customer: customerId },
          { apiVersion: '2020-08-27' }
      );

      //Creates a new payment intent with amount passed in from the client
      const paymentIntent = await stripe.paymentIntents.create({
          amount: parseInt(req.body.amount),
          currency: 'usd',
          customer: customerId,
      })
      console.log(res.body);
      res.status(200).send({
          paymentIntent: paymentIntent.client_secret,
          ephemeralKey: ephemeralKey.secret,
          customer: customerId,
          success: true,
      })
      
  } catch (error) {
      res.status(404).send({ success: false, error: error.message })
  }
});

I don't know what I'm missing, why is the payment flow being cancelled, and how can I fix it to successfully process payments using Stripe in my Flutter app?

Thanks in advance:)

0

There are 0 best solutions below