Skip to content
FlutterFlow+Firebase + Stripe
Stack Integration

FlutterFlow + Firebase + Stripe Payments

FlutterFlow's Firebase integration is excellent out of the box. Adding Stripe payments requires custom action code.

Use Cases
  1. Subscription payments in FlutterFlow apps
  2. One-time purchase flows with Stripe Checkout
  3. Payment status stored in Firestore
  4. Cloud Functions handling Stripe webhooks
Implementation

Stripe's client SDK handles the payment UI. Firebase Cloud Functions receive webhooks and write payment status to Firestore. FlutterFlow listens to the Firestore document — real-time updates, no polling.

In detail

How the pieces connect

The three parts each own a layer. FlutterFlow generates the Flutter client, which talks to Firebase directly through the FlutterFire SDKs — Firebase Auth for sign-in, Cloud Firestore for data. Stripe is the only part FlutterFlow can't wire visually, so you add a Custom Action that calls Stripe's API. The pattern that holds up: never create charges from the client. The app calls a Cloud Function (onCall or an HTTPS endpoint) that uses the Stripe Node SDK and your secret key to create a PaymentIntent or a Checkout Session. Stripe processes the payment, then fires a webhook back to a second Cloud Function. That function writes the result to a Firestore document — say users/{uid}/subscriptions/{id}. FlutterFlow already has a Firestore listener on that document, so the UI flips to "active" the moment the write lands. No polling, no client-side trust in the payment outcome.

Production gotchas

The webhook handler is where most builds break. First, verify every event with stripe.webhooks.constructEvent using the signing secret from the Stripe dashboard — without it, anyone who finds the URL can POST a fake checkout.session.completed. Second, make the handler idempotent: Stripe retries on any non-2xx response, so the same event can arrive several times. Key your Firestore writes off the Stripe event ID or the subscription/payment ID, not a fresh document each call. Third, watch Cloud Functions cold starts — the first invocation after idle adds latency, and Stripe times webhooks out at ~10 seconds, so return 200 fast and do heavy work after acknowledging. Fourth, the Stripe secret key lives only in the Functions environment (firebase functions:config or runtime env), never in the FlutterFlow client. The publishable key is the only Stripe key that belongs in the app.

Securing the money path

Firestore is the weak point if rules are loose. A user's payment and subscription documents must be readable by that user but writable only by the backend. Set rules so request.auth.uid matches the document owner for reads, and block all client writes to payment/subscription paths — only the Cloud Function, running with the Admin SDK, should mutate them. The Admin SDK bypasses security rules by design, which is exactly why the webhook function is the single trusted writer. On the Stripe side, confirm amounts and prices server-side from your own Stripe Price IDs rather than trusting any amount sent from the client; a client can edit a request body, so the function should look up the canonical price. Treat the webhook secret and the Stripe secret key as the two credentials that, if leaked, compromise the whole flow.

When this combo fits

This stack fits when you want a real mobile or web app shipped fast and the payment logic is standard — subscriptions, one-time purchases, a checkout flow. FlutterFlow handles the screens and Firebase wiring visually, and the only hand-written code is the Stripe Custom Action plus two Cloud Functions. The same FlutterFlow + Firebase foundation backs the templates I publish on the FlutterFlow marketplace, where Stripe is the common payment layer apps add on top. Where it fits less well: heavily custom payment UX, marketplace-style split payouts (Stripe Connect adds real complexity the visual builder won't cover), or anything needing tight control over native checkout that's easier in raw Flutter. If your billing rules are unusual, budget for more Functions code than the happy path implies — the gap between "demo works" and "production-safe" is the webhook and rules work above, not the UI.

Live ExampleFlutterFlow Templates — Case Study
Other integration guidesView all →
Related

Need this built?