Billing & Subscriptions
Overview
This feature governs the monetization of Bambu using Stripe (and potentially Lemon Squeezy). It isolates 'Free' users from 'Pro' users, enforcing hard resource limits.
Why it exists
As a robust SaaS, we must limit costly automated actions (like AI Chat Usage, Automated SMS, and unlimited Product Storage) to paying subscribers to maintain business profitability.
User flow
- The user goes to
app/dashboard/settings/billing. - They see their active 'Free' plan and click 'Upgrade to Pro'.
- They are redirected to a Stripe Checkout Session.
- Upon successful payment, they hit the
successpage and the app unlocks Premium toggles seamlessly.
UI walkthrough


Backend logic
Stripe Webhooks are critical here:
- The user pays Stripe.
- Stripe sends an HTTP POST to
app/api/webhooks/stripe/route.ts. - The server authenticates the payload via cryptographically signed hashes.
- Prisma updates the
public.subscriptionstable, attaching the user'sbusinessId. - Next.js triggers a NextCache revalidation, forcing the UI to recognize the Pro status.
Database tables involved
Global public Schema:
Subscription: The master object of truth linking a Strip Customer ID to a Business ID.Plan: Defined system configurations (e.g., name, cost, maxUsers limit).
API endpoints
POST /api/billing/checkout- Initializes Stripe session.POST /api/webhooks/stripe- Solely for Stripe to report status updates to Bambu.
Permissions / roles
- Owner: Only the tenant owner can manage billing subscriptions.
Edge cases
- "Past Due" statuses: If a payment card fails during a renewal, the Webhook downgrades the system status to
past_due, which conditionally locks out Pro features with a grace period warning.
Validation rules
- Webhook signature validation relies on the
STRIPE_WEBHOOK_SECRETenvironment variable. Ensure this matches identically between Stripe and.env.
Error handling
- If the Webhook fails processing, Stripe will retry up to 3 days. A dead-letter queue log is recommended to monitor failures.
Screenshots placeholders

Troubleshooting
- User paid but plan didn't upgrade: A mismatch in the webhook secret or a timeout. Check the Stripe Developer Logs and trigger a manual sync script (e.g.,
verify-entitlements.ts).