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 URLNEXT_PUBLIC_SUPABASE_ANON_KEY, anon keySUPABASE_SERVICE_ROLE_KEY, service role keyDATABASE_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
DODO_WEBHOOK_SECRET의 값입니다.6
Create .env.local
root directory에 Next.js app은
.env.local file을 생성합니다:DODO_WEBHOOK_SECRET를 제외한 이 file의 모든 variable을 읽습니다. Edge Function은 Supabase secrets에서 DODO_WEBHOOK_SECRET를 읽으며, function을 배포할 때 설정합니다.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를 표시하려면, 선택적으로 Metadata values는 strings, numbers 또는 booleans이므로 array를 JSON string으로 저장합니다. Pricing UI는
features key와 문자열의 JSON array를 value로 갖는 metadata entry를 추가할 수 있습니다. 그러면 product metadata는 다음과 같이 표시됩니다:features value를 parse하고 각 item을 render합니다.10
Run the Dev Server
이제 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:migratescripts가 포함된 Drizzle ORM schema - invoices, subscription status 및 plan features가 포함된 dashboard
- plan 변경, subscription 취소 및 취소된 subscription 복원을 위한 server actions
주요 Files 및 Paths
webhook handler, app routes 및 database schema는 다음 files에 있습니다:- Edge Function
- Next.js Routes
- Database (Drizzle)
Environment Variables
Next.js app과 Edge Function은 다음 variables를 읽습니다:Supabase
Supabase
.env.example에는 SUPABASE_SERVICE_ROLE_KEY가 나열되어 있지 않지만, lib/supabase/admin.ts의 app admin client에는 이 값이 필요합니다. 직접 추가합니다.Dodo Payments
Dodo Payments
Google OAuth
Google OAuth
app은 environment variables에서 Google credentials를 읽지 않습니다. Supabase Auth의 Google provider settings에 Client ID와 Client Secret을 입력하고, Google Cloud의 OAuth client에 다음 redirect URI를 추가합니다:
Verification 및 Troubleshooting
Webhook signature invalid (400)
Webhook signature invalid (400)
- 함수의
DODO_WEBHOOK_SECRETsecret이 Dodo Payments 대시보드에 있는 endpoint의 signing secret과 일치하는지 확인하세요. - 최신
dodo-webhookfunction을 배포했는지 확인하세요. - 함수는 Standard Webhooks headers
webhook-id,webhook-signature및webhook-timestamp를 확인합니다. 프록시가 해당 headers를 제거하지 않는지 확인하세요.
Database push fails
Database push fails
DATABASE_URLsyntax을 확인하세요.- 직접 연결(
db.[project-ref].supabase.co:5432)은 프로젝트에 IPv4 add-on이 없는 경우 IPv6을 사용합니다. IPv4 전용 네트워크에서는 대신 session pooler connection string을 사용하세요(Supabase connection docs). - 프로젝트를 생성한 후 첫 번째 push를 수행하기 전에 2~3분 기다리세요.
OAuth redirect mismatch
OAuth redirect mismatch
- redirect URI는
https://[ref].supabase.co/auth/v1/callback여야 합니다. - Google Cloud와 Supabase Auth provider에서 동일한 URI를 사용하세요.
원본 repository와 자세한 단계는 dodo-supabase-subscription-starter를 참조하세요.