In-app purchases in Bubble work through a credit or coin system where users buy credits via Stripe Checkout, credits are stored in the User Data Type, and the app deducts credits when users access premium features. This tutorial covers the complete purchase flow from Stripe integration to credit management.
Overview: In-App Purchases in Bubble
Since Bubble apps run in the browser, traditional mobile in-app purchases do not apply. Instead, you build a credit or virtual currency system where users buy credits via Stripe and spend them on premium features. This pattern works for AI tools, content platforms, marketplace services, and any app with consumable features.
Prerequisites
- A Bubble app with user accounts
- A Stripe account configured with the Stripe plugin
- Backend workflows enabled (Starter+)
- Basic understanding of Bubble workflows
Step-by-step guide
Design the credit system data structure
Design the credit system data structure
Add a field called credits (type: number, default: 0) to the User Data Type. Create a Data Type called CreditTransaction with fields: user (User), amount (number — positive for purchases, negative for usage), description (text), stripe_session_id (text, optional), and Created Date (auto). Create a CreditPackage Option Set with attributes: name (text), credits (number), price_cents (number) — e.g., Starter Pack / 100 credits / 999 ($9.99).
Expected result: A credit system with balance tracking, transaction history, and predefined purchase packages.
Build the credit purchase page with Stripe Checkout
Build the credit purchase page with Stripe Checkout
Create a pricing page showing your CreditPackage options in a Repeating Group. Each cell displays the package name, credit amount, and price. The Buy button triggers a workflow that creates a Stripe Checkout session via the Stripe plugin with the package's price. After Stripe redirects back on success, a webhook fires to add credits to the user's account.
Expected result: Users can select a credit package and complete purchase through Stripe Checkout.
Handle the Stripe webhook to add credits
Handle the Stripe webhook to add credits
Create a backend API workflow called stripe-webhook. When Stripe sends a checkout.session.completed event, the workflow: (1) Finds the user by their Stripe customer ID or session metadata. (2) Adds the purchased credits to the user's credits field. (3) Creates a CreditTransaction record with a positive amount. (4) Returns a 200 response to Stripe. Configure the webhook URL in your Stripe dashboard.
Pro tip: Always add credits in the webhook, not in the frontend redirect. The redirect can fail, but webhooks are reliable and retried by Stripe.
Expected result: Credits are reliably added to the user's account after successful payment.
Deduct credits when users access premium features
Deduct credits when users access premium features
When a user triggers a premium feature (e.g., generating AI content, downloading a report), add a condition: Only when Current User's credits >= required amount. In the workflow, use Make Changes to Current User to subtract the required credits. Create a CreditTransaction with a negative amount and a description of the feature used. If insufficient credits, show a popup directing them to the purchase page.
Expected result: Credits are deducted when premium features are used, with a transaction record created.
Display the credit balance and transaction history
Display the credit balance and transaction history
Show the user's current credit balance in the header or account page: Current User's credits. Build a transaction history page with a Repeating Group of CreditTransactions where user = Current User, sorted by Created Date descending. Each cell shows the date, description, and amount (color-coded: green for positive, red for negative).
Expected result: Users can see their credit balance and a history of all purchases and usage.
Complete working example
1IN-APP PURCHASE SYSTEM SUMMARY2================================34DATA STRUCTURE:5 User additions: credits (number, default: 0)6 CreditTransaction: user, amount, description, stripe_session_id, Created Date7 CreditPackage (Option Set):8 - Starter: 100 credits, $9.99 (999 cents)9 - Pro: 500 credits, $39.99 (3999 cents)10 - Enterprise: 2000 credits, $99.99 (9999 cents)1112PURCHASE WORKFLOW:13 Buy button clicked:14 1. Stripe → Create Checkout Session15 → Line items: package price16 → Metadata: user_id, package_name, credits17 → Success URL: /purchase-success18 → Cancel URL: /pricing19 2. Redirect to Stripe Checkout2021WEBHOOK (backend workflow: stripe-webhook):22 Event: checkout.session.completed23 Actions:24 1. Find user from session metadata25 2. Make Changes to User: credits + package credits26 3. Create CreditTransaction (positive amount)27 4. Return 2002829CREDIT DEDUCTION (premium feature button):30 Condition: Only when Current User's credits >= 1031 Actions:32 1. Make Changes to Current User: credits - 1033 2. Create CreditTransaction: amount=-10, description="AI generation"34 3. Execute the premium feature35 If insufficient:36 → Show popup: "You need more credits. [Buy Credits]"3738BALANCE DISPLAY:39 Header: "[Current User's credits] credits"40 Transaction history: RG of CreditTransactions, sorted by date descCommon mistakes when implementing in-app purchases in Bubble.io: Step-by-Step Guide
Why it's a problem: Adding credits on the Stripe redirect instead of the webhook
How to avoid: Always add credits in the Stripe webhook handler, which is reliable and retried by Stripe if your server does not respond.
Why it's a problem: Not checking credit balance before deducting
How to avoid: Add an Only When condition checking Current User's credits >= required amount before the deduction action
Why it's a problem: Not recording credit transactions
How to avoid: Create a CreditTransaction record for every purchase and every deduction with descriptive details
Best practices
- Process credit additions via Stripe webhooks, not frontend redirects
- Always check credit balance before deducting to prevent negative balances
- Record every credit change as a CreditTransaction for auditing
- Show the credit balance prominently so users know their remaining credits
- Offer multiple credit packages at different price points
- Send a low-balance email notification when credits drop below a threshold
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I want to add a credit-based in-app purchase system to my Bubble.io app. Users buy credits via Stripe and spend them on premium features. Can you walk me through the data structure, Stripe integration, and credit management workflows?
Build a credit purchase system for my app. Users should buy credit packages via Stripe, see their balance, and spend credits on premium features. Set up the data structure, Stripe webhook, and deduction workflows.
Frequently asked questions
Can I offer a subscription instead of credits?
Yes. Use Stripe subscriptions with a recurring billing cycle. Store the subscription status on the User and check it for feature access instead of credit balances.
How do I handle refunds?
Create a backend workflow triggered by Stripe's charge.refunded webhook. Deduct the refunded credits from the user's balance and create a negative CreditTransaction.
Can I give free credits to new users?
Yes. In your signup workflow, set credits to a starter amount (e.g., 10 free credits) and create a CreditTransaction with description 'Welcome bonus'.
Do credits expire?
Not by default. If you want expiring credits, add an expiry_date field to CreditTransaction and build a scheduled workflow that removes expired credits.
How do I prevent credit fraud?
Always process credit additions server-side via Stripe webhooks, never from the frontend. Use Stripe's signature verification. Validate all credit deductions server-side. RapidDev can help build fraud-resistant payment systems.
Can I sell credits for different feature categories?
Yes. Create separate credit types (e.g., AI credits, download credits) with separate balance fields, or use a single currency and vary the cost per feature.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation