Skip to main content

GitHub Repository

Boilerplate mínimo de assinatura com Next.js, Supabase e Dodo Payments.

Live Demo

Explore a demonstração implantada.

Visão geral

O starter de assinatura do Supabase é um app Next.js 15 e React 19 que vende assinaturas com o Dodo Payments. O Supabase fornece o login OAuth do Google e o banco de dados Postgres, enquanto o Drizzle ORM define o schema. Uma Supabase Edge Function recebe os webhooks do Dodo Payments e armazena pagamentos e assinaturas, e um painel básico mostra o plano e as faturas de cada usuário. Se você precisa apenas de checkout, Customer Portal e handlers de rota de webhook para um app existente, use um adaptador de framework:

Next.js Adaptor

Express Adaptor

Pré-requisitos

Antes de começar, você precisa de:
  • Node.js 18 ou posterior, ou Bun 1.0 ou posterior.
  • Um projeto do Supabase. Você precisa da URL, da chave anon, da chave de função de serviço e da string de conexão do banco de dados.
  • Uma conta do Dodo Payments, para obter uma chave de API e um segredo de assinatura de webhook.
  • Um cliente OAuth do Google Cloud, para obter o Client ID e o Client Secret.

Início rápido

1

Clone and Install

Clone o repositório e instale as dependências com Bun, npm ou pnpm:
2

Create a Supabase Project

Crie um projeto do Supabase. As etapas posteriores usam a referência do projeto, o subdomínio em https://[your-project-ref].supabase.co. Copie estes valores:
  • NEXT_PUBLIC_SUPABASE_URL, a URL do projeto
  • NEXT_PUBLIC_SUPABASE_ANON_KEY, a chave anon
  • SUPABASE_SERVICE_ROLE_KEY, a chave de função de serviço
  • DATABASE_URL, a string de conexão do banco de dados
3

Configure Google OAuth

No Google Cloud, adicione este URI de redirecionamento autorizado ao seu cliente OAuth: https://[your-project-ref].supabase.co/auth/v1/callback. Em seguida, no Supabase Auth, habilite o provedor do Google com seu Client ID e Client Secret.
4

Configure Dodo Payments

Com o seletor Live Mode desativado na barra lateral, crie uma chave de API em Developer → API Keys, no painel do Dodo Payments. Mantenha DODO_PAYMENTS_ENVIRONMENT definido como test_mode enquanto estiver desenvolvendo.
5

Add the Webhook in Dodo Payments

Em Developer → Webhooks, adicione um endpoint com esta URL. Você implantará a função que o disponibiliza em uma etapa posterior.
Selecione os eventos de pagamento e assinatura que a função tratará:
  • Eventos de pagamento: payment.succeeded, payment.failed, payment.processing e payment.cancelled
  • Eventos de assinatura: subscription.active, subscription.plan_changed, subscription.renewed, subscription.on_hold, subscription.cancelled, subscription.expired e subscription.failed
Copie o segredo de assinatura do endpoint. Ele é o valor de DODO_WEBHOOK_SECRET.
6

Create .env.local

Crie um arquivo .env.local no diretório raiz:
O app Next.js lê todas as variáveis deste arquivo, exceto DODO_WEBHOOK_SECRET. A Edge Function lê DODO_WEBHOOK_SECRET dos secrets do Supabase, que você define ao implantá-la.
Não faça commit dos secrets. Em ambientes implantados, defina-os como variáveis de ambiente.
7

Provision the Database Schema

Envie o schema do Drizzle para o banco de dados do Supabase:
Tabelas criadas: users, subscriptions, payments.
8

Deploy the Webhook Function

Faça login no Supabase, armazene o segredo de assinatura como um secret da função e implante a Edge Function dodo-webhook. Substitua [your-project-ref] pela referência do seu projeto:
O script deploy:webhook executa supabase functions deploy dodo-webhook --no-verify-jwt, para que o Dodo Payments possa chamar a função sem um token de autenticação do Supabase. O Supabase fornece SUPABASE_URL e SUPABASE_SERVICE_ROLE_KEY à função por padrão.Para verificar a implantação, envie uma requisição sem assinatura:
cURL
Uma resposta 400 com Invalid webhook signature significa que a função está em execução e possui o secret. Uma resposta 500 com Server configuration error significa que DODO_WEBHOOK_SECRET não está definido. Para enviar um evento de teste assinado, abra o endpoint em Developer → Webhooks e use a aba Testing.
9

Create Products and Features

Em Products, no painel do Dodo Payments, clique em Add Product para criar um produto de assinatura para cada plano. Opcionalmente, para listar os recursos do plano no app, adicione uma entrada de metadata com a chave features e um array JSON de strings como valor. A metadata do produto ficará assim:
Os valores de metadata são strings, números ou booleanos, portanto armazene o array como uma string JSON. A interface de preços analisa o valor de features e renderiza cada item.
10

Run the Dev Server

Abra http://localhost:3000 e faça login com o Google.
Agora você tem um SaaS de assinatura funcional, estruturado com Supabase e Dodo Payments. Para confirmá-lo de ponta a ponta, assine um plano usando um cartão de teste. Depois que o webhook chegar, o painel mostrará seu novo plano.

O que está incluído

  • Autenticação por meio do Supabase, com OAuth do Google configurado
  • Checkout de assinatura por meio do Dodo Payments
  • Uma Supabase Edge Function para webhooks (dodo-webhook)
  • Um schema do Drizzle ORM, com os scripts db:generate e db:migrate para migrações
  • Um painel com faturas, status da assinatura e recursos do plano
  • Server actions para alterar planos, cancelar uma assinatura e restaurar uma assinatura cancelada
Mantenha DODO_PAYMENTS_ENVIRONMENT definido como test_mode até concluir os testes de ponta a ponta. Para entrar em produção, defina-o como live_mode e use uma chave de API do modo live.

Arquivos e caminhos principais

O handler de webhook, as rotas do app e o schema do banco de dados estão nestes arquivos:

Variáveis de ambiente

O app Next.js e a Edge Function leem estas variáveis:
.env.example não lista SUPABASE_SERVICE_ROLE_KEY, mas o cliente administrativo do app em lib/supabase/admin.ts precisa dele. Adicione-o manualmente.
O app não lê as credenciais do Google a partir de variáveis de ambiente. Insira o Client ID e o Client Secret nas configurações do provedor do Google no Supabase Auth e adicione este URI de redirecionamento ao cliente OAuth no Google Cloud:

Verificação e solução de problemas

  • Certifique-se de que o secret da função DODO_WEBHOOK_SECRET corresponda ao signing secret do endpoint no dashboard do Dodo Payments.
  • Confirme que você fez o deploy da versão mais recente da função dodo-webhook.
  • A função verifica os headers do Standard Webhooks webhook-id, webhook-signature e webhook-timestamp. Certifique-se de que um proxy não os remova.
  • Verifique a sintaxe de DATABASE_URL.
  • A conexão direta (db.[project-ref].supabase.co:5432) usa IPv6, a menos que seu projeto tenha o complemento de IPv4. Em uma rede somente IPv4, use a connection string do session pooler (documentação de conexão do Supabase).
  • Aguarde de 2 a 3 minutos após criar o projeto antes do primeiro push.
  • O redirect URI deve ser https://[ref].supabase.co/auth/v1/callback.
  • Use a mesma URI no Google Cloud e no provedor de autenticação do Supabase.
Para acessar o repositório original e as etapas detalhadas, consulte dodo-supabase-subscription-starter.
Última modificação em 28 de setembro de 2026