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

How to build a ticket booking system in Bubble

Build an event ticket booking system in Bubble with seat selection, ticket quantity limits, a booking hold timer, payment processing, and e-ticket delivery. This tutorial covers creating the event and ticket data model, designing the seat selection UI, implementing a hold-and-pay workflow to prevent overselling, and generating digital tickets via email.

What you'll learn

  • How to design event and ticket Data Types with seat and availability tracking
  • How to build a seat or ticket selection interface
  • How to implement a hold timer that releases unpaid seats
  • How to process payment and deliver e-tickets via email
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner7 min read30-35 minAll Bubble plans (Stripe plugin for payments)March 2026RapidDev Engineering Team
TL;DR

Build an event ticket booking system in Bubble with seat selection, ticket quantity limits, a booking hold timer, payment processing, and e-ticket delivery. This tutorial covers creating the event and ticket data model, designing the seat selection UI, implementing a hold-and-pay workflow to prevent overselling, and generating digital tickets via email.

Overview: Building a Ticket Booking System in Bubble

This tutorial shows you how to build a complete ticket booking system in Bubble. You will create the data model for events and tickets, design a booking interface with seat selection and quantity controls, implement a temporary hold system to prevent overselling during the payment window, process payments via Stripe, and generate digital tickets sent by email. Ideal for event organizers, venues, and ticketing platforms.

Prerequisites

  • A Bubble account with a new or existing app
  • The Stripe plugin installed for payment processing
  • Basic familiarity with Bubble's Data tab and Workflows
  • Understanding of Backend Workflows in Bubble

Step-by-step guide

1

Create the Event and Ticket Data Types

Go to the Data tab. Create a Data Type called Event with fields: Title (text), Description (text), Date (date), Venue (text), Cover Image (image), Total Tickets (number), Tickets Sold (number, default 0), Price (number), and Is Active (yes/no). Create a Data Type called Ticket with fields: Event (Event), Buyer (User), Buyer Email (text), Quantity (number), Total Price (number), Status (Option Set: Held, Confirmed, Cancelled), Hold Expires (date), Ticket Code (text), and Purchase Date (date).

Expected result: Event and Ticket Data Types appear in the Data tab with all fields configured.

2

Build the event listing and detail pages

Create an events page with a Repeating Group showing active events: Do a Search for Events where Is Active is yes, sorted by Date ascending. Display Cover Image, Title, Date, Venue, Price, and an Available Tickets count (Total Tickets minus Tickets Sold). Create a dynamic event page with Type set to Event that shows full details plus a Book Tickets section with a number input for quantity and a Book Now button.

Expected result: Events are listed with availability counts, and each event has a detail page with a booking interface.

3

Implement the ticket hold workflow to prevent overselling

When a user clicks Book Now, first check availability: add an Only when condition that Quantity Input's value is less than or equal to (Event's Total Tickets minus Event's Tickets Sold). Create a new Ticket with Status set to Held, Hold Expires set to Current date/time plus 10 minutes, and the selected quantity. Simultaneously, update the Event's Tickets Sold by adding the quantity. This holds the tickets for 10 minutes while the user completes payment. Create a Backend Workflow called release-expired-holds that runs every minute, searches for Tickets where Status is Held and Hold Expires is less than Current date/time, changes their Status to Cancelled, and reduces the Event's Tickets Sold by the cancelled quantity.

Pro tip: Use a Backend Workflow for the hold release to ensure it runs reliably regardless of whether the user is still on the page.

Expected result: Clicking Book Now creates a held ticket and reduces available inventory. Unpaid holds are automatically released after 10 minutes.

4

Process payment with Stripe

After creating the held ticket, redirect the user to a checkout page or show a payment popup. Use the Stripe plugin's Checkout action to create a payment session with the total price (quantity times event price). On successful payment (Stripe's payment success event), update the Ticket's Status from Held to Confirmed, set Purchase Date to Current date/time, and generate a unique Ticket Code using a random string or the Ticket's unique ID. If payment fails or the user abandons, the hold timer will automatically release the tickets.

Expected result: Successful Stripe payment converts the held ticket to Confirmed status with a unique ticket code.

5

Generate and deliver e-tickets via email

After confirming the ticket, send an email to the buyer. Include the Event Title, Date, Venue, Quantity, Ticket Code (which serves as the entry code), and a formatted HTML email with the ticket details styled as a digital ticket. For a QR code, use an API like goqr.me to generate a QR image from the Ticket Code and include the image URL in the email body.

Expected result: The buyer receives an email with their e-ticket containing event details, ticket code, and optionally a QR code.

6

Build a ticket verification page for event staff

Create a page called verify-ticket. Add an Input field for the Ticket Code. When the staff member enters a code and clicks Verify, search for a Ticket where Ticket Code equals the input value. If found and Status is Confirmed, display a green success message with the buyer name, event, and quantity. If not found or Status is Cancelled, show a red error message. Optionally add a Check In button that marks the ticket as used to prevent re-entry.

Expected result: Event staff can enter a ticket code and instantly verify whether it is valid, seeing buyer and event details.

Complete working example

Workflow summary
1TICKET BOOKING SYSTEM WORKFLOW SUMMARY
2=========================================
3
4DATA TYPES:
5 Event
6 - Title, Description, Date, Venue, Cover Image
7 - Total Tickets (number)
8 - Tickets Sold (number, default 0)
9 - Price (number)
10 - Is Active (yes/no)
11
12 Ticket
13 - Event (Event)
14 - Buyer (User), Buyer Email (text)
15 - Quantity (number)
16 - Total Price (number)
17 - Status (Option Set: Held, Confirmed, Cancelled)
18 - Hold Expires (date)
19 - Ticket Code (text)
20 - Purchase Date (date)
21
22WORKFLOW 1: Hold Tickets
23 Trigger: Book Now button clicked
24 Condition: Qty <= (Total Tickets - Tickets Sold)
25 Actions:
26 1. Create Ticket (Status=Held, Hold Expires=now+10min)
27 2. Make changes to Event Tickets Sold + Quantity
28 3. Redirect to checkout / show payment
29
30WORKFLOW 2: Confirm Payment
31 Trigger: Stripe payment success
32 Actions:
33 1. Make changes to Ticket Status=Confirmed
34 2. Set Ticket Code = Generate unique string
35 3. Set Purchase Date = Current date/time
36 4. Send e-ticket email to Buyer
37
38BACKEND WORKFLOW: release-expired-holds
39 Schedule: Every 1 minute (recursive)
40 Actions:
41 1. Search Tickets (Status=Held, Hold Expires < now)
42 2. For each: Status Cancelled
43 3. For each: Event's Tickets Sold - Quantity
44
45PAGE: verify-ticket (staff)
46 Input: Ticket Code
47 Search: Ticket where Code = input
48 Show: Buyer, Event, Quantity, Status
49 Button: Check In mark as Used

Common mistakes when building a ticket booking system in Bubble

Why it's a problem: Not implementing a hold timer for pending payments

How to avoid: Create a hold with a 10-minute expiration and a Backend Workflow that releases expired holds automatically

Why it's a problem: Checking availability on the frontend only

How to avoid: Perform the availability check and ticket creation in a Backend Workflow for atomic operation

Why it's a problem: Using sequential ticket numbers as codes

How to avoid: Generate random alphanumeric codes or use the Ticket's Unique ID, which is a 32-character string

Best practices

  • Use a Backend Workflow for the hold-and-create process to prevent race conditions
  • Set a 10-minute hold expiration and release held tickets automatically on a recurring schedule
  • Generate unique non-sequential ticket codes to prevent forgery
  • Send e-tickets immediately after payment confirmation with QR codes for easy check-in
  • Add a verification page for event staff to scan or enter ticket codes
  • Track Tickets Sold on the Event for quick availability checks without counting related tickets
  • Add Privacy Rules so buyers can only see their own tickets

Still stuck?

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

ChatGPT Prompt

I'm building a ticket booking system in Bubble.io for events. I need ticket selection, a hold timer during checkout, Stripe payment, and e-ticket email delivery. How should I structure the data and handle the booking flow?

Bubble Prompt

Create an event booking page where users select ticket quantity, hold the tickets for 10 minutes during checkout, and receive a confirmation email with a ticket code after payment.

Frequently asked questions

How do I handle different ticket types like VIP and General?

Create a Ticket Type Option Set (VIP, General, Early Bird) with an Attribute for Price. Add a Ticket Type field to the Ticket Data Type. On the booking page, let users select a type and calculate the total based on the type's price.

Can I add a seating map for seat selection?

Bubble does not have a native seating map. Create a simple grid using a Repeating Group where each cell represents a seat. Track seat status (Available, Held, Sold) in the database. For complex venue maps, consider an external seating chart widget embedded via iframe.

How do I prevent scalping and ticket reselling?

Make tickets non-transferable by linking them to the buyer's account. On the verification page, check the buyer's identity. Limit the quantity per order (such as 4 tickets maximum) using an Only when condition on the booking workflow.

What happens if the payment fails after tickets are held?

The tickets remain in Held status until the hold expires (10 minutes). The backend release workflow then cancels them and returns the quantity to available inventory. No manual intervention needed.

Can RapidDev help build a professional ticketing platform?

Yes. RapidDev can help you build enterprise-grade ticketing features including interactive seating maps, dynamic pricing, group bookings, refund management, check-in apps, and analytics dashboards.

How do I generate QR codes for e-tickets?

Use the goqr.me free API by constructing an image URL like https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=YOUR_TICKET_CODE and including it as an image source in the confirmation email.

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.