1

As the title suggests, I am trying to implement Stripe into my flutter app using the stripe extension for Firebase and using Javascript Firebase Cloud Functions for the server side. I believe the issue is on the server side when I try to create a customer and create a payment intent.

The server side code is here:

const functions = require("firebase-functions");
const stripe = require("stripe")("my test secret key"); // this works fine for the other stripe functions I am calling 

exports.stripePaymentIntentRequest = functions.https.onRequest(
async (req, res) => {
  const {email, amount} = req.body;
  try {
    let customerId;

    // Gets the customer who's email id matches the one sent by the client
    const customerList = await stripe.customers.list({
      email: 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: email,
      });
      customerId = customer.data.id;
    }

    // Creates a temporary secret key linked with the customer
    const ephemeralKey = await stripe.ephemeralKeys.create(
        {customer: customerId},
        {apiVersion: "2022-11-15"},
    );

    // Creates a new payment intent with amount passed in from the client
    const paymentIntent = await stripe.paymentIntents.create({
      amount: parseInt(amount),
      currency: "gbp",
      customer: customerId,
    });

    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});
  }
},

);

Then my client-side code is:

try {
    // 1. create payment intent on the server
    final response = await http.post(
      Uri.parse(
          'https://us-central1-clublink-1.cloudfunctions.net/stripePaymentIntentRequest'),
      headers: {"Content-Type": "application/json"},
      body: json.encode({
        'email': email,
        'amount': amount.toString(),
      }),
    );

    final jsonResponse = json.decode(response.body);
    if (jsonResponse['error'] != null) {
      throw Exception(jsonResponse['error']);
    }
    log(jsonResponse.toString());

    //2. initialize the payment sheet
    await Stripe.instance.initPaymentSheet(
      paymentSheetParameters: SetupPaymentSheetParameters(
        paymentIntentClientSecret: jsonResponse['paymentIntent'],
        merchantDisplayName: 'Clublink UK',
        customerId: jsonResponse['customer'],
        customerEphemeralKeySecret: jsonResponse['ephemeralKey'],
        style: ThemeMode.dark,
      ),
    );

    await Stripe.instance.presentPaymentSheet();

    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(content: Text('Payment completed!')),
    );
  } catch (e) {
    if (e is StripeException) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text('Error from Stripe: ${e.error.localizedMessage}'),
        ),
      );
    } else {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Error: $e')),
      );
    }
  }
}

I basically copied the flutter_stripe documentation to create the payment sheet with the necessary changes. Any help would be greatly appreciated!

  • Does this answer your question? [Flutter FormatException: Unexpected character (at character 1)](https://stackoverflow.com/questions/55671441/flutter-formatexception-unexpected-character-at-character-1) – orakaro Jan 16 '23 at 01:50
  • Yes, that seemed to work - thanks for your reply. Now I am getting a 403 status error with reason phrase "forbidden" though – Seonaidh Morrison Jan 16 '23 at 13:11

1 Answers1

1

Ok so I found what worked! I was being given a 403 status error with reason "forbidden". This meant I had to go to the google cloud console and update the permissions in the cloud functions tab.