Set up crowdfunding in Bubble by creating Campaign and Pledge data types, building campaign pages with progress bars and pledge tiers, implementing a pledge workflow with running totals, and adding deadline logic for all-or-nothing funding. This gives founders the tools to launch fundraising features without writing code.
Overview: Setting Up Crowdfunding in Bubble
This tutorial walks you through building crowdfunding features in Bubble. You will create the data structure for campaigns and pledges, build campaign pages with goals, deadlines, and progress bars, set up pledge tier selection and payment, track pledged amounts in real time, and implement all-or-nothing vs. flexible funding models. This is ideal for platforms that host product launches, community projects, or creative endeavors.
Prerequisites
- A Bubble account with an existing app
- Stripe plugin installed and configured for payments
- Basic understanding of Bubble data types and workflows
- Familiarity with Repeating Groups and conditional formatting
Step-by-step guide
Create the Campaign and Pledge data types
Create the Campaign and Pledge data types
Go to the Data tab and create a Campaign data type with fields: title (text), description (text), creator (User), goal_amount (number), amount_pledged (number, default 0), end_date (date), image (image), funding_type (Option Set: All-or-nothing, Flexible), and status (Option Set: Active, Funded, Failed, Closed). Then create a PledgeTier data type with fields: campaign (Campaign), name (text, e.g., Early Bird), amount (number), description (text), limit (number), and claimed_count (number, default 0). Finally, create a Pledge data type with fields: campaign (Campaign), backer (User), tier (PledgeTier), amount (number), and stripe_charge_id (text).
Expected result: Three data types exist: Campaign, PledgeTier, and Pledge with all required fields.
Build the campaign creation page
Build the campaign creation page
Create a page called create-campaign. Add input fields for title, description, goal amount, end date (Date Picker), and image (File Uploader). Add a Dropdown for funding type linked to the Option Set. Add a section for pledge tiers: a Repeating Group showing existing tiers with an Add Tier button that opens a popup form for tier name, amount, description, and limit. The workflow for saving: When Button Create Campaign is clicked — Create a new Campaign with all field values and creator = Current User. For tiers, create them in a separate workflow triggered by the Add Tier popup's save button.
Expected result: Creators can build a campaign with details, funding type, and multiple pledge tiers.
Design the campaign page with progress bar
Design the campaign page with progress bar
Create a page called campaign with type Campaign. Display the image, title, description, creator name, end date, and funding type. For the progress bar, add two Groups: an outer Group with a fixed width and a colored background, and an inner Group whose width is set to a percentage: Current Page Campaign's amount_pledged / Current Page Campaign's goal_amount * 100 (capped at 100). Above the bar, display the amount pledged, the goal, and the percentage. Add a conditional: When Current date/time > Campaign's end_date, show Campaign Ended instead of the pledge section.
Pro tip: Use a conditional max of 100 on the inner group width so the bar does not exceed the container when funding surpasses the goal.
Expected result: The campaign page shows a visual progress bar that fills as pledges come in, along with all campaign details.
Set up the pledge workflow with Stripe
Set up the pledge workflow with Stripe
Below the progress bar, add a Repeating Group showing PledgeTiers filtered by the current Campaign. Each cell shows the tier name, amount, description, remaining spots (limit minus claimed_count), and a Back This button. The workflow: When Back This is clicked — Only when Current date/time < Campaign's end_date and (tier's limit is empty or tier's claimed_count < tier's limit). Trigger Stripe Checkout with amount = tier's amount * 100. On payment success: Create a new Pledge with campaign, backer, tier, and amount. Then Make changes to Campaign: amount_pledged = amount_pledged + tier's amount. Make changes to PledgeTier: claimed_count = claimed_count + 1.
Expected result: Backers can select a tier, pay via Stripe, and the campaign's pledged amount and tier count update automatically.
Implement all-or-nothing deadline logic
Implement all-or-nothing deadline logic
Create a backend workflow called check_campaign_deadline with a parameter campaign_id (text). In it: Look up the Campaign by ID. If amount_pledged >= goal_amount, set status to Funded. If amount_pledged < goal_amount and funding_type is All-or-nothing, set status to Failed and trigger refund workflows for each Pledge. If funding_type is Flexible, set status to Funded regardless of amount. Schedule this backend workflow to run at each campaign's end_date using Schedule API workflow when the campaign is created.
Pro tip: For the refund step in all-or-nothing campaigns, use the Stripe API Connector to call the refund endpoint with each pledge's stripe_charge_id.
Expected result: Campaigns automatically close at their deadline with the correct funded or failed status based on the funding type.
Add the backer dashboard and campaign listing
Add the backer dashboard and campaign listing
Create a my-pledges page showing a Repeating Group of Pledges where backer = Current User, displaying campaign title, tier, amount, and campaign status. Create a campaigns listing page showing all Active campaigns in a Repeating Group sorted by end_date ascending (ending soonest first). Add filter options for funding type and category. Each cell shows the image, title, progress percentage, amount pledged, and days remaining (calculated as Campaign's end_date minus Current date/time in days).
Expected result: Backers can view their pledge history, and visitors can browse all active campaigns with progress indicators.
Complete working example
1CROWDFUNDING FEATURE — WORKFLOW SUMMARY2========================================34DATA TYPES:5 Campaign6 - title (text)7 - description (text)8 - creator (User)9 - goal_amount (number)10 - amount_pledged (number, default 0)11 - end_date (date)12 - image (image)13 - funding_type (Option Set: All-or-nothing / Flexible)14 - status (Option Set: Active / Funded / Failed / Closed)1516 PledgeTier17 - campaign (Campaign)18 - name (text)19 - amount (number)20 - description (text)21 - limit (number)22 - claimed_count (number, default 0)2324 Pledge25 - campaign (Campaign)26 - backer (User)27 - tier (PledgeTier)28 - amount (number)29 - stripe_charge_id (text)3031WORKFLOW 1: Create campaign32 Event: Button Create Campaign is clicked33 Action 1: Create new Campaign34 (all fields from form inputs)35 status = Active36 Action 2: Schedule API workflow check_campaign_deadline37 Scheduled date = Campaign's end_date38 campaign_id = Result of Step 1's unique ID3940WORKFLOW 2: Back a campaign41 Event: Button Back This is clicked42 Only when: Current date/time < Campaign's end_date43 AND tier's claimed_count < tier's limit (or limit empty)44 Action 1: Stripe Checkout45 Amount = Current cell's PledgeTier's amount * 10046 On payment success:47 Action 2: Create new Pledge48 campaign = Current Page Campaign49 backer = Current User50 tier = Current cell's PledgeTier51 amount = tier's amount52 stripe_charge_id = Stripe charge ID53 Action 3: Make changes to Campaign54 amount_pledged = amount_pledged + tier's amount55 Action 4: Make changes to PledgeTier56 claimed_count = claimed_count + 15758BACKEND WORKFLOW: check_campaign_deadline59 Parameter: campaign_id (text)60 Step 1: Search for Campaign by ID61 Step 2 (funded): Make changes to Campaign62 Only when: amount_pledged >= goal_amount63 status = Funded64 Step 3 (failed — all-or-nothing): Make changes65 Only when: amount_pledged < goal_amount66 AND funding_type is All-or-nothing67 status = Failed68 Step 4 (refund): Schedule refund workflow on list69 Only when: status just set to Failed70 List = Search for Pledges (campaign = this campaign)71 Step 5 (flexible funded): Make changes72 Only when: funding_type is Flexible73 status = Funded7475PROGRESS BAR:76 Outer Group: fixed width, light gray background77 Inner Group: width = (amount_pledged / goal_amount * 100)%78 Max width: 100%79 Background: greenCommon mistakes when building crowdfunding in Bubble
Why it's a problem: Not updating the amount_pledged field atomically
How to avoid: Use the increment pattern: amount_pledged = amount_pledged + pledge amount. Bubble handles this server-side to minimize race conditions.
Why it's a problem: Allowing pledges after the campaign deadline
How to avoid: Add Only when Current date/time < Campaign's end_date to the pledge workflow and hide the pledge buttons when the deadline has passed.
Why it's a problem: Forgetting to schedule the deadline check backend workflow
How to avoid: Schedule the check_campaign_deadline backend workflow at the campaign's end_date when the campaign is created.
Best practices
- Use Option Sets for campaign status and funding type to keep values consistent
- Schedule a backend workflow at campaign creation time to handle deadline logic automatically
- Store stripe_charge_id on each Pledge so you can process refunds for failed all-or-nothing campaigns
- Cap the progress bar width at 100% so it does not overflow when campaigns exceed their goal
- Add tier limits and track claimed counts to create urgency for limited reward tiers
- Show days remaining as a countdown to create urgency on the campaign page
- Add Privacy Rules so backers can only view their own pledge details
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I am building a crowdfunding platform in Bubble.io similar to Kickstarter. I need campaign pages with goals and deadlines, pledge tiers, progress bars, Stripe payments, and all-or-nothing funding logic. What data types and workflows do I need?
Build crowdfunding features for my app. Create Campaign, PledgeTier, and Pledge data types. Build a campaign page with a progress bar and pledge tiers. Set up Stripe payment workflows and schedule a backend workflow to check campaign deadlines for all-or-nothing funding.
Frequently asked questions
How do refunds work for failed all-or-nothing campaigns?
When the deadline check marks a campaign as Failed, a backend workflow iterates through all Pledges and calls the Stripe Refund API using each pledge's stripe_charge_id to return funds to backers.
Can campaign creators edit their campaign after launching?
You can allow edits to description and image while the campaign is active. Do not allow changes to goal_amount or end_date after pledges have been received, as this could undermine backer trust.
How do I display a countdown timer?
Calculate the remaining time as Campaign's end_date minus Current date/time and display it formatted as days, hours, and minutes. The value updates automatically because Current date/time is dynamic.
Can I add stretch goals?
Yes. Create a StretchGoal data type linked to Campaign with a target_amount and reward_description. Display them on the campaign page with conditionals that highlight achieved stretch goals.
Is Stripe required for crowdfunding?
Stripe is the most straightforward payment option in Bubble. You could use other gateways via the API Connector, but Stripe has the best plugin support and handles refunds easily.
Can RapidDev help build a full crowdfunding platform?
Yes. RapidDev specializes in Bubble development and can help build complete crowdfunding platforms with advanced features like social sharing, backer updates, reward fulfillment tracking, and analytics dashboards.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation