Article

Supabase + Stripe: the fastest way to add subscriptions to your SaaS

Step-by-step guide to wiring up Stripe billing with Supabase auth and row-level security in under 2 hours.

Why this combination works so well

Stripe handles money. Supabase handles everything else. They were designed with developers in mind, have excellent TypeScript support, and — crucially — work together without a lot of glue code.

Here's the pattern we use on every SaaS project.

Step 1: Set up Supabase auth (20 min)

Use Supabase's built-in auth. Email/password and magic links are configured in two minutes. For OAuth (Google, GitHub), add the credentials in the dashboard — no extra code needed.

The key table you need:

create table profiles (
  id uuid references auth.users on delete cascade,
  stripe_customer_id text,
  plan text default 'free',
  primary key (id)
);
create table profiles (
  id uuid references auth.users on delete cascade,
  stripe_customer_id text,
  plan text default 'free',
  primary key (id)
);
create table profiles (
  id uuid references auth.users on delete cascade,
  stripe_customer_id text,
  plan text default 'free',
  primary key (id)
);

Create a trigger that auto-creates a profile when a user signs up.

Step 2: Wire up Stripe (30 min)

Install the Stripe SDK and create a webhook handler. The events you care about:

  • checkout.session.completed — user paid, activate their plan

  • customer.subscription.updated — plan changed

  • customer.subscription.deleted — subscription cancelled

Each webhook handler updates the plan column in your profiles table.

Step 3: Row Level Security (20 min)

This is where Supabase shines. Instead of writing permission checks in every API route, you write them once in the database:

create policy "pro users can access premium features"
  on premium_table for select
  using (
    exists (
      select 1 from profiles
      where id = auth.uid()
      and plan = 'pro'
    )
  );
create policy "pro users can access premium features"
  on premium_table for select
  using (
    exists (
      select 1 from profiles
      where id = auth.uid()
      and plan = 'pro'
    )
  );
create policy "pro users can access premium features"
  on premium_table for select
  using (
    exists (
      select 1 from profiles
      where id = auth.uid()
      and plan = 'pro'
    )
  );

Now it's impossible for a free user to access paid features — even with a compromised API key.

Step 4: The Stripe Checkout flow (30 min)

Create a server action that generates a Checkout session:

export async function createCheckoutSession(priceId: string) {
  const session = await stripe.checkout.sessions.create({
    customer: stripeCustomerId,
    line_items: [{ price: priceId, quantity: 1 }],
    mode: 'subscription',
    success_url: `${baseUrl}/dashboard?upgraded=true`,
    cancel_url: `${baseUrl}/pricing`,
  })
  redirect(session.url!)
}
export async function createCheckoutSession(priceId: string) {
  const session = await stripe.checkout.sessions.create({
    customer: stripeCustomerId,
    line_items: [{ price: priceId, quantity: 1 }],
    mode: 'subscription',
    success_url: `${baseUrl}/dashboard?upgraded=true`,
    cancel_url: `${baseUrl}/pricing`,
  })
  redirect(session.url!)
}
export async function createCheckoutSession(priceId: string) {
  const session = await stripe.checkout.sessions.create({
    customer: stripeCustomerId,
    line_items: [{ price: priceId, quantity: 1 }],
    mode: 'subscription',
    success_url: `${baseUrl}/dashboard?upgraded=true`,
    cancel_url: `${baseUrl}/pricing`,
  })
  redirect(session.url!)
}

That's it. The webhook handles the rest.

The result

A fully working subscription system — auth, payments, access control, cancellation — in under 2 hours. We've done this enough times that we have a template. First build from scratch: 2 hours. Subsequent builds: 45 minutes.

About this article

Reading Time

1 min read

Category

Engeenring

Written by

The Novabuild Team

Build with Novabuild

Turn your idea into a live product. We ship in days, not months.

Available now — 2 slots left this month

Ready to build something great?

We ship products fast. Let's talk about your idea.

Replies in 48 hours

You own all the code

Average ship in 7 days

5.0 — Rated by 50+ founders

NOVABUILD

We build products at the speed of thought. AI-native agency for founders who move fast.

© 2026 Novabuild Agency. All rights reserved.

NOVABUILD

We build products at the speed of thought. AI-native agency for founders who move fast.

© 2026 Novabuild Agency. All rights reserved.

NOVABUILD

We build products at the speed of thought. AI-native agency for founders who move fast.

© 2026 Novabuild Agency. All rights reserved.

Create a free website with Framer, the website builder loved by startups, designers and agencies.