Skip to main content

GitHub Repository

최소 구성의 Next.js, Supabase 및 Dodo Payments subscription boilerplate입니다.

Live Demo

배포된 demo를 확인하세요.

개요

Supabase subscription starter는 Dodo Payments로 subscription을 판매하는 Next.js 15 및 React 19 app입니다. Supabase는 Google OAuth sign-in과 Postgres database를 제공하고, Drizzle ORM이 schema를 정의합니다. Supabase Edge Function은 Dodo Payments webhooks를 수신하여 payments와 subscriptions를 저장하며, 기본 dashboard에는 각 사용자의 plan과 invoices가 표시됩니다. 기존 app에 checkout, Customer Portal 및 webhook route handlers만 필요한 경우에는 대신 framework adaptor를 사용하세요:

Next.js Adaptor

Express Adaptor

사전 요구 사항

시작하기 전에 다음이 필요합니다:
  • Node.js 18 이상 또는 Bun 1.0 이상
  • Supabase project. URL, anon key, service role key 및 database connection string이 필요합니다.
  • API key와 webhook signing secret을 위한 Dodo Payments account
  • Client ID와 Client Secret을 위한 Google Cloud OAuth client

빠른 시작

1

Clone and Install

repository를 clone한 다음 Bun, npm 또는 pnpm으로 dependencies를 설치합니다:
2

Create a Supabase Project

Supabase project를 생성합니다. 이후 단계에서는 https://[your-project-ref].supabase.co의 subdomain인 project reference를 사용합니다. 다음 값을 복사합니다:
  • NEXT_PUBLIC_SUPABASE_URL, project URL
  • NEXT_PUBLIC_SUPABASE_ANON_KEY, anon key
  • SUPABASE_SERVICE_ROLE_KEY, service role key
  • DATABASE_URL, database connection string
3

Configure Google OAuth

Google Cloud에서 OAuth client에 다음 authorized redirect URI를 추가합니다: https://[your-project-ref].supabase.co/auth/v1/callback. 그런 다음 Supabase Auth에서 Client ID와 Client Secret을 사용하여 Google provider를 활성화합니다.
4

Configure Dodo Payments

sidebar의 Live Mode switch가 꺼진 상태에서 Dodo Payments dashboard의 Developer → API Keys 아래에서 API key를 생성합니다. 개발하는 동안 DODO_PAYMENTS_ENVIRONMENT를 test_mode로 유지합니다.
5

Add the Webhook in Dodo Payments

Developer → Webhooks에서 이 URL을 사용하는 endpoint를 추가합니다. 이 endpoint를 제공하는 function은 이후 단계에서 배포합니다.
function이 처리할 payment 및 subscription events를 선택합니다:
  • Payment events: payment.succeeded, payment.failed, payment.processing 및 payment.cancelled
  • Subscription events: subscription.active, subscription.plan_changed, subscription.renewed, subscription.on_hold, subscription.cancelled, subscription.expired 및 subscription.failed
endpoint의 signing secret을 복사합니다. 이는 DODO_WEBHOOK_SECRET의 값입니다.
6

Create .env.local

root directory에 .env.local file을 생성합니다:
Next.js app은 DODO_WEBHOOK_SECRET를 제외한 이 file의 모든 variable을 읽습니다. Edge Function은 Supabase secrets에서 DODO_WEBHOOK_SECRET를 읽으며, function을 배포할 때 설정합니다.
secrets를 commit하지 마세요. deployed environments에서는 이를 environment variables로 설정합니다.
7

Provision the Database Schema

Drizzle schema를 Supabase database에 push합니다:
생성된 tables: users, subscriptions, payments.
8

Deploy the Webhook Function

Supabase에 로그인하고 signing secret을 function secret으로 저장한 다음 dodo-webhook Edge Function을 배포합니다. [your-project-ref]를 project reference로 바꿉니다:
deploy:webhook script는 supabase functions deploy dodo-webhook --no-verify-jwt를 실행하므로 Dodo Payments가 Supabase auth token 없이 function을 호출할 수 있습니다. Supabase는 기본적으로 SUPABASE_URL 및 SUPABASE_SERVICE_ROLE_KEY를 function에 제공합니다.배포를 확인하려면 unsigned request를 보냅니다:
cURL
Invalid webhook signature가 포함된 400 response는 function이 실행 중이며 secret을 가지고 있음을 의미합니다. Server configuration error가 포함된 500 response는 DODO_WEBHOOK_SECRET가 설정되지 않았음을 의미합니다. signed test event를 보내려면 Developer → Webhooks에서 endpoint를 열고 Testing tab을 사용합니다.
9

Create Products and Features

Dodo Payments dashboard의 Products에서 Add Product를 클릭하여 각 plan에 대한 subscription product를 생성합니다. app에 plan features를 표시하려면, 선택적으로 features key와 문자열의 JSON array를 value로 갖는 metadata entry를 추가할 수 있습니다. 그러면 product metadata는 다음과 같이 표시됩니다:
Metadata values는 strings, numbers 또는 booleans이므로 array를 JSON string으로 저장합니다. Pricing UI는 features value를 parse하고 각 item을 render합니다.
10

Run the Dev Server

http://localhost:3000을 열고 Google로 sign in합니다.
이제 Supabase와 Dodo Payments로 구성된 정상 작동하는 subscription SaaS scaffold를 갖추었습니다. end-to-end로 확인하려면 test card로 plan을 구독합니다. webhook이 도착하면 dashboard에 새 plan이 표시됩니다.

포함된 항목

  • Google OAuth가 구성된 Supabase를 통한 authentication
  • Dodo Payments를 통한 subscription checkout
  • webhook을 위한 Supabase Edge Function (dodo-webhook)
  • migration을 위한 db:generate 및 db:migrate scripts가 포함된 Drizzle ORM schema
  • invoices, subscription status 및 plan features가 포함된 dashboard
  • plan 변경, subscription 취소 및 취소된 subscription 복원을 위한 server actions
end-to-end tests를 완료할 때까지 DODO_PAYMENTS_ENVIRONMENT를 test_mode로 유지합니다. live 환경으로 전환하려면 live_mode로 설정하고 live mode API key를 사용합니다.

주요 Files 및 Paths

webhook handler, app routes 및 database schema는 다음 files에 있습니다:

Environment Variables

Next.js app과 Edge Function은 다음 variables를 읽습니다:
.env.example에는 SUPABASE_SERVICE_ROLE_KEY가 나열되어 있지 않지만, lib/supabase/admin.ts의 app admin client에는 이 값이 필요합니다. 직접 추가합니다.
app은 environment variables에서 Google credentials를 읽지 않습니다. Supabase Auth의 Google provider settings에 Client ID와 Client Secret을 입력하고, Google Cloud의 OAuth client에 다음 redirect URI를 추가합니다:

Verification 및 Troubleshooting

  • 함수의 DODO_WEBHOOK_SECRET secret이 Dodo Payments 대시보드에 있는 endpoint의 signing secret과 일치하는지 확인하세요.
  • 최신 dodo-webhook function을 배포했는지 확인하세요.
  • 함수는 Standard Webhooks headers webhook-id, webhook-signature 및 webhook-timestamp를 확인합니다. 프록시가 해당 headers를 제거하지 않는지 확인하세요.
  • DATABASE_URL syntax을 확인하세요.
  • 직접 연결(db.[project-ref].supabase.co:5432)은 프로젝트에 IPv4 add-on이 없는 경우 IPv6을 사용합니다. IPv4 전용 네트워크에서는 대신 session pooler connection string을 사용하세요(Supabase connection docs).
  • 프로젝트를 생성한 후 첫 번째 push를 수행하기 전에 2~3분 기다리세요.
  • redirect URI는 https://[ref].supabase.co/auth/v1/callback여야 합니다.
  • Google Cloud와 Supabase Auth provider에서 동일한 URI를 사용하세요.
원본 repository와 자세한 단계는 dodo-supabase-subscription-starter를 참조하세요.
마지막 수정일 2026년 9월 28일