Build a complete donation system in Bubble with preset and custom donation amounts, Stripe payment processing, donor receipts, and a donation tracking dashboard. This tutorial covers one-time and recurring donations so you can accept contributions from supporters without writing a single line of code.
Overview: Setting Up a Donation System in Bubble
Whether you are building a nonprofit platform, a crowdfunding page, or a community support tool, accepting donations is a core feature. This tutorial walks you through creating a donation form with preset amounts ($10, $25, $50, $100) and a custom amount input, connecting Stripe for secure payment processing, sending automated email receipts, and building an admin dashboard to track total donations over time.
Prerequisites
- A Bubble account with an app ready to edit
- A Stripe account (test mode is fine for development)
- The Stripe.js plugin installed in your Bubble app
- Basic familiarity with Bubble's Design and Workflow tabs
Step-by-step guide
Create the Donation data type
Create the Donation data type
Go to the Data tab and click Data types. Click Create a new type and name it Donation. Add these fields: amount (number), donor_name (text), donor_email (text), donation_date (date), is_recurring (yes/no), stripe_charge_id (text), and donor (User, optional — for logged-in donors). This data type stores every donation your app receives.
Expected result: A Donation data type appears in your Data tab with all the required fields.
Design the donation form page
Design the donation form page
Switch to the Design tab. Create a new page called donate. Add a Group container with Column layout. Inside it, place a Text element with the heading 'Support Our Mission'. Below it, add four Button elements in a Row group for preset amounts: $10, $25, $50, $100. Below the buttons, add an Input element labeled Custom Amount (content format: Integer). Add two more inputs for Donor Name and Donor Email. Finally, add a Checkbox labeled 'Make this a monthly donation' and a Button labeled 'Donate Now'.
Pro tip: Use conditional formatting to highlight the selected preset amount button — set a custom state called selected_amount on the page and change each button's background color when selected_amount equals its value.
Expected result: A clean donation form with preset amount buttons, a custom amount input, donor details fields, and a submit button.
Wire up the preset amount buttons with custom states
Wire up the preset amount buttons with custom states
Click the page element in the Element Tree and add a custom state called selected_amount (type: number). For each preset amount button ($10, $25, $50, $100), create a workflow: When Button $10 is clicked → Set state of page → selected_amount = 10. Repeat for each amount. On the Custom Amount input, add a workflow: When Input Custom Amount's value is changed → Set state of page → selected_amount = Input Custom Amount's value. This ensures one value is always selected.
Expected result: Clicking any preset button or typing a custom amount updates the selected_amount state on the page.
Configure Stripe and process the payment
Configure Stripe and process the payment
Go to the Plugins tab and open the Stripe.js plugin settings. Enter your Stripe publishable key and secret key from your Stripe Dashboard (use test keys during development). Back on the donate page, select the 'Donate Now' button and create a workflow. Add the action Stripe.js → Charge the current user. Set amount to page's selected_amount * 100 (Stripe uses cents). Set currency to usd. Set description to 'Donation from ' merged with Input Donor Name's value. For recurring donations, use Stripe.js → Subscribe the current user to a plan instead.
Pro tip: Always multiply by 100 when passing amounts to Stripe — $25 becomes 2500 cents.
Expected result: Clicking Donate Now charges the donor's card via Stripe for the selected amount.
Save the donation record and send a receipt
Save the donation record and send a receipt
In the same workflow, after the Stripe charge action, add a Create a new thing action. Type: Donation. Set amount to page's selected_amount, donor_name to Input Donor Name's value, donor_email to Input Donor Email's value, donation_date to Current date/time, is_recurring to Checkbox Recurring's value, and stripe_charge_id to Result of step (Stripe charge)'s id. Then add a Send email action with the recipient as Input Donor Email's value, subject 'Thank you for your donation!', and body including the amount and date.
Expected result: Each donation is saved in your database and the donor receives an email receipt.
Build the admin donation dashboard
Build the admin donation dashboard
Create a new page called admin-donations. Add a Text element showing 'Total Donations: $' followed by Do a search for Donations:each item's amount:sum. Below it, add a Repeating Group with data source Do a search for Donations, sorted by donation_date descending. In each cell, display donor_name, amount, donation_date formatted as MM/DD/YYYY, and is_recurring as a badge. Add a search input above the Repeating Group that filters donations by donor_name contains.
Pro tip: Restrict access to this page by adding a Page is loaded workflow with a condition: if Current User's admin field is not yes, navigate to the home page.
Expected result: An admin dashboard showing total donation amount, a searchable list of all donations, and recurring donation indicators.
Complete working example
1DONATION SYSTEM — WORKFLOW SUMMARY2===================================34DATA MODEL5 Donation:6 - amount (number)7 - donor_name (text)8 - donor_email (text)9 - donation_date (date)10 - is_recurring (yes/no)11 - stripe_charge_id (text)12 - donor (User, optional)1314PAGE: donate15 Custom State: selected_amount (number) on Page1617 WORKFLOW: Preset Button Clicked ($10)18 Trigger: When Button $10 is clicked19 Step 1: Set state → page → selected_amount = 102021 WORKFLOW: Preset Button Clicked ($25)22 Trigger: When Button $25 is clicked23 Step 1: Set state → page → selected_amount = 252425 (Repeat for $50, $100)2627 WORKFLOW: Custom Amount Changed28 Trigger: When Input Custom Amount value is changed29 Step 1: Set state → page → selected_amount = Input value3031 WORKFLOW: Process Donation32 Trigger: When Button "Donate Now" is clicked33 Only when: page's selected_amount > 034 Step 1: Stripe.js → Charge current user35 - Amount: page's selected_amount * 10036 - Currency: usd37 - Description: "Donation from " + donor name38 Step 2: Create a new Donation39 - amount: page's selected_amount40 - donor_name: Input Donor Name's value41 - donor_email: Input Donor Email's value42 - donation_date: Current date/time43 - is_recurring: Checkbox value44 - stripe_charge_id: Result of step 1's id45 Step 3: Send email46 - To: Input Donor Email's value47 - Subject: "Thank you for your donation!"48 - Body: Receipt with amount and date4950PAGE: admin-donations51 Total: Do a search for Donations:each item's amount:sum52 Repeating Group: Donations sorted by date descending53 Access control: redirect non-admin usersCommon mistakes when setting up a donation system in Bubble.io: Step-by-Step Guide
Why it's a problem: Forgetting to multiply the amount by 100 for Stripe
How to avoid: Always multiply your dollar amount by 100 before sending to Stripe: page's selected_amount * 100.
Why it's a problem: Not validating the donation amount before charging
How to avoid: Add an Only when condition to the workflow: page's selected_amount > 0. Show an alert if no amount is selected.
Why it's a problem: Using live Stripe keys during development
How to avoid: Use pk_test and sk_test keys from your Stripe Dashboard during development. Switch to live keys only when deploying.
Best practices
- Use Stripe test mode and test card number 4242 4242 4242 4242 during development
- Always save the Stripe charge ID in your database for refund and dispute handling
- Add input validation to ensure a valid email format before sending receipts
- Include a confirmation popup after successful donation showing the amount and a thank-you message
- For recurring donations, create a Stripe subscription rather than a one-time charge
- Add Privacy Rules to the Donation data type so only admins can view all records
- Test the full flow from donation to receipt email before publishing your app
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I'm building a donation page in Bubble.io with preset amounts ($10, $25, $50, $100), a custom amount field, Stripe payment processing, email receipts, and an admin dashboard. Walk me through the data model, workflows, and Stripe integration step by step.
Create a donation page with four preset amount buttons ($10, $25, $50, $100) and a custom amount input. Add a Stripe payment workflow that charges the selected amount, saves a Donation record to the database, and sends an email receipt to the donor.
Frequently asked questions
Can I accept donations without a Stripe account?
Stripe is the most common payment processor for Bubble apps. Alternatives include PayPal (via API Connector) or the PayPal plugin, but Stripe offers the smoothest Bubble integration.
How do I handle recurring monthly donations?
Use Stripe subscriptions instead of one-time charges. Create a Stripe product and price in your Stripe Dashboard, then use the Subscribe the current user action in your Bubble workflow.
Can donors give without creating an account?
Yes. You do not need to require user registration. Collect donor name and email in form fields and process the payment via Stripe without requiring a Bubble login.
How do I issue refunds for donations?
Use the Stripe Dashboard to issue refunds manually, or set up an API Connector call to Stripe's refund endpoint using the stored stripe_charge_id from your Donation record.
Is there a minimum donation amount?
Stripe requires a minimum charge of $0.50 USD. Set your minimum preset amount to at least $1 and add validation on the custom amount field to enforce this.
Can RapidDev help me build a more complex donation platform?
Yes. RapidDev can help you build advanced donation features like campaign-specific fundraising pages, donor tiers with perks, tax-deductible receipt generation, and Stripe Connect for multi-organization fundraising.
How do I generate tax receipts for donors?
Create an email template that includes your organization's tax ID, the donation amount, date, and a statement that no goods or services were provided. Send this via the Send email action after each donation.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation