> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dodopayments.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Supabase Boilerplate

> Use the official Next.js + Supabase + Dodo Payments subscription starter to ship subscriptions fast. Includes auth, database schema, webhook handler, and pricing UI.

<CardGroup cols={2}>
  <Card title="GitHub Repository" icon="github" href="https://github.com/dodopayments/dodo-supabase-subscription-starter">
    Minimal Next.js + Supabase + Dodo Payments subscription boilerplate
  </Card>

  <Card title="Live Demo" icon="rocket" href="https://dodopayments-supabase-nextjs.vercel.app">
    Explore the deployed demo
  </Card>
</CardGroup>

## Overview

A production-ready boilerplate for subscriptions using Next.js 15, React 19, Supabase, Drizzle ORM, and Dodo Payments. It ships with Google OAuth, subscription checkout, webhook handling, database schema, and a basic dashboard.

<Info>
  If you need only route handlers for an existing app, see the dedicated adaptors: <a href="/developer-resources/nextjs-adaptor">Next.js Adaptor</a> and <a href="/developer-resources/express-adaptor">Express Adaptor</a>.
</Info>

## Prerequisites

* Node.js 18+ (or Bun 1.0+)
* Supabase project (URL, Anon key, Service role key, Database URL)
* Dodo Payments account (API key, Webhook secret)
* Google Cloud OAuth client (Client ID and Secret)

## Quickstart

<Steps>
  <Step title="Clone and install">
    ```bash theme={null}
    git clone https://github.com/dodopayments/dodo-supabase-subscription-starter.git
    cd dodo-supabase-subscription-starter
    # choose one
    bun install
    # or
    npm install
    # or
    pnpm install
    ```
  </Step>

  <Step title="Create Supabase project">
    Create a Supabase project and copy:

    * NEXT\_PUBLIC\_SUPABASE\_URL
    * NEXT\_PUBLIC\_SUPABASE\_ANON\_KEY
    * SUPABASE\_SERVICE\_ROLE\_KEY
    * DATABASE\_URL (Connection string)
  </Step>

  <Step title="Configure Google OAuth">
    Set the redirect URI to: `https://[your-project-ref].supabase.co/auth/v1/callback` in Google Cloud, then enable Google provider in Supabase Auth using your Client ID and Secret.
  </Step>

  <Step title="Configure Dodo Payments">
    Generate an API key and Webhook secret from the Dodo dashboard. Set environment to `test_mode` while developing.
  </Step>

  <Step title="Create .env.local">
    ```env theme={null}
    # Supabase
    NEXT_PUBLIC_SUPABASE_URL=https://your-project-ref.supabase.co
    NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
    SUPABASE_SERVICE_ROLE_KEY=your-service-role

    # Database
    DATABASE_URL=postgresql://postgres:[password]@db.[project-ref].supabase.co:5432/postgres

    # Dodo Payments
    DODO_PAYMENTS_API_KEY=your-dodo-api-key
    DODO_WEBHOOK_SECRET=your-webhook-secret
    DODO_PAYMENTS_ENVIRONMENT=test_mode
    ```

    <Warning>
      Never commit secrets. Use environment variables in deployment environments.
    </Warning>
  </Step>

  <Step title="Provision database schema">
    ```bash theme={null}
    bun run db:push
    # or
    npm run db:push
    # or
    pnpm run db:push
    ```

    <Check>
      Tables created: `users`, `subscriptions`, `payments`.
    </Check>
  </Step>

  <Step title="Deploy webhook function">
    ```bash theme={null}
    # login (one-time)
    bunx supabase login
    # or
    npx supabase login

    # deploy the edge function
    bun run deploy:webhook --project-ref [your-project-ref]
    # or
    npm run deploy:webhook -- --project-ref [your-project-ref]
    # or
    pnpm run deploy:webhook --project-ref [your-project-ref]
    ```

    ```bash cURL theme={null}
    curl -X POST \
      'https://[your-project-ref].supabase.co/functions/v1/dodo-webhook' \
      -H 'Content-Type: application/json' \
      -H 'Dodo-Signature: <signature>' \
      -d '{"type":"payment.succeeded","data":{}}'
    ```
  </Step>

  <Step title="Add webhook in Dodo Payments">
    Set endpoint URL to:

    ```text theme={null}
    https://[your-project-ref].supabase.co/functions/v1/dodo-webhook
    ```

    Select payment and subscription events.
  </Step>

  <Step title="Create products and features">
    In Dodo dashboard → Products → Create Product. Optionally add metadata:

    ```json theme={null}
    {
      "features": ["Feature 1", "Feature 2", "Feature 3"]
    }
    ```

    The pricing UI reads this `features` array and renders it dynamically.
  </Step>

  <Step title="Run the dev server">
    ```bash theme={null}
    bun run dev
    # or
    npm run dev
    # or
    pnpm run dev
    ```

    Open [http://localhost:3000](http://localhost:3000).
  </Step>
</Steps>

## What’s included

* Authentication via Supabase (Google OAuth configured)
* Subscription checkout via Dodo Payments
* Supabase Edge Function for webhooks (`dodo-webhook`)
* Drizzle ORM schema and migrations
* Dashboard with invoices, subscription status, and plan features

<Tip>
  Keep `DODO_PAYMENTS_ENVIRONMENT` as `test_mode` until you complete end-to-end tests.
</Tip>

## Key files and paths

<Tabs>
  <Tab title="Edge Function">
    ```text theme={null}
    supabase/functions/dodo-webhook/
      index.ts            # webhook handler verifying signatures
      deno.json           # permissions
    ```
  </Tab>

  <Tab title="Next.js routes">
    ```text theme={null}
    app/(marketing)/*     # landing + pricing UI
    app/(dashboard)/*     # protected pages
    app/api/*             # server actions & helpers
    ```
  </Tab>

  <Tab title="Database (Drizzle)">
    ```text theme={null}
    lib/db/schema.ts      # users, subscriptions, payments
    lib/db/index.ts       # client
    ```
  </Tab>
</Tabs>

## Environment variables

<AccordionGroup>
  <Accordion title="Supabase">
    ```env theme={null}
    NEXT_PUBLIC_SUPABASE_URL=
    NEXT_PUBLIC_SUPABASE_ANON_KEY=
    SUPABASE_SERVICE_ROLE_KEY=
    DATABASE_URL=
    ```
  </Accordion>

  <Accordion title="Dodo Payments">
    ```env theme={null}
    DODO_PAYMENTS_API_KEY=
    DODO_WEBHOOK_SECRET=
    DODO_PAYMENTS_ENVIRONMENT=test_mode|live_mode
    ```
  </Accordion>

  <Accordion title="Google OAuth">
    ```env theme={null}
    GOOGLE_CLIENT_ID=
    GOOGLE_CLIENT_SECRET=
    ```
  </Accordion>
</AccordionGroup>

## Verification and troubleshooting

<AccordionGroup>
  <Accordion title="Webhook signature invalid (401)">
    * Ensure `DODO_WEBHOOK_SECRET` matches the value from Dodo dashboard
    * Confirm you deployed the latest `dodo-webhook` function
    * Verify the header name is correct in your function (Dodo-Signature)
  </Accordion>

  <Accordion title="Database push fails">
    * Check `DATABASE_URL` syntax and Supabase network egress
    * Wait \~2–3 minutes after project creation before first push
  </Accordion>

  <Accordion title="OAuth redirect mismatch">
    * Redirect URI must be `https://[ref].supabase.co/auth/v1/callback`
    * Ensure the same in Google Cloud and Supabase Auth provider
  </Accordion>
</AccordionGroup>

<Check>
  You now have a working subscription SaaS scaffolded with Supabase and Dodo Payments.
</Check>

<Info>
  Original repository and detailed steps: <a href="https://github.com/dodopayments/dodo-supabase-subscription-starter">dodo-supabase-subscription-starter</a>.
</Info>
