Skip to main content
RapidDev - Software Development Agency
bubble-tutorial

How to create an e-commerce portal in Bubble.io: Step-by-Step Guide

Build a complete e-commerce portal in Bubble with product listings, a shopping cart, Stripe-powered checkout, order management, and customer accounts. This tutorial walks through creating Data Types for products and orders, designing the storefront with Repeating Groups, and wiring up payment and fulfillment workflows — all without writing code.

What you'll learn

  • How to design an e-commerce data model with Products, Orders, and Line Items
  • How to build a product catalog and shopping cart using Repeating Groups and Custom States
  • How to integrate Stripe Checkout for secure payments
  • How to manage orders and fulfillment status in a dashboard
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Advanced11 min read60-90 minGrowth plan+ (Stripe plugin requires paid plan for live mode)March 2026RapidDev Engineering Team
TL;DR

Build a complete e-commerce portal in Bubble with product listings, a shopping cart, Stripe-powered checkout, order management, and customer accounts. This tutorial walks through creating Data Types for products and orders, designing the storefront with Repeating Groups, and wiring up payment and fulfillment workflows — all without writing code.

Overview: Building an E-Commerce Portal in Bubble

This tutorial guides you through building a full e-commerce storefront in Bubble. You will create the database schema for products, orders, and line items, design product listing and detail pages, implement an add-to-cart flow with Custom States, connect Stripe for payment processing, and build an admin dashboard for order management. This guide is ideal for non-technical founders who want to launch a product-based business without hiring developers.

Prerequisites

  • A Bubble account on the Growth plan or higher
  • A Stripe account (test mode is fine to start)
  • Basic familiarity with Bubble's Design and Data tabs
  • Product images ready to upload
  • Understanding of Bubble workflows (event → action pattern)

Step-by-step guide

1

Create your e-commerce Data Types

Go to the Data tab and click Data types. Create a new Data Type called Product with these fields: Name (text), Description (text), Price (number), Image (image), Category (text), Stock (number), and Active (yes/no). Create a second Data Type called Order with fields: Customer (User), Status (text — e.g. Pending, Paid, Shipped, Delivered), Total (number), Stripe_Payment_ID (text), and Created_Date (date). Create a third Data Type called LineItem with fields: Product (Product type), Quantity (number), Subtotal (number), and Order (Order type). This three-type structure separates product data, order metadata, and individual items cleanly.

Pro tip: Use an Option Set for Order Status (Pending, Paid, Shipped, Delivered) instead of a plain text field — it prevents typos and makes conditional formatting easier.

Expected result: Three Data Types (Product, Order, LineItem) appear in the Data tab with all fields configured.

2

Build the product catalog page

Go to the Design tab and open your index page (or create a new page called products). Click the + icon, search for Repeating Group, and drag it onto the page. Set its Type of content to Product and Data source to Do a search for Products where Active = yes. Set the layout to a grid (e.g. 3 columns, fixed number of rows: 4). Inside the first cell, add an Image element and set its dynamic source to Current cell's Product's Image. Add a Text element for Current cell's Product's Name, another for Current cell's Product's Price formatted as currency ($), and a Button labeled Add to Cart.

Pro tip: Add a Search Input above the Repeating Group and apply a constraint on the search: Name contains Search Input's value. Check 'Ignore empty constraints' so it shows all products when the search is empty.

Expected result: A responsive product grid displays all active products with images, names, prices, and Add to Cart buttons.

3

Implement the shopping cart with Custom States

Select the page element (click on the page background) and create a Custom State called cart of type LineItem (check 'This is a list'). On the Add to Cart button's workflow, add action Element Actions → Set state: set cart to cart plus item — but first you need to create the LineItem. Use the action 'Create a new thing' (Type: LineItem, Product = Current cell's Product, Quantity = 1, Subtotal = Current cell's Product's Price). Then Set state of page to cart = page's cart plus item Result of step 1. For the cart display, add a Floating Group anchored to the right. Inside it, place a Repeating Group with Type: LineItem and Data source: page's cart. Display each item's Product Name, Quantity, and Subtotal. Add a Text element below showing the total: page's cart's each item's Subtotal:sum formatted as currency.

Pro tip: To handle duplicate products, add a condition: Only when page's cart's each item's Product contains Current cell's Product is no — otherwise increment the existing LineItem's Quantity instead of creating a new one.

Expected result: Users can add products to a visual cart sidebar that shows items, quantities, subtotals, and a grand total.

4

Install and configure the Stripe plugin

Go to the Plugins tab and click Add plugins. Search for Stripe and install the official Stripe plugin by Bubble. Once installed, click the plugin name to open its settings. Paste your Stripe Test Publishable Key into the Publishable key field and your Test Secret Key into the Secret key field. You can find these in your Stripe dashboard under Developers → API keys. Keep the keys in test mode until you are ready to go live. Scroll down to Checkout settings and ensure 'Use Stripe Checkout' is enabled.

Pro tip: Never paste live Stripe keys while testing. Switch to live keys only after thorough testing in Stripe's test mode with card number 4242 4242 4242 4242.

Expected result: The Stripe plugin is installed and configured with test API keys.

5

Create the checkout workflow

On the cart Floating Group, add a Checkout button. Create a workflow: When Checkout button is clicked. Add action Plugins → Stripe Checkout. In the Stripe Checkout action settings, set the Line items dynamically from the page's cart list — map each LineItem's Product Name as the description, Subtotal as the amount (in cents — multiply by 100), and Quantity. Set the success URL to your order confirmation page and the cancel URL back to the products page. After the Stripe Checkout action, add a second action: Create a new thing (Type: Order, Customer = Current User, Status = Pending, Total = page's cart's each item's Subtotal:sum). Then add actions to Make changes to a list of things — set each LineItem in the cart to have Order = Result of step 2.

Expected result: Clicking Checkout redirects users to Stripe's hosted checkout page, and a Pending order is created in the database.

6

Handle payment confirmation with a webhook

In the Stripe dashboard, go to Developers → Webhooks → Add endpoint. Enter your Bubble backend workflow URL (you will create this next). In Bubble, go to the Workflow tab, open the pages dropdown, and click Backend workflows at the bottom. Create a new backend workflow called stripe-webhook. Add a parameter called stripe_event of type text. In the workflow actions, use the 'Make changes to a thing' action: search for the Order whose Stripe_Payment_ID matches the event's payment intent ID and set its Status to Paid. Back in the Stripe dashboard, set the webhook to listen for checkout.session.completed events.

Pro tip: For complex e-commerce setups where you need advanced Stripe features like subscription billing, inventory sync, or multi-currency support, RapidDev can help architect a scalable payment system tailored to your business.

Expected result: When a customer completes payment, Stripe sends a webhook that automatically updates the order status to Paid.

7

Build the order management dashboard

Create a new page called admin-orders. Add a Repeating Group with Type of content: Order and Data source: Do a search for Orders, sorted by Created Date descending. In each cell, display the Order's Customer email, Status, Total formatted as currency, and Created Date formatted as MM/DD/YYYY. Add a Dropdown element in each cell with values from the Order Status Option Set (Pending, Paid, Shipped, Delivered). Create a workflow on the dropdown: When dropdown value changes → Make changes to Current cell's Order → set Status to This dropdown's value. Add Privacy Rules on the Order Data Type: only users with an Admin role field = yes can view all orders.

Expected result: An admin page shows all orders in a table with the ability to update order status via a dropdown.

8

Add customer account and order history pages

Create a page called my-orders. Add a Repeating Group with Type: Order and Data source: Do a search for Orders where Customer = Current User, sorted by Created Date descending. In each cell, show the order's Status (with conditional coloring — green for Delivered, yellow for Shipped, blue for Paid, gray for Pending), Total, and date. Add a group inside each cell that is only visible when the cell is clicked — this expands to show the order's LineItems in a nested Repeating Group (Type: LineItem, Data source: Search for LineItems where Order = Current cell's Order). Each LineItem row shows Product Name, Quantity, and Subtotal.

Expected result: Logged-in customers see their order history with expandable details showing individual items per order.

Complete working example

Workflow summary
1E-COMMERCE PORTAL WORKFLOW SUMMARY
2=====================================
3
4DATA TYPES:
5 Product: Name (text), Description (text), Price (number),
6 Image (image), Category (text), Stock (number), Active (yes/no)
7 Order: Customer (User), Status (Option Set), Total (number),
8 Stripe_Payment_ID (text), Created_Date (date)
9 LineItem: Product (Product), Quantity (number), Subtotal (number),
10 Order (Order)
11
12Option Set OrderStatus:
13 Pending, Paid, Shipped, Delivered
14
15PAGE: products
16 Repeating Group Type: Product, Source: Search Products (Active=yes)
17 Each cell: Image, Name, Price, [Add to Cart] button
18 Custom State on page: cart (list of LineItem)
19
20 Workflow: Add to Cart clicked
21 1. Create new LineItem (Product, Qty=1, Subtotal=Price)
22 2. Set state cart = cart + Result of step 1
23
24 Workflow: Checkout clicked
25 1. Stripe Checkout (line items from cart list)
26 2. Create Order (Customer=Current User, Status=Pending, Total=sum)
27 3. Make changes to list: each LineItem set Order = Result of step 2
28
29PAGE: admin-orders (Admin only)
30 Repeating Group Type: Order, Source: Search Orders (sorted by date)
31 Each cell: Customer email, Status dropdown, Total, Date
32
33 Workflow: Dropdown value changes
34 1. Make changes to Current cell's Order Status = dropdown value
35
36PAGE: my-orders (Customer)
37 Repeating Group Type: Order, Source: Search Orders (Customer=Current User)
38 Nested RG: LineItems where Order = Current cell's Order
39
40BACKEND WORKFLOW: stripe-webhook
41 Trigger: Incoming webhook from Stripe
42 1. Search for Order where Stripe_Payment_ID = event payment intent
43 2. Make changes Status = Paid
44
45PRIVACY RULES:
46 Product: Everyone can view active products
47 Order: Only Creator can view own orders; Admin can view all
48 LineItem: Same as Order (linked via Order field)

Common mistakes when creating an e-commerce portal in Bubble.io: Step-by-Step Guide

Why it's a problem: Storing the cart in the database instead of Custom States

How to avoid: Use a Custom State (list of LineItem) on the page for the cart. Only write to the database when the user checks out.

Why it's a problem: Not multiplying the price by 100 for Stripe

How to avoid: In the Stripe Checkout action, set the amount to Product's Price * 100 to convert dollars to cents.

Why it's a problem: Forgetting Privacy Rules on the Order Data Type

How to avoid: Add a Privacy Rule: 'This Order's Customer is Current User' with Find in searches and View all fields checked.

Why it's a problem: Skipping the webhook and relying on the redirect URL for payment confirmation

How to avoid: Always use Stripe webhooks to confirm payment. The webhook fires server-side regardless of what the user does.

Best practices

  • Use Option Sets for product categories and order statuses to ensure consistency across the app
  • Add a Stock field to Products and decrement it in the checkout workflow to prevent overselling
  • Display loading indicators during Stripe Checkout to reassure customers the payment is processing
  • Test the full purchase flow end-to-end in Stripe test mode before switching to live keys
  • Set up email notifications (via SendGrid or Bubble's built-in email) for order confirmation and status updates
  • Add search and filter controls on the admin dashboard to help manage orders at scale
  • Use Stripe's Customer Portal for self-service refund requests to reduce admin workload
  • Compress product images before uploading to keep page load times fast

Still stuck?

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

ChatGPT Prompt

I'm building an e-commerce store in Bubble.io with products, a shopping cart, Stripe checkout, and order management. Can you help me design the data model and outline the key workflows I need for adding to cart, checking out with Stripe, and tracking order status?

Bubble Prompt

Create a product catalog page with a Repeating Group showing product images, names, and prices. Add an Add to Cart button that stores selected items in a Custom State list. Include a cart sidebar showing all selected items with a Checkout button.

Frequently asked questions

Can I build an e-commerce store on Bubble's Free plan?

You can prototype on the Free plan, but you cannot process live Stripe payments or use a custom domain. Upgrade to the Growth plan before accepting real customer payments.

How do I handle product variants like sizes and colors?

Create a separate Data Type called Variant with fields for Size, Color, Price, and Stock, linked to the parent Product. Display variants in a dropdown on the product detail page and reference the selected variant in the cart.

What happens if Stripe checkout fails?

If the customer's payment fails, Stripe shows an error on the checkout page and does not redirect to your success URL. The Order remains in Pending status. You can add a workflow on the cancel URL page to clean up or notify the user.

How do I add shipping cost calculations?

Use a backend workflow that calls a shipping API (like EasyPost or Shippo) via the API Connector. Pass the customer's address and cart weight to get rates, then add the shipping cost to the order total before Stripe Checkout.

Can I send order confirmation emails from Bubble?

Yes. Add a Send email action in your stripe-webhook backend workflow that fires after the order status changes to Paid. Use dynamic data to include the customer's name, order number, and item details.

Is Bubble suitable for a high-volume e-commerce store?

Bubble works well for stores with up to a few thousand products and moderate traffic. For high-volume stores with thousands of daily transactions, consider consulting RapidDev to evaluate whether a hybrid architecture or migration would better support your scale.

How do I handle inventory management?

Add a Stock (number) field to the Product Data Type. In the checkout workflow, after payment confirmation, use Make changes to a thing to decrement each product's Stock by the LineItem's Quantity. Add a condition to the Add to Cart button: only visible when Product's Stock > 0.

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.