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

How to Create an E-Commerce Store Using FlutterFlow

Build a complete single-store e-commerce app using Firestore collections for products and orders. Display products in a responsive GridView with ChoiceChips category filter and Slider price range. Store cart items in persisted App State as a JSON list so the cart survives navigation. Checkout via a Stripe Checkout Session Cloud Function that creates the order document on payment success and returns a confirmation page.

What you'll learn

  • How to model products and orders in Firestore for a single-store shop
  • How to build a filterable product grid with category chips and price range slider
  • How to implement a persistent cart using App State with JSON serialization
  • How to integrate Stripe Checkout Sessions for secure payment processing
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Advanced9 min read45-60 minFlutterFlow Pro+ (Custom Functions and Cloud Functions required)March 2026RapidDev Engineering Team
TL;DR

Build a complete single-store e-commerce app using Firestore collections for products and orders. Display products in a responsive GridView with ChoiceChips category filter and Slider price range. Store cart items in persisted App State as a JSON list so the cart survives navigation. Checkout via a Stripe Checkout Session Cloud Function that creates the order document on payment success and returns a confirmation page.

Full single-store e-commerce with product catalog, cart, and Stripe payments

This tutorial builds a complete e-commerce store: a Firestore products collection displayed in a responsive GridView with category and price filters, a product detail page with image PageView and size/color selectors, a persistent cart backed by App State, and Stripe Checkout for payments. Orders are recorded in Firestore with status tracking. This is a single-seller store — for multi-seller marketplaces, see the marketplace tutorial.

Prerequisites

  • A FlutterFlow project with Firebase/Firestore connected
  • Stripe account with test API keys (pk_test and sk_test)
  • Cloud Functions enabled (Blaze plan on Firebase)
  • Basic familiarity with App State and Backend Queries in FlutterFlow
  • Product images uploaded to Firebase Storage or external URLs

Step-by-step guide

1

Set up the products and orders Firestore collections

Create a products collection with fields: name (String), description (String), price (Double), images (List of Strings — image URLs), category (String), sizes (List of Strings), colors (List of Strings), and inStock (Boolean, default true). Create an orders collection with fields: userId (String), items (List of Maps — each with productId, productName, qty, price, size, color), total (Double), status (String — pending, confirmed, shipped, delivered), and timestamp (Timestamp). Add 5-10 test products in the Firebase Console with real image URLs and varied categories like Clothing, Accessories, Electronics.

Expected result: Firestore has products and orders collections with test data ready for querying.

2

Build the product catalog with GridView filters

Create a ShopPage with a Column layout. At the top, add a ChoiceChips widget with options All, Clothing, Accessories, Electronics — bind the selected value to a Page State variable categoryFilter (String, default All). Below it, add a RangeSlider (or two Slider widgets) for min/max price bound to Page State priceMin and priceMax. Add a GridView with crossAxisCount 2 (responsive: 3 on tablet) bound to a Backend Query on products. Apply query filters: if categoryFilter != All, where category == categoryFilter; where price >= priceMin AND price <= priceMax; where inStock == true. Each grid cell is a Container with a Column: Image (first item from images array), Text (name), and Text (price formatted as currency).

Expected result: Products display in a responsive grid. Selecting a category or adjusting the price slider filters the results in real time.

3

Create the product detail page with image carousel and variant selectors

Create ProductDetailPage that receives a productRef parameter. Add a Backend Query for the product document. Build the layout: a PageView widget at the top bound to the product's images array showing each image in full width with dot indicators. Below, add a Text for the product name (headlineMedium), a Text for price (headlineSmall, primary color), a short description Text. Add ChoiceChips for size options bound to the product's sizes list, and another ChoiceChips for color options. At the bottom, place an Add to Cart ElevatedButton. On tap, the button triggers a Custom Function that serializes the selection (productId, name, qty: 1, price, selectedSize, selectedColor) and appends it to the App State cartItems list.

Expected result: Users can browse product images, select size and color, and add items to the cart.

4

Implement the persistent cart with App State

In App State, create a variable cartItems of type List of JSON (persisted: ON). This stores cart entries as JSON objects with productId, productName, qty, price, size, and color. Create a CartPage with a ListView bound to cartItems. Each row shows: Image (product thumbnail), Text (name + size + color), Row with IconButton minus and plus to decrement/increment qty (update the cartItems list via Custom Function), and Text (line total = qty * price). At the bottom, display the cart total calculated by a Custom Function that sums all line totals. Add a Badge widget on the AppBar cart icon showing cartItems.length. The persisted App State ensures the cart survives page navigation and app restarts.

Expected result: Cart persists across pages. Users can adjust quantities, see running totals, and the AppBar badge shows item count.

5

Integrate Stripe Checkout for payment processing

Deploy a Cloud Function createCheckoutSession that accepts the cartItems array, creates Stripe line items from each cart entry (name, unit_amount in cents, quantity), calls stripe.checkout.sessions.create with mode: payment and success/cancel URLs, and returns the session URL. In FlutterFlow, add a Checkout button on the CartPage that calls this Cloud Function via an API Call action, then opens the returned URL with Launch URL action. Deploy a second Cloud Function handleStripeWebhook listening for checkout.session.completed: it creates an order document in Firestore with the cart items, total, status: confirmed, and the authenticated userId. After payment, the success URL returns the user to an OrderConfirmationPage. Clear the cartItems App State on successful return.

createCheckoutSession.js
1// Cloud Function: createCheckoutSession
2const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
3
4exports.createCheckoutSession = async (req, res) => {
5 const { cartItems, userId } = req.body;
6 const lineItems = cartItems.map(item => ({
7 price_data: {
8 currency: 'usd',
9 product_data: { name: `${item.productName} (${item.size}, ${item.color})` },
10 unit_amount: Math.round(item.price * 100),
11 },
12 quantity: item.qty,
13 }));
14 const session = await stripe.checkout.sessions.create({
15 payment_method_types: ['card'],
16 line_items: lineItems,
17 mode: 'payment',
18 success_url: 'https://yourapp.com/order-success?session_id={CHECKOUT_SESSION_ID}',
19 cancel_url: 'https://yourapp.com/cart',
20 metadata: { userId },
21 });
22 res.json({ url: session.url });
23};

Expected result: Clicking Checkout opens Stripe's hosted payment page. After payment, an order is created in Firestore and the cart is cleared.

6

Build the order history and status tracking page

Create an OrdersPage with a ListView bound to a Backend Query on orders where userId == currentUser.uid, ordered by timestamp descending. Each order card shows: order date (formatted timestamp), status with a color-coded Container badge (green for delivered, blue for shipped, yellow for confirmed, grey for pending), item count, and total amount. Tap an order to navigate to OrderDetailPage showing the full items list, delivery status stepper (Column of status steps with active/completed indicators), and a Support button. For admin use, create a separate AdminOrdersPage where staff can update the status field via a DropDown selector triggering an Update Document action.

Expected result: Customers see their order history with color-coded statuses. Admins can update order status from a management page.

Complete working example

E-Commerce Store Architecture
1Firestore Data Model:
2 products/{productId}
3 name: String ("Classic Cotton T-Shirt")
4 description: String
5 price: Double (29.99)
6 images: List<String> ([url1, url2, url3])
7 category: String ("Clothing")
8 sizes: List<String> (["S", "M", "L", "XL"])
9 colors: List<String> (["Black", "White", "Navy"])
10 inStock: Boolean (true)
11 orders/{orderId}
12 userId: String
13 items: List<Map> ([{productId, productName, qty, price, size, color}])
14 total: Double (89.97)
15 status: String ("pending" | "confirmed" | "shipped" | "delivered")
16 timestamp: Timestamp
17
18App State:
19 cartItems: List<JSON> (persisted: ON)
20 [{productId, productName, qty, price, size, color}, ...]
21
22ShopPage:
23 ChoiceChips (All | Clothing | Accessories | Electronics)
24 RangeSlider (price: $0 - $500)
25 GridView (crossAxisCount: 2, query: products filtered)
26 Container Column
27 Image (images[0])
28 Text (name)
29 Text (price, formatted currency)
30 On Tap Navigate To: ProductDetailPage
31
32ProductDetailPage:
33 PageView (product images with dot indicators)
34 Text (name, headlineMedium)
35 Text (price, primary color)
36 ChoiceChips (sizes)
37 ChoiceChips (colors)
38 ElevatedButton ("Add to Cart")
39 On Tap Custom Function: addToCart(cartItems, product, size, color)
40
41CartPage:
42 ListView (cartItems from App State)
43 Row: Image + Name + Qty controls + Line total
44 Text (cart total via Custom Function)
45 Button ("Checkout")
46 On Tap API Call: createCheckoutSession Launch URL

Common mistakes when creating an E-Commerce Store Using FlutterFlow

Why it's a problem: Storing cart in Page State instead of persisted App State

How to avoid: Use App State with persistence ON for cartItems. Persisted App State survives navigation and even app restarts, just like a real shopping cart.

Why it's a problem: Calculating order total only on the client side

How to avoid: Recalculate the total inside the Cloud Function from the actual product prices in Firestore. Never trust the client-sent total for payment processing.

Why it's a problem: Not creating a Firestore composite index for category + price queries

How to avoid: Check the Firebase Console logs for the auto-generated index creation URL when the query first fails, or proactively create a composite index on products for category (ascending) + price (ascending).

Best practices

  • Use persisted App State for the cart so items survive navigation and app restarts
  • Always recalculate totals server-side in the Cloud Function — never trust client-sent amounts
  • Create composite Firestore indexes for multi-field product queries (category + price + inStock)
  • Use Stripe Checkout Sessions instead of handling card data directly — PCI compliance handled by Stripe
  • Show product image placeholders while images load to prevent layout jumps in the GridView
  • Implement an addToCart function that merges duplicate items instead of creating separate entries
  • Test the full checkout flow with Stripe test card 4242 4242 4242 4242 before going live
  • Add Firestore Security Rules that prevent customers from modifying order status — only admin Cloud Functions should update status

Still stuck?

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

ChatGPT Prompt

Design a Firestore data model for a single-store e-commerce app. I need a products collection with name, price, images, category, sizes, colors, and stock status. I need an orders collection with userId, line items array, total, status enum, and timestamp. Also write the Stripe Checkout Session Cloud Function that creates a session from the cart items.

FlutterFlow Prompt

Create a product catalog page with a GridView showing product images, names, and prices. Add ChoiceChips at the top for category filtering (All, Clothing, Accessories, Electronics) and a price range slider. Connect the grid to my Firestore products collection with the selected filters applied.

Frequently asked questions

How do I handle product variants like size and color combinations?

Store sizes and colors as List fields on the product document. Display them as ChoiceChips on the product detail page. When adding to cart, include the selected size and color in the cart entry. For inventory tracking per variant, use a variants subcollection with sku, size, color, and stockCount fields.

Can I add a search bar to the product catalog?

Yes. Add a TextField above the GridView and bind its value to a Page State searchQuery variable. Filter the Backend Query with a where name >= searchQuery clause for prefix matching. For full-text search, integrate Algolia or Typesense via a Cloud Function.

How do I handle out-of-stock products?

Add an inStock Boolean field to products. Filter the Backend Query to only show inStock == true products. On the product detail page, use Conditional Visibility to show a Sold Out badge and disable the Add to Cart button when inStock is false.

What happens if the Stripe payment fails?

Stripe Checkout handles all error states on its hosted page — declined cards, expired cards, insufficient funds. The user stays on the Stripe page until payment succeeds. Your cancel_url brings them back to the cart with all items intact in App State.

How do I send order confirmation emails?

In the handleStripeWebhook Cloud Function, after creating the order document, use a service like SendGrid or Firebase Extensions (Trigger Email) to send a confirmation email with the order details, items, and total.

Can RapidDev help build a production e-commerce app with inventory management?

Yes. A production e-commerce app needs inventory sync, webhook-based order fulfillment, shipping integration, tax calculation, refund handling, and admin dashboards. RapidDev can architect the full system beyond what the visual builder handles alone.

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.