Skip to main content
RapidDev - Software Development Agency
flutterflow-tutorials

How to Integrate FlutterFlow with Stripe for Payments

Integrate Stripe with FlutterFlow by creating a Firebase Cloud Function that uses the Stripe Node.js SDK to create a Checkout Session, then calling that function from FlutterFlow and using Launch URL to redirect the user to Stripe's hosted payment page. Deploy a second Cloud Function as a webhook endpoint to receive payment confirmation events and update your Firestore database. Never put Stripe secret keys in FlutterFlow code — they must live in Cloud Function environment variables.

What you'll learn

  • How to create a Stripe Checkout Session from a Firebase Cloud Function and redirect users from FlutterFlow
  • How to configure Stripe webhooks with a Cloud Function endpoint to confirm payments in Firestore
  • How to set up subscription payments with Stripe Billing and manage the Customer Portal
  • How to test the complete payment flow using Stripe test cards before going live
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner9 min read60-90 minFlutterFlow Free+March 2026RapidDev Engineering Team
TL;DR

Integrate Stripe with FlutterFlow by creating a Firebase Cloud Function that uses the Stripe Node.js SDK to create a Checkout Session, then calling that function from FlutterFlow and using Launch URL to redirect the user to Stripe's hosted payment page. Deploy a second Cloud Function as a webhook endpoint to receive payment confirmation events and update your Firestore database. Never put Stripe secret keys in FlutterFlow code — they must live in Cloud Function environment variables.

Accept payments in FlutterFlow using Stripe Checkout — no card form code required

Stripe is the most reliable payment processor for FlutterFlow apps. The recommended integration pattern uses Stripe Checkout — a Stripe-hosted payment page that handles PCI compliance, card validation, 3D Secure authentication, Apple Pay, Google Pay, and 40+ local payment methods automatically. Your Cloud Function creates the Checkout Session (specifying what the user is paying for and the price), returns the session URL, and FlutterFlow launches that URL. After payment, Stripe sends a webhook to your second Cloud Function, which updates Firestore with the payment confirmation. This pattern requires zero card-handling code on your end.

Prerequisites

  • A FlutterFlow project with Firebase configured (Settings → Project Setup → Firebase)
  • A Stripe account — create one free at stripe.com
  • Cloud Functions enabled on your Firebase project (Blaze pay-as-you-go plan required)
  • Node.js knowledge is helpful but not required — the code provided can be copied directly

Step-by-step guide

1

Set up Stripe and store API keys securely in Cloud Functions

In your Stripe Dashboard (dashboard.stripe.com), go to Developers → API Keys. Copy the Secret key (starts with sk_test_ for test mode). In your Firebase project's Cloud Functions, set this as an environment variable using the Firebase CLI: firebase functions:config:set stripe.secret_key='sk_test_YOUR_KEY_HERE'. Never paste this key into FlutterFlow or any client-side code. Your publishable key (pk_test_) is safe to store in FlutterFlow Secrets (Settings → Secrets → STRIPE_PK) — it is designed to be public. Create Products and Prices in Stripe Dashboard → Products before writing any code. Copy the Price ID (price_xxx) for use in the Checkout Session.

Expected result: Stripe keys are configured in Cloud Functions environment (secret key) and FlutterFlow Secrets (publishable key). Products with prices are defined in Stripe Dashboard.

2

Create the Checkout Session Cloud Function

Create a Firebase Cloud Function named createCheckoutSession. Install the Stripe SDK: npm install stripe in your functions directory. The function accepts priceId (the Stripe price_xxx ID), userId (Firebase Auth UID), and successUrl and cancelUrl as parameters. It creates a Stripe Customer for the user if one doesn't exist yet (store stripeCustomerId on the Firestore user document), then calls stripe.checkout.sessions.create with mode: 'payment' for one-time or mode: 'subscription' for recurring, customer: stripeCustomerId, line_items with the price ID and quantity, success_url pointing to your app's success deep link, and cancel_url pointing back to your pricing page. Return the session.url to FlutterFlow.

create_checkout_session.js
1const functions = require('firebase-functions');
2const admin = require('firebase-admin');
3const Stripe = require('stripe');
4admin.initializeApp();
5
6const stripe = new Stripe(functions.config().stripe.secret_key);
7
8exports.createCheckoutSession = functions.https.onRequest(async (req, res) => {
9 res.set('Access-Control-Allow-Origin', '*');
10 if (req.method === 'OPTIONS') return res.status(204).send('');
11
12 const { priceId, userId, successUrl, cancelUrl } = req.body;
13 if (!priceId || !userId) {
14 return res.status(400).json({ error: 'priceId and userId required' });
15 }
16
17 const userRef = admin.firestore().collection('users').doc(userId);
18 const userDoc = await userRef.get();
19 let customerId = userDoc.data()?.stripeCustomerId;
20
21 if (!customerId) {
22 const customer = await stripe.customers.create({
23 metadata: { firebaseUid: userId },
24 });
25 customerId = customer.id;
26 await userRef.update({ stripeCustomerId: customerId });
27 }
28
29 const session = await stripe.checkout.sessions.create({
30 customer: customerId,
31 payment_method_types: ['card'],
32 line_items: [{ price: priceId, quantity: 1 }],
33 mode: 'payment',
34 success_url: successUrl || 'https://yourapp.com/success',
35 cancel_url: cancelUrl || 'https://yourapp.com/cancel',
36 });
37
38 res.json({ sessionUrl: session.url, sessionId: session.id });
39});

Expected result: The Cloud Function returns a Stripe Checkout Session URL. Calling it from FlutterFlow and launching the URL opens Stripe's hosted payment page.

3

Call the Cloud Function from FlutterFlow and launch Stripe Checkout

In FlutterFlow's API Manager, create an API Group named PaymentAPI with your Cloud Function's base URL. Add a POST call named createCheckoutSession. Set the request body as JSON with fields priceId (Variable), userId (Variable — bind to the current authenticated user's UID from Authenticated User > User Reference > uid), successUrl and cancelUrl (fixed values pointing to your app's deep link URLs). Add the call to an Action Flow on your Buy Now button. After the API call succeeds, add a Launch URL action binding the URL to the API response field sessionUrl. Set the URL mode to In App Browser (WebView) so users don't leave your app entirely, or External Browser if you prefer the full browser experience.

Expected result: Tapping the Buy button opens Stripe's checkout page. Users can enter their card and complete payment without leaving the app.

4

Set up a webhook Cloud Function to confirm payments

Create a second Cloud Function named stripeWebhook. This function receives events from Stripe after payment is completed. In Stripe Dashboard → Developers → Webhooks → Add endpoint, paste your Cloud Function's HTTPS URL and select the events: checkout.session.completed, payment_intent.succeeded, customer.subscription.updated, customer.subscription.deleted. Copy the Webhook Signing Secret (whsec_xxx) and add it to Cloud Function environment: firebase functions:config:set stripe.webhook_secret='whsec_xxx'. In the function, verify the event signature using stripe.webhooks.constructEvent(req.rawBody, sig, webhookSecret) — this prevents fake webhook calls. On checkout.session.completed, look up the Firebase user by stripeCustomerId and update their Firestore document: isPaid: true, paymentDate: serverTimestamp(), orderId: session.id.

Expected result: When a payment completes, Stripe calls your webhook, your Cloud Function verifies it and updates Firestore, and the user's paid status is reflected in the app.

5

Add the Stripe Customer Portal for subscription management

For subscription products, users need to manage their billing — change plans, update payment method, cancel. Stripe's Customer Portal provides this automatically. Create a third Cloud Function named createPortalSession that accepts a userId, looks up their stripeCustomerId from Firestore, calls stripe.billingPortal.sessions.create({ customer: customerId, return_url: yourAppUrl }), and returns the portal URL. In FlutterFlow, add a Manage Subscription button (visible only to users where isPaid is true) with an Action Flow that calls createPortalSession and launches the returned URL. The portal handles all subscription lifecycle events and sends webhooks back to your stripeWebhook function for changes.

Expected result: Subscribed users can click Manage Subscription, which opens Stripe's portal for plan changes, payment method updates, and cancellation.

Complete working example

stripe_webhook.js
1const functions = require('firebase-functions');
2const admin = require('firebase-admin');
3const Stripe = require('stripe');
4
5const stripe = new Stripe(functions.config().stripe.secret_key);
6const webhookSecret = functions.config().stripe.webhook_secret;
7
8exports.stripeWebhook = functions.https.onRequest(async (req, res) => {
9 const sig = req.headers['stripe-signature'];
10 let event;
11
12 try {
13 event = stripe.webhooks.constructEvent(req.rawBody, sig, webhookSecret);
14 } catch (err) {
15 console.error('Webhook signature verification failed:', err.message);
16 return res.status(400).send(`Webhook Error: ${err.message}`);
17 }
18
19 const db = admin.firestore();
20
21 if (event.type === 'checkout.session.completed') {
22 const session = event.data.object;
23 const customerId = session.customer;
24 const snapshot = await db.collection('users')
25 .where('stripeCustomerId', '==', customerId).limit(1).get();
26 if (!snapshot.empty) {
27 await snapshot.docs[0].ref.update({
28 isPaid: true,
29 stripeSessionId: session.id,
30 paymentDate: admin.firestore.FieldValue.serverTimestamp(),
31 });
32 }
33 }
34
35 if (event.type === 'customer.subscription.deleted') {
36 const sub = event.data.object;
37 const snapshot = await db.collection('users')
38 .where('stripeCustomerId', '==', sub.customer).limit(1).get();
39 if (!snapshot.empty) {
40 await snapshot.docs[0].ref.update({ isPaid: false, subscriptionStatus: 'cancelled' });
41 }
42 }
43
44 res.json({ received: true });
45});

Common mistakes when integrating FlutterFlow with Stripe for Payments

Why it's a problem: Using Stripe test API keys in production without switching to live keys

How to avoid: Before launching, update Cloud Function environment variables to your live keys: firebase functions:config:set stripe.secret_key='sk_live_...' stripe.webhook_secret='whsec_live_...'. Live keys start with sk_live_ and pk_live_. Verify in Stripe Dashboard that you are viewing Live mode data, not Test mode.

Why it's a problem: Not verifying the webhook signature in the Cloud Function

How to avoid: Always use stripe.webhooks.constructEvent(req.rawBody, sig, webhookSecret). If the signature is invalid, the function throws and you return 400. Never process webhook events without this check.

Why it's a problem: Calling Stripe APIs directly from FlutterFlow's API Manager using the secret key

How to avoid: The secret key must only exist in Cloud Function environment variables. FlutterFlow only calls your Cloud Function endpoint, which then calls Stripe server-side.

Best practices

  • Always test the complete payment flow with Stripe test cards (4242 4242 4242 4242 for success, 4000 0000 0000 9995 for declined) before going live
  • Set up Stripe Radar fraud detection rules in Dashboard → Radar to block suspicious payment patterns automatically
  • Store the Stripe sessionId and customerId on the Firestore user document so you can look up payment history and handle disputes
  • Enable Apple Pay and Google Pay in Stripe Dashboard → Settings → Payment Methods — they appear automatically in Stripe Checkout for eligible devices at no extra cost
  • Set up email receipts in Stripe Dashboard → Settings → Emails so customers receive automatic payment confirmations without extra code
  • Add idempotency keys to your Cloud Function Stripe API calls to prevent duplicate charges if a user taps Buy multiple times quickly
  • Monitor Stripe Dashboard → Payments and set up webhook alerts for failed payments so you can follow up with users who had card declines

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I am building a FlutterFlow app and want to integrate Stripe payments using Firebase Cloud Functions. Write two Cloud Functions in Node.js: (1) createCheckoutSession that accepts priceId and userId, creates or retrieves a Stripe customer, creates a Checkout Session for a one-time payment, and returns the session URL; (2) stripeWebhook that receives Stripe events, verifies the webhook signature, and on checkout.session.completed updates the corresponding user's Firestore document to mark them as paid. Include proper error handling and CORS headers.

FlutterFlow Prompt

Add a Buy Now button to my pricing page in FlutterFlow that calls my createCheckoutSession Cloud Function API, receives the Stripe Checkout URL, and opens it in an in-app browser. After the user returns from checkout, check their Firestore isPaid field and navigate to the premium features page if payment was successful.

Frequently asked questions

How do I integrate Stripe with FlutterFlow?

Create a Firebase Cloud Function using the Stripe Node.js SDK to create a Checkout Session. Call this function from FlutterFlow using the API Manager and launch the returned session URL with a Launch URL action. Create a second Cloud Function as a webhook endpoint to receive payment confirmations and update Firestore. Never use your Stripe secret key in FlutterFlow client code.

Can I accept subscriptions in FlutterFlow with Stripe?

Yes. In your createCheckoutSession function, set mode: 'subscription' instead of 'payment' and use a recurring Price ID. Stripe handles billing on the scheduled interval. Listen for customer.subscription.updated and customer.subscription.deleted webhook events to update the user's subscription status in Firestore. Add the Customer Portal for users to self-manage their subscriptions.

How do I test Stripe payments in FlutterFlow without charging real cards?

Use Stripe test mode keys (sk_test_... and pk_test_...) and Stripe's test card numbers: 4242 4242 4242 4242 for a successful payment (any future expiry, any CVC), 4000 0000 0000 9995 for a declined card, 4000 0025 0000 3155 for a card requiring 3D Secure authentication. Test mode payments never process real money.

Does Stripe Checkout support Apple Pay and Google Pay?

Yes, automatically. When you use Stripe Checkout (the hosted payment page), Apple Pay and Google Pay appear as options for eligible users without any additional code. Enable them in Stripe Dashboard → Settings → Payment Methods. They require HTTPS and are available on iOS Safari, Chrome for Android, and desktop Chrome/Safari.

How do I show different content to paid vs free users in FlutterFlow?

After the Stripe webhook updates the user's Firestore document with isPaid: true, use a Conditional Visibility on your premium content containers: show them only if the current user document's isPaid field is true. You can also add a subscription tier field (free / pro / enterprise) and conditionally show/hide features based on the tier.

What if I need help setting up the complete Stripe billing and subscription system?

Stripe integrations involving subscriptions, trials, coupons, metered billing, and multiple plan tiers require careful Cloud Function architecture and webhook handling logic. RapidDev has implemented Stripe integrations for dozens of FlutterFlow apps and can build the complete payment system including the customer portal, subscription management, and failed payment recovery.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.