> ## 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.

# Plantilla base de Supabase

> Clona el starter de suscripciones de Next.js, Supabase y Dodo Payments, con inicio de sesión de Google, un esquema de Drizzle, una Edge Function para webhooks y un dashboard de facturación.

<CardGroup cols={2}>
  <Card title="GitHub Repository" icon="github" href="https://github.com/dodopayments/dodo-supabase-subscription-starter">
    Boilerplate minimalista de suscripciones con Next.js, Supabase y Dodo Payments.
  </Card>

  <Card title="Live Demo" icon="rocket" href="https://dodopayments-supabase-nextjs.vercel.app">
    Explora la demo desplegada.
  </Card>
</CardGroup>

## Descripción general

El starter de suscripciones de Supabase es una aplicación de Next.js 15 y React 19 que vende suscripciones con Dodo Payments. Supabase proporciona el inicio de sesión mediante Google OAuth y la base de datos de Postgres, mientras que Drizzle ORM define el esquema. Una Supabase Edge Function recibe los webhooks de Dodo Payments y almacena los pagos y las suscripciones, y un dashboard básico muestra el plan y las facturas de cada usuario.

Si solo necesitas checkout, Customer Portal y manejadores de rutas de webhooks para una aplicación existente, usa en su lugar un adaptador de framework:

<CardGroup cols={2}>
  <Card title="Next.js Adaptor" icon="code-merge" href="/developer-resources/nextjs-adaptor" />

  <Card title="Express Adaptor" icon="code-merge" href="/developer-resources/express-adaptor" />
</CardGroup>

## Requisitos previos

Antes de comenzar, necesitas:

* Node.js 18 o posterior, o Bun 1.0 o posterior.
* Un proyecto de Supabase. Necesitas su URL, anon key, service role key y cadena de conexión de la base de datos.
* Una cuenta de Dodo Payments, para obtener una API key y un secreto de firma de webhook.
* Un cliente OAuth de Google Cloud, con su Client ID y Client Secret.

## Inicio rápido

<Steps>
  <Step title="Clone and Install">
    Clona el repositorio y, después, instala las dependencias con Bun, npm o pnpm:

    ```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 a Supabase Project">
    Crea un proyecto de Supabase. Los pasos posteriores usan la referencia del proyecto, el subdominio en `https://[your-project-ref].supabase.co`. Copia estos valores:

    * `NEXT_PUBLIC_SUPABASE_URL`, la URL del proyecto
    * `NEXT_PUBLIC_SUPABASE_ANON_KEY`, la anon key
    * `SUPABASE_SERVICE_ROLE_KEY`, la service role key
    * `DATABASE_URL`, la cadena de conexión de la base de datos
  </Step>

  <Step title="Configure Google OAuth">
    En Google Cloud, añade esta URI de redirección autorizada a tu cliente OAuth: `https://[your-project-ref].supabase.co/auth/v1/callback`. Después, en Supabase Auth, habilita el proveedor de Google con tu Client ID y Client Secret.
  </Step>

  <Step title="Configure Dodo Payments">
    Con el interruptor de **Live Mode** de la barra lateral desactivado, crea una API key en **Developer → API Keys**, dentro del dashboard de Dodo Payments. Mantén `DODO_PAYMENTS_ENVIRONMENT` establecido en `test_mode` mientras desarrollas.
  </Step>

  <Step title="Add the Webhook in Dodo Payments">
    En **Developer → Webhooks**, añade un endpoint con esta URL. Desplegarás la función que lo sirve en un paso posterior.

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

    Selecciona los eventos de pago y suscripción que gestionará la función:

    * Eventos de pago: `payment.succeeded`, `payment.failed`, `payment.processing` y `payment.cancelled`
    * Eventos de suscripción: `subscription.active`, `subscription.plan_changed`, `subscription.renewed`, `subscription.on_hold`, `subscription.cancelled`, `subscription.expired` y `subscription.failed`

    Copia el secreto de firma del endpoint. Es el valor de `DODO_WEBHOOK_SECRET`.
  </Step>

  <Step title="Create .env.local">
    Crea un archivo `.env.local` en el directorio raíz:

    ```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
    ```

    La aplicación de Next.js lee todas las variables de este archivo excepto `DODO_WEBHOOK_SECRET`. La Edge Function lee `DODO_WEBHOOK_SECRET` de los secretos de Supabase, que configuras al desplegarla.

    <Warning>
      No subas secretos al repositorio. En entornos desplegados, configúralos como variables de entorno.
    </Warning>
  </Step>

  <Step title="Provision the Database Schema">
    Envía el esquema de Drizzle a tu base de datos de Supabase:

    ```bash theme={null}
    bun run db:push
    # or
    npm run db:push
    # or
    pnpm run db:push
    ```

    <Check>
      Tablas creadas: `users`, `subscriptions`, `payments`.
    </Check>
  </Step>

  <Step title="Deploy the Webhook Function">
    Inicia sesión en Supabase, guarda el secreto de firma como secreto de la función y despliega la Edge Function `dodo-webhook`. Sustituye `[your-project-ref]` por la referencia de tu proyecto:

    ```bash theme={null}
    # login (one-time)
    bunx supabase login
    # or
    npx supabase login

    # store the Dodo Payments signing secret for the function
    npx supabase secrets set DODO_WEBHOOK_SECRET=your-webhook-secret --project-ref [your-project-ref]

    # 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]
    ```

    El script `deploy:webhook` ejecuta `supabase functions deploy dodo-webhook --no-verify-jwt`, para que Dodo Payments pueda llamar a la función sin un token de autenticación de Supabase. Supabase proporciona `SUPABASE_URL` y `SUPABASE_SERVICE_ROLE_KEY` a la función de forma predeterminada.

    Para comprobar el despliegue, envía una solicitud sin firma:

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

    Una respuesta `400` con `Invalid webhook signature` significa que la función está en ejecución y tiene su secreto. Una respuesta `500` con `Server configuration error` significa que `DODO_WEBHOOK_SECRET` no está configurado. Para enviar un evento de prueba firmado, abre el endpoint en **Developer → Webhooks** y usa su pestaña **Testing**.
  </Step>

  <Step title="Create Products and Features">
    En **Products**, dentro del dashboard de Dodo Payments, haz clic en **Add Product** para crear un producto de suscripción para cada plan. Opcionalmente, para mostrar las características del plan en la aplicación, añade una entrada de metadata con la clave `features` y un array JSON de strings como valor. La metadata del producto se verá así:

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

    Los valores de metadata son strings, números o booleanos, así que debes almacenar el array como un string JSON. La interfaz de precios analiza el valor `features` y muestra cada elemento.
  </Step>

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

    Abre [http://localhost:3000](http://localhost:3000) e inicia sesión con Google.
  </Step>
</Steps>

<Check>
  Ahora tienes un SaaS de suscripciones funcional creado con Supabase y Dodo Payments. Para confirmarlo de principio a fin, suscríbete a un plan con una [tarjeta de prueba](/miscellaneous/testing-process). Cuando llegue el webhook, el dashboard mostrará tu nuevo plan.
</Check>

## Qué incluye

* Autenticación mediante Supabase, con Google OAuth configurado
* Checkout de suscripciones mediante Dodo Payments
* Una Supabase Edge Function para webhooks (`dodo-webhook`)
* Un esquema de Drizzle ORM, con los scripts `db:generate` y `db:migrate` para las migraciones
* Un dashboard con facturas, estado de la suscripción y características del plan
* Server actions para cambiar de plan, cancelar una suscripción y restaurar una suscripción cancelada

<Tip>
  Mantén `DODO_PAYMENTS_ENVIRONMENT` establecido en `test_mode` hasta completar las pruebas de principio a fin. Para pasar a producción, establécelo en `live_mode` y utiliza una API key de live mode.
</Tip>

## Archivos y rutas principales

El manejador de webhooks, las rutas de la aplicación y el esquema de la base de datos se encuentran en estos archivos:

<Tabs>
  <Tab title="Edge Function">
    ```text theme={null}
    supabase/functions/dodo-webhook/
      index.ts            # verifies signatures, stores payments and subscriptions
      deno.json           # Deno configuration
    ```
  </Tab>

  <Tab title="Next.js Routes">
    ```text theme={null}
    app/page.tsx                    # redirects to /login or /dashboard
    app/login/page.tsx              # Google sign-in page
    app/dashboard/page.tsx          # plans, subscription, and invoices
    app/checkout/route.ts           # checkout handler
    app/api/auth/callback/route.ts  # OAuth callback
    actions/*                       # server actions
    ```
  </Tab>

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

## Variables de entorno

La aplicación de Next.js y la Edge Function leen estas variables:

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

    `.env.example` no incluye `SUPABASE_SERVICE_ROLE_KEY`, pero el cliente de administración de la aplicación en `lib/supabase/admin.ts` lo necesita. Añádelo manualmente.
  </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">
    La aplicación no lee las credenciales de Google desde las variables de entorno. Introduce el Client ID y el Client Secret en la configuración del proveedor de Google de Supabase Auth y añade esta URI de redirección al cliente OAuth en Google Cloud:

    ```text theme={null}
    https://[your-project-ref].supabase.co/auth/v1/callback
    ```
  </Accordion>
</AccordionGroup>

## Verificación y solución de problemas

<AccordionGroup>
  <Accordion title="Webhook signature invalid (400)">
    * Asegúrate de que el secreto `DODO_WEBHOOK_SECRET` de la función coincida con el secreto de firma del endpoint en el dashboard de Dodo Payments.
    * Confirma que implementaste la función `dodo-webhook` más reciente.
    * La función verifica los encabezados de [Standard Webhooks](https://standardwebhooks.com/) `webhook-id`, `webhook-signature` y `webhook-timestamp`. Asegúrate de que un proxy no los elimine.
  </Accordion>

  <Accordion title="Database push fails">
    * Comprueba la sintaxis de `DATABASE_URL`.
    * La conexión directa (`db.[project-ref].supabase.co:5432`) usa IPv6, a menos que tu proyecto tenga el complemento de IPv4. En una red que solo admite IPv4, usa la cadena de conexión del session pooler en su lugar ([documentación de conexión de Supabase](https://supabase.com/docs/guides/database/connecting-to-postgres)).
    * Espera entre 2 y 3 minutos después de crear el proyecto antes del primer push.
  </Accordion>

  <Accordion title="OAuth redirect mismatch">
    * El URI de redirección debe ser `https://[ref].supabase.co/auth/v1/callback`.
    * Usa el mismo URI en Google Cloud y en el proveedor de Supabase Auth.
  </Accordion>
</AccordionGroup>

<Info>
  Para consultar el repositorio original y los pasos detallados, visita [dodo-supabase-subscription-starter](https://github.com/dodopayments/dodo-supabase-subscription-starter).
</Info>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.