From Tool to Product: Implementing FlowBoard's SaaS Foundation

Developer hunched over laptop, Stripe dashboard glowing on screen, payment flow diagrams scattered on desk

This week I shipped the unglamorous but critical infrastructure that turns FlowBoard from a local tool into a monetizable product: user authentication, subscription management, and payment processing. The kind of work that doesn't make for exciting demos but determines whether you have a business or a hobby project.

The User Journey Problem

Before this week, FlowBoard had a working node-based editor. You could build image generation pipelines, save projects, and export prompts. But there was no account system—just local storage. No way to limit features, track usage, or accept money. The fundamental pieces you need to actually sell software as a service.

I tackled the full signup-to-payment flow: user creates account, confirms email, logs in to dashboard, sees their trial status, hits the paywall when trial expires, upgrades via Stripe checkout, and has their account updated via webhook. Each step had its own surprises.

Edge Functions and the Deno Runtime Shift

The first wall I hit was Supabase edge functions. I'd written them months ago, and in the interim Supabase updated their Deno runtime. My existing webhook code that had worked fine suddenly failed with cryptic import errors.

The fix required updating to Stripe SDK v14 with the Deno-compatible fetch client, switching from deprecated std/http/serve imports to native Deno.serve(), and using constructEventAsync for webhook signature verification instead of the synchronous version. None of this was documented in one place—I pieced it together from GitHub issues and the Stripe Deno SDK readme.

// Old approach (broken)
import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'

// New approach (working)
Deno.serve(async (req) => {
  const event = await stripe.webhooks.constructEventAsync(
    body,
    signature,
    webhookSecret,
    undefined,
    Stripe.createSubtleCryptoProvider()
  )
  // ...
})

The Stale Session Trap

After fixing the edge functions, I had a more subtle bug: users would sign up, confirm their email, and get redirected back to the app—but still see the login page instead of their dashboard. The problem? Supabase auth state wasn't refreshing after email confirmation.

The solution was adding a dedicated "check your email" screen that polls for session changes. When the user confirms and returns, the app catches the new session and routes to dashboard. It sounds obvious in retrospect, but email confirmation flows create this timing gap where your client-side auth state and server-side reality diverge.

Gating Features Without Breaking UX

With auth working, I needed to actually limit things for trial users. FlowBoard has "pro" node types—Scene nodes for 3D integration, FX nodes for post-processing, and so on. After trial expiration, these should be locked.

I built a useProGate hook that checks subscription status and trial expiry. Pro nodes render with a lock icon and disabled state. Clicking them opens the upgrade modal instead of adding them to the canvas. The dashboard shows trial users their project count ("3 of 6 projects") and disables "New Project" when they hit the limit.

The key decision: be explicit about limits rather than hiding features entirely. Users should see what they're missing so they understand the value proposition.

The Webhook Dance

Stripe webhooks are where payment flows get interesting. The happy path is simple: user completes checkout, Stripe fires checkout.session.completed, your webhook updates their subscription status. But production reality includes: webhook signature validation (crucial for security), idempotency (webhooks can fire multiple times), database transactions (what if the update partially fails?), and logging (when something goes wrong at 3am, you need breadcrumbs).

Promo Codes and Launch Prep

The final piece was enabling Stripe promotion codes. One line of config (allow_promotion_codes: true) opens up discount strategies—LAUNCH50 for early adopters, partnership codes for potential college collaborations, whatever makes sense. The infrastructure is there now.

I also locked down the trial period at 3 days. Long enough to evaluate the tool seriously, short enough to create urgency. The trial-expired state shows clearly in the UI and funnels users toward checkout.

What's Next

FlowBoard's SaaS bones are solid now. The immediate next steps are pre-launch: marketing site polish, landing page graphics, and a thorough testing pass on the payment flow with real cards. Then it's time to put it in front of actual users and see what breaks.

Building payment infrastructure is the kind of work that separates "I made a thing" from "I'm selling a thing." Not glamorous, but necessary. And now it's done.