Skip to main content
The Dodo Supabase Subscription Starter kit includes a secure webhook handler that processes payment and subscription events from Dodo Payments.

Webhook Endpoint

The webhook handler is deployed as a Supabase Edge Function at:
https://[your-project-ref].supabase.co/functions/v1/dodo-webhook
Source: ~/workspace/source/supabase/functions/dodo-webhook/index.ts

Security & Verification

All webhook requests are verified using the standardwebhooks library to ensure authenticity.

Verification Process

The webhook handler validates every incoming request by:
  1. Extracting required headers from the request:
    • webhook-id: Unique identifier for the webhook event
    • webhook-signature: HMAC signature for verification
    • webhook-timestamp: Timestamp of the event
  2. Verifying the signature using the DODO_WEBHOOK_SECRET:
const webhook = new Webhook(dodoWebhookSecret);
await webhook.verify(rawBody, webhookHeaders);
  1. Rejecting requests with invalid signatures (returns 400 status)

Required Environment Variables

DODO_WEBHOOK_SECRET
string
required
Secret key provided by Dodo Payments for webhook verification
SUPABASE_URL
string
required
Your Supabase project URL
SUPABASE_SERVICE_ROLE_KEY
string
required
Service role key for database access

Event Processing

The webhook handler processes two categories of events:

Payment Events

These events update the payments table:
  • payment.succeeded
  • payment.failed
  • payment.processing
  • payment.cancelled
Handler: managePayment() function at line 120

Subscription Events

These events update the subscriptions table and may also update user subscription status: Active/Upgrade Events (updates user tier):
  • subscription.active
  • subscription.plan_changed
Status Change Events:
  • subscription.renewed
  • subscription.on_hold
Cancellation Events (downgrades user):
  • subscription.cancelled
  • subscription.expired
  • subscription.failed
Handler: manageSubscription() function at line 164

Response Codes

200
Success
Event processed successfully or event type not handled
400
Bad Request
Invalid webhook signature - verification failed
405
Method Not Allowed
Non-POST request received
500
Server Error
Missing configuration or error processing webhook

CORS Support

The webhook endpoint includes CORS headers for cross-origin requests:
const corsHeaders = {
  "Access-Control-Allow-Origin": "*",
  "Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type"
};

Database Operations

The webhook handler uses upsert operations to handle both new events and updates:
  • Payments: Upserted by payment_id
  • Subscriptions: Upserted by subscription_id
  • Users: Updated by dodo_customer_id
This ensures idempotency - replaying the same webhook event will not create duplicates.

Next Steps

Webhook Events

View all webhook event types and payloads

Database Schema

Explore the database structure

Build docs developers (and LLMs) love