Skip to main content

GitHub Repository

Minimales Next.js-, Supabase- und Dodo Payments-Abonnement-Boilerplate.

Live Demo

Sieh dir die bereitgestellte Demo an.

Übersicht

Der Supabase-Abonnement-Starter ist eine Next.js-15- und React-19-App, die Abonnements mit Dodo Payments verkauft. Supabase stellt die Google-OAuth-Anmeldung und die Postgres-Datenbank bereit, während Drizzle ORM das Schema definiert. Eine Supabase Edge Function empfängt Dodo Payments-Webhooks und speichert Zahlungen und Abonnements. Ein einfaches Dashboard zeigt den Plan und die Rechnungen jedes Benutzers an. Wenn du nur Checkout, Customer Portal und Webhook-Route-Handler für eine bestehende App benötigst, verwende stattdessen einen Framework-Adapter:

Next.js Adaptor

Express Adaptor

Voraussetzungen

Bevor du beginnst, benötigst du:
  • Node.js 18 oder höher bzw. Bun 1.0 oder höher.
  • Ein Supabase-Projekt. Du benötigst dessen URL, Anon-Key, Service-Role-Key und Datenbankverbindungszeichenfolge.
  • Ein Dodo Payments-Konto für einen API-Key und ein Webhook-Signaturgeheimnis.
  • Einen Google-Cloud-OAuth-Client mit Client ID und Client Secret.

Schnellstart

1

Clone and Install

Klone das Repository und installiere anschließend die Abhängigkeiten mit Bun, npm oder pnpm:
2

Create a Supabase Project

Erstelle ein Supabase-Projekt. In späteren Schritten wird die Projekt-Referenz verwendet, also die Subdomain in https://[your-project-ref].supabase.co. Kopiere diese Werte:
  • NEXT_PUBLIC_SUPABASE_URL, die Projekt-URL
  • NEXT_PUBLIC_SUPABASE_ANON_KEY, der Anon-Key
  • SUPABASE_SERVICE_ROLE_KEY, der Service-Role-Key
  • DATABASE_URL, die Datenbankverbindungszeichenfolge
3

Configure Google OAuth

Füge in Google Cloud diese autorisierte Redirect-URI zu deinem OAuth-Client hinzu: https://[your-project-ref].supabase.co/auth/v1/callback. Aktiviere anschließend in Supabase Auth den Google-Provider mit deiner Client ID und deinem Client Secret.
4

Configure Dodo Payments

Erstelle bei deaktiviertem Schalter Live Mode in der Seitenleiste unter Developer → API Keys im Dodo Payments-Dashboard einen API-Key. Lass DODO_PAYMENTS_ENVIRONMENT während der Entwicklung auf test_mode gesetzt.
5

Add the Webhook in Dodo Payments

Füge unter Developer → Webhooks einen Endpunkt mit dieser URL hinzu. Die Funktion, die ihn bereitstellt, wird in einem späteren Schritt bereitgestellt.
Wähle die Zahlungs- und Abonnementereignisse aus, die die Funktion verarbeitet:
  • Zahlungsereignisse: payment.succeeded, payment.failed, payment.processing und payment.cancelled
  • Abonnementereignisse: subscription.active, subscription.plan_changed, subscription.renewed, subscription.on_hold, subscription.cancelled, subscription.expired und subscription.failed
Kopiere das Signaturgeheimnis des Endpunkts. Es ist der Wert von DODO_WEBHOOK_SECRET.
6

Create .env.local

Erstelle im Stammverzeichnis eine .env.local-Datei:
Die Next.js-App liest jede Variable in dieser Datei außer DODO_WEBHOOK_SECRET. Die Edge Function liest DODO_WEBHOOK_SECRET aus den Supabase-Secrets, die du beim Bereitstellen festlegst.
Veröffentliche keine Secrets. Lege sie in bereitgestellten Umgebungen als Umgebungsvariablen fest.
7

Provision the Database Schema

Übertrage das Drizzle-Schema in deine Supabase-Datenbank:
Erstellte Tabellen: users, subscriptions, payments.
8

Deploy the Webhook Function

Melde dich bei Supabase an, speichere das Signaturgeheimnis als Function-Secret und stelle die dodo-webhook Edge Function bereit. Ersetze [your-project-ref] durch deine Projekt-Referenz:
Das Skript deploy:webhook führt supabase functions deploy dodo-webhook --no-verify-jwt aus, sodass Dodo Payments die Funktion ohne Supabase-Authentifizierungstoken aufrufen kann. Supabase stellt der Funktion standardmäßig SUPABASE_URL und SUPABASE_SERVICE_ROLE_KEY bereit.Überprüfe die Bereitstellung, indem du eine nicht signierte Anfrage sendest:
cURL
Eine 400-Antwort mit Invalid webhook signature bedeutet, dass die Funktion ausgeführt wird und über ihr Secret verfügt. Eine 500-Antwort mit Server configuration error bedeutet, dass DODO_WEBHOOK_SECRET nicht gesetzt ist. Um ein signiertes Testereignis zu senden, öffne den Endpunkt unter Developer → Webhooks und verwende den Tab Testing.
9

Create Products and Features

Klicke im Dodo Payments-Dashboard unter Products auf Add Product, um für jeden Plan ein Abonnementprodukt zu erstellen. Wenn du Planfunktionen in der App auflisten möchtest, füge optional einen Metadateneintrag mit dem Schlüssel features und einem JSON-Array aus Zeichenfolgen als Wert hinzu. Die Metadaten des Produkts sehen dann so aus:
Metadatenwerte sind Zeichenfolgen, Zahlen oder boolesche Werte. Speichere das Array daher als JSON-Zeichenfolge. Die Preisoberfläche analysiert den Wert features und rendert jedes Element.
10

Run the Dev Server

Öffne http://localhost:3000 und melde dich mit Google an.
Du verfügst nun über ein funktionierendes, mit Supabase und Dodo Payments erstelltes Abonnement-SaaS-Grundgerüst. Um den gesamten Ablauf zu bestätigen, abonniere einen Plan mit einer Testkarte. Sobald der Webhook eingegangen ist, zeigt das Dashboard deinen neuen Plan an.

Enthaltene Funktionen

  • Authentifizierung über Supabase mit konfiguriertem Google OAuth
  • Abonnement-Checkout über Dodo Payments
  • Eine Supabase Edge Function für Webhooks (dodo-webhook)
  • Ein Drizzle-ORM-Schema mit den Migrationsskripten db:generate und db:migrate
  • Ein Dashboard mit Rechnungen, Abonnementstatus und Planfunktionen
  • Server Actions zum Ändern von Plänen, Kündigen eines Abonnements und Wiederherstellen eines gekündigten Abonnements
Lass DODO_PAYMENTS_ENVIRONMENT auf test_mode gesetzt, bis du die Tests des gesamten Ablaufs abgeschlossen hast. Um live zu gehen, setze den Wert auf live_mode und verwende einen API-Key für den Live-Modus.

Wichtige Dateien und Pfade

Der Webhook-Handler, die App-Routen und das Datenbankschema befinden sich in diesen Dateien:

Umgebungsvariablen

Die Next.js-App und die Edge Function lesen diese Variablen:
.env.example listet SUPABASE_SERVICE_ROLE_KEY nicht auf, aber der Admin-Client der App in lib/supabase/admin.ts benötigt ihn. Füge ihn selbst hinzu.
Die App liest die Google-Zugangsdaten nicht aus Umgebungsvariablen. Gib Client ID und Client Secret in den Google-Provider-Einstellungen von Supabase Auth ein und füge diese Redirect-URI zum OAuth-Client in Google Cloud hinzu:

Überprüfung und Fehlerbehebung

  • Stelle sicher, dass das Secret der DODO_WEBHOOK_SECRET-Funktion mit dem Signatur-Secret des Endpunkts im Dodo Payments-Dashboard übereinstimmt.
  • Bestätige, dass du die neueste dodo-webhook-Funktion bereitgestellt hast.
  • Die Funktion überprüft die Standard Webhooks-Header webhook-id, webhook-signature und webhook-timestamp. Stelle sicher, dass ein Proxy sie nicht entfernt.
  • Überprüfe die DATABASE_URL-Syntax.
  • Die direkte Verbindung (db.[project-ref].supabase.co:5432) verwendet IPv6, sofern dein Projekt nicht über die IPv4-Erweiterung verfügt. In einem reinen IPv4-Netzwerk verwende stattdessen den Verbindungsstring des Session-Poolers (Supabase-Verbindungsdokumentation).
  • Warte 2–3 Minuten, nachdem du das Projekt erstellt hast, bevor du den ersten Push durchführst.
  • Die Redirect-URI muss https://[ref].supabase.co/auth/v1/callback sein.
  • Verwende dieselbe URI in Google Cloud und im Supabase-Auth-Provider.
Das ursprüngliche Repository und ausführliche Schritte findest du unter dodo-supabase-subscription-starter.
Zuletzt geändert am 26. September 2026