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

How to Build a Coupon and Discount Code System in Bubble

A coupon system in Bubble requires a Coupon Data Type with fields for code, discount type, value, expiry date, and usage limits. You create a validation workflow that checks the entered code against your database, verifies it has not expired or exceeded its limit, then applies the discount to the order total. This tutorial covers the full system from code generation to checkout application.

What you'll learn

  • How to design a Coupon Data Type with all necessary fields
  • How to generate unique coupon codes in Bubble
  • How to validate and apply coupons at checkout
  • How to enforce usage limits and expiry dates
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner6 min read25-30 minAll Bubble plansMarch 2026RapidDev Engineering Team
TL;DR

A coupon system in Bubble requires a Coupon Data Type with fields for code, discount type, value, expiry date, and usage limits. You create a validation workflow that checks the entered code against your database, verifies it has not expired or exceeded its limit, then applies the discount to the order total. This tutorial covers the full system from code generation to checkout application.

Overview: Building a Coupon System in Bubble

This tutorial walks through creating a complete coupon and discount code system for your Bubble e-commerce app. You will build the data structure, create an admin interface for generating codes, implement validation logic for expiry and usage limits, and apply percentage or flat discounts to order totals at checkout.

Prerequisites

  • A Bubble app with a basic e-commerce or checkout flow
  • An Order or Cart Data Type already set up
  • Understanding of Bubble workflows and conditional logic
  • Familiarity with Data Types and fields in Bubble

Step-by-step guide

1

Create the Coupon Data Type with required fields

Go to the Data tab and click 'New type' to create 'Coupon'. Add fields: 'code' (text) for the unique string; 'discount_type' (text) for 'percentage' or 'flat'; 'discount_value' (number) for the amount; 'expiry_date' (date); 'max_uses' (number); 'current_uses' (number, default 0); 'is_active' (yes/no, default yes); and 'min_order_amount' (number) for minimum order requirements.

Pro tip: Add a 'created_by' field linked to User so you can track which admin created each coupon.

Expected result: A Coupon Data Type exists with all fields for code, discount configuration, usage tracking, and activation status.

2

Build an admin page to create and manage coupons

Create a new page called 'admin-coupons'. Add input fields for each Coupon field: text input for code, dropdown for discount type (percentage/flat), number input for value, date picker for expiry, and number inputs for max uses and minimum order. Add a 'Generate Random Code' button that sets the code input to a random string using 'Calculate random string' (length 8, alphanumeric). Add a 'Create Coupon' button with a workflow that creates a new Coupon Thing. Below, add a Repeating Group showing all coupons with a 'Deactivate' button per row.

Expected result: An admin page where you can create coupons with custom or random codes, set parameters, and manage existing coupons.

3

Add a coupon input field to your checkout page

On your checkout page, add a text input labeled 'Coupon Code' and an 'Apply' button next to it. Add a text element below for validation messages (initially hidden). Create custom states on the page: 'applied_coupon' (type Coupon) and 'discount_amount' (type number). These store the validated coupon and calculated discount for the order total.

Expected result: The checkout page has a coupon input, Apply button, message area, and custom states to hold applied coupon data.

4

Create the coupon validation workflow

On the Apply button click, create a workflow. Step 1: Do a Search for Coupons where code equals the input value (use :lowercase on both sides), is_active is yes, expiry_date is greater than Current date/time, and current_uses is less than max_uses. Only when search count is greater than 0. Step 2: Set 'applied_coupon' state to the first result. Step 3: Calculate discount — if discount_type is 'percentage', set discount_amount to subtotal times discount_value divided by 100; if 'flat', set to discount_value. Step 4: Show success message. Add a second workflow for when search count equals 0 showing an error.

Pro tip: Add a check that the order subtotal meets the coupon's min_order_amount with a specific error like 'Minimum order of $50 required'.

Expected result: Valid coupons show a success message and store the discount; invalid or expired codes show an error message.

5

Apply the discount to the order total display

Update your order total text element's dynamic expression to: Subtotal minus page's discount_amount (or 0 if empty). Add a conditional: 'When applied_coupon is not empty' — show the original price with strikethrough and the discounted total. Add a 'Remove coupon' link that resets both custom states to empty.

Expected result: The checkout shows the original price crossed out and the discounted total when a valid coupon is applied.

6

Increment coupon usage count on successful order

In your order completion workflow (payment success or order placed), add 'Make changes to a Thing' targeting the applied_coupon. Set current_uses to current_uses plus 1. If current_uses now equals max_uses, also set is_active to no. Store the coupon reference on the Order by adding a 'coupon_used' field (type Coupon) to the Order Data Type.

Expected result: Each successful order increments usage count, and the coupon auto-deactivates when it reaches maximum uses.

Complete working example

Workflow summary
1COUPON SYSTEM COMPLETE WORKFLOW SUMMARY
2==========================================
3
4DATA TYPE: Coupon
5 Fields:
6 code (text) unique coupon string
7 discount_type (text) 'percentage' or 'flat'
8 discount_value (number)
9 expiry_date (date)
10 max_uses (number)
11 current_uses (number, default 0)
12 is_active (yes/no, default yes)
13 min_order_amount (number)
14 created_by (User)
15
16PAGE CUSTOM STATES:
17 applied_coupon (type: Coupon)
18 discount_amount (type: number)
19
20WORKFLOW: Apply Coupon Button Click
21 Step 1 (Only when search count > 0):
22 Search: Coupon where
23 code:lowercase = Input value:lowercase
24 is_active = yes
25 expiry_date > Current date/time
26 current_uses < max_uses
27 Step 2: Set state applied_coupon = first item
28 Step 3: Set state discount_amount =
29 percentage: subtotal * discount_value / 100
30 flat: discount_value
31 Step 4: Show success message
32
33WORKFLOW: Invalid Coupon
34 Condition: search count = 0
35 Show error: 'Invalid or expired code'
36
37WORKFLOW: Order Completion
38 Step 1: Create Order with coupon_used = applied_coupon
39 Step 2: Make changes to applied_coupon:
40 current_uses = current_uses + 1
41 is_active = no (when current_uses = max_uses)
42
43DISPLAY:
44 Total = Subtotal - discount_amount
45 Show strikethrough original when coupon applied

Common mistakes when building a Coupon and Discount Code System in Bubble

Why it's a problem: Not checking the expiry date in the validation search

How to avoid: Add constraint: expiry_date greater than Current date/time

Why it's a problem: Forgetting to increment current_uses after a successful order

How to avoid: Add a 'Make changes to Thing' step in your order completion workflow that increments current_uses

Why it's a problem: Using case-sensitive code comparison

How to avoid: Use the ':lowercase' operator on both the input value and search constraint

Why it's a problem: Applying the discount after payment instead of before

How to avoid: Calculate the discounted total before initiating payment and pass the discounted amount to the processor

Best practices

  • Use random alphanumeric codes (8+ characters) to prevent guessing
  • Always validate coupons server-side in a workflow, not just client-side
  • Store the used coupon reference on the Order for audit trail and analytics
  • Add minimum order amounts to prevent tiny orders from using high-value coupons
  • Create an admin dashboard showing coupon usage statistics
  • Use ':lowercase' on both sides of code comparisons for case-insensitive matching
  • Set Privacy Rules on the Coupon type so non-admin users cannot view discount values

Still stuck?

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

ChatGPT Prompt

I'm building an e-commerce app in Bubble.io and need a coupon code system with percentage and flat discounts, expiry dates, and usage limits. What Data Types and workflows do I need?

Bubble Prompt

Build a coupon system for my checkout page. Create a Coupon data type with code, discount type (percentage or flat), value, expiry date, and max uses. Add a coupon input with validation and apply the discount to the order total.

Frequently asked questions

Can I create single-use coupons unique per customer?

Yes. Add a 'used_by' list field (type User) to Coupon. In validation, check the current user is not in used_by. After redemption, add the user to the list.

How do I create bulk coupon codes for a promotion?

Use a recursive backend workflow that generates one coupon with a random code, then schedules itself until the desired count is reached. Trigger it from your admin page.

Can I apply multiple coupons to a single order?

You can by changing the custom state to a list of Coupons and stacking discounts. Most apps limit to one coupon per order to simplify logic.

How do I prevent coupon code abuse?

Combine protections: random 8+ character codes, per-user limits, expiry dates, minimum order amounts, and usage tracking.

Can RapidDev help build a complete e-commerce system with coupons?

Yes. RapidDev can build your entire e-commerce backend including product catalog, cart, checkout, coupons, payments, and order management in Bubble.

Should I use an Option Set or Data Type for discount types?

Use an Option Set for discount type choices (percentage, flat). Option Sets are cached and load instantly with zero WU cost, ideal for static dropdown values.

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.