A B2B SaaS with per-seat billing, a full admin panel, and a Stripe billing portal — launched in 10 weeks.
The client had a working no-code prototype built in Bubble and a waiting list of 80 businesses ready to pay. They needed the real product: multi-tenant, proper auth, Stripe subscription management with seat-based billing, and an admin dashboard. We delivered in 10 weeks.
Bubble prototype that couldn't handle real multi-tenancy or the Stripe billing complexity the product required
The client had invested 6 months building a Bubble prototype of their B2B project management tool. The prototype was good enough to get 80 businesses on a waiting list who'd verbally committed to paying. The problem: Bubble's multi-tenancy model couldn't isolate tenant data the way enterprise buyers require, the Stripe billing integration was limited to simple subscription plans (no seat-based pricing, no annual billing discount, no per-plan feature gating), and the performance on the most data-intensive screens was unacceptable.
They tried to extend the Bubble prototype further before rebuilding, but every new feature revealed another architectural constraint. After two months of going sideways, they came to us.
Production-ready B2B SaaS launched to paying customers in 10 weeks
Stack: Next.js 14 App Router, Convex (database and real-time), Clerk Organisations (multi-tenancy and auth), Stripe Billing with Stripe Customer Portal, Vercel (deployment).
Multi-tenancy: Clerk Organisations for tenant isolation. Each business account gets a Clerk Org. All database queries use the orgId from the Clerk session — no cross-tenant data access is architecturally possible.
Stripe billing: Per-seat subscription with three plans (Starter, Growth, Scale). Plan feature gates enforced at the API layer using the Stripe subscription metadata synced to Convex. Annual billing option with 2 months free (20% discount). Stripe Customer Portal for self-serve subscription management, seat changes, and billing history — no custom billing UI to maintain.
Admin panel: Super-admin panel for managing all tenant accounts, manually adjusting seats, viewing subscription status, and overriding feature access for trial extensions. Built on the same Next.js codebase with a separate admin-only route group.
Performance: Convex's real-time queries replaced the Bubble page-load-on-every-action pattern. The most data-intensive screen (project board with 200+ tasks) loads in under 400ms.
One honest number to start.
Fixed-scope, fixed-price. The number below is the starting point — final scope is built from your brief.
Production-ready B2B SaaS launched to paying customers in 10 weeks
Three steps, every time.
The same repeatable engagement on every project. No surprises, no mystery, no billable ambiguity.
Brief & discovery.
We send you questions, then get on a call. Output: a written scope with every step, feature, and integration listed.
Build & ship.
Fixed schedule, weekly reviews. No scope creep unless you change the scope — and if you do, we reprice it transparently.
Warranty & retainer.
30-day warranty on every launch. Most clients stay on a monthly retainer for ongoing features and maintenance.
Why Fixed-Price Matters Here
The client was burning runway and couldn't afford a time-and-materials engagement that might run 30% over. Fixed scope, fixed price meant they could plan their launch timeline and investor update around a committed delivery date.
Related engagements.
Questions, answered.
The migration was a rebuild, not a migration. The Bubble data was exported and imported into Convex via a migration script. The UI was rebuilt from scratch in Next.js — the Bubble prototype served as the functional spec, not the code base.
All 80 customers were migrated into the new product's Stripe billing on launch day. 67 converted to paid plans within the first two weeks.
B2B SaaS with multi-tenancy, Stripe seat billing, and admin panel: from $35k. Fixed-price.
Tell Ryel about your project.
Describe what you’re building and what outcome you need. You’ll have a written, fixed-price scope within the week.