Webhook Handlers for SaaS

fullstack
TypeScript
scaffolding
corporate_pm
Remix

Handle webhooks from Stripe and Clerk for subscription and auth events.

12/8/2025

Prompt

Implement complete webhook handlers for a SaaS application integrating Stripe for payments/subscriptions and Clerk for authentication with the following requirements:

Application Overview

SaaS Application Details

  • Application Name: [e.g., MyApp, SaaS Platform]
  • Framework: [Next.js / Express / NestJS / Remix / Custom]
  • Database: [PostgreSQL / MySQL / MongoDB / Supabase / PlanetScale]
  • ORM: [Prisma / Drizzle / TypeORM / Mongoose / Raw SQL]
  • Deployment: [Vercel / Railway / AWS / Custom]

Integration Scope

  • Stripe Integration: [Yes / No]
  • Clerk Integration: [Yes / No]
  • Other Webhooks: [List any additional webhook providers]

Stripe Webhook Configuration

Stripe Setup

  • Stripe Mode: [Test mode / Live mode / Both]
  • Stripe Products: [List products/plans]
  • Billing Model: [Subscription / One-time / Both]
  • Currency: [USD / EUR / GBP / Multiple]

Subscription Plans

Define your subscription tiers:

Plan 1: [Name, e.g., Free]

  • Stripe Price ID: [price_xxx or placeholder]
  • Amount: [0 / 9.99 / Custom]
  • Interval: [month / year / one-time]
  • Features: [List features for this plan]
  • User Limits: [Max users, projects, etc.]

Plan 2: [Name, e.g., Pro]

  • Stripe Price ID: [Price ID]
  • Amount: [Amount]
  • Interval: [Interval]
  • Features: [Features]
  • User Limits: [Limits]

Plan 3: [Name, e.g., Enterprise]

  • Stripe Price ID: [Price ID]
  • Amount: [Amount]
  • Interval: [Interval]
  • Features: [Features]
  • User Limits: [Limits]

[Define 2-5 plans]

Stripe Events to Handle

Subscription Events

  • customer.subscription.created:

    • Action: [Create subscription record in database]
    • Update User: [Set plan, enable features, update status]
    • Notifications: [Send welcome email / None]
    • Additional Logic: [Custom logic]
  • customer.subscription.updated:

    • Action: [Update subscription record]
    • Handle Changes: [Plan upgrade/downgrade, quantity change, status change]
    • Notifications: [Email on plan change / None]
    • Additional Logic: [Custom logic]
  • customer.subscription.deleted:

    • Action: [Mark subscription as canceled]
    • Update User: [Downgrade to free, disable features]
    • Data Retention: [Keep data / Delete after X days / Archive]
    • Notifications: [Cancellation email / None]

Payment Events

  • invoice.payment_succeeded:

    • Action: [Record payment, extend subscription]
    • Update User: [Renew access, reset usage limits]
    • Notifications: [Receipt email / None]
    • Additional Logic: [Custom logic]
  • invoice.payment_failed:

    • Action: [Record failed payment]
    • Update User: [Grace period / Immediate suspension]
    • Notifications: [Payment failed email / None]
    • Retry Logic: [Stripe handles / Custom]
  • payment_intent.succeeded:

    • Action: [For one-time payments]
    • Update User: [Grant access, credits, etc.]
    • Notifications: [Confirmation email / None]

Customer Events

  • customer.created:

    • Action: [Store customer ID with user]
    • Additional Logic: [Custom logic]
  • customer.updated:

    • Action: [Update customer details]
    • Sync Fields: [Email, name, metadata]
  • customer.deleted:

    • Action: [Handle customer deletion]
    • Data Cleanup: [Remove references / Archive]

[Define additional Stripe events if needed]

Database Schema for Stripe

Subscriptions Table

  • id: [Primary key]
  • userId: [Foreign key to users]
  • stripeSubscriptionId: [Stripe subscription ID]
  • stripeCustomerId: [Stripe customer ID]
  • stripePriceId: [Price ID]
  • status: [active, canceled, past_due, etc.]
  • currentPeriodStart: [Timestamp]
  • currentPeriodEnd: [Timestamp]
  • cancelAtPeriodEnd: [Boolean]
  • createdAt: [Timestamp]
  • updatedAt: [Timestamp]

Payments Table (optional)

  • id: [Primary key]
  • userId: [Foreign key]
  • stripeInvoiceId: [Invoice ID]
  • amount: [Amount paid]
  • currency: [Currency]
  • status: [paid, failed, etc.]
  • createdAt: [Timestamp]

Clerk Webhook Configuration

Clerk Setup

  • Clerk Instance: [Production / Development / Both]
  • User Metadata: [Custom fields to sync]
  • Organization Support: [Yes / No]

Clerk Events to Handle

User Events

  • user.created:

    • Action: [Create user record in database]
    • Fields to Store: [id, email, firstName, lastName, imageUrl, etc.]
    • Default Values: [Set default plan, credits, etc.]
    • Notifications: [Welcome email / None]
    • Additional Logic: [Create Stripe customer / Custom]
  • user.updated:

    • Action: [Update user record]
    • Sync Fields: [Email, name, profile image, metadata]
    • Handle Changes: [Email change, profile updates]
    • Additional Logic: [Update Stripe customer / Custom]
  • user.deleted:

    • Action: [Soft delete / Hard delete user]
    • Cascade: [Delete subscriptions, data, etc.]
    • Data Retention: [Archive data / Immediate deletion]
    • Cleanup: [Cancel Stripe subscription / Custom]

Session Events (optional)

  • session.created:

    • Action: [Track user sessions / None]
    • Analytics: [Log session start / None]
  • session.ended:

    • Action: [Track session end / None]
    • Analytics: [Log session duration / None]

Organization Events (if using orgs)

  • organization.created:

    • Action: [Create organization record]
    • Default Settings: [Plan, limits, etc.]
  • organization.updated:

    • Action: [Update organization]
    • Sync Fields: [Name, metadata, etc.]
  • organization.deleted:

    • Action: [Delete organization and members]
    • Cascade: [Handle member cleanup]
  • organizationMembership.created:

    • Action: [Add user to organization]
    • Permissions: [Set role, permissions]
  • organizationMembership.deleted:

    • Action: [Remove user from organization]
    • Cleanup: [Revoke access]

Database Schema for Clerk

Users Table

  • id: [Clerk user ID as primary key]
  • email: [Email address]
  • firstName: [First name]
  • lastName: [Last name]
  • imageUrl: [Profile image]
  • plan: [free, pro, enterprise]
  • stripeCustomerId: [Link to Stripe]
  • createdAt: [Timestamp]
  • updatedAt: [Timestamp]

Organizations Table (if using orgs)

  • id: [Clerk org ID]
  • name: [Organization name]
  • plan: [Organization plan]
  • stripeCustomerId: [Stripe customer for org]
  • createdAt: [Timestamp]
  • updatedAt: [Timestamp]

Webhook Endpoint Implementation

Stripe Endpoint

  • Path: [/api/webhooks/stripe / /webhooks/stripe]
  • Method: [POST]
  • Body Parser: [express.raw() for signature verification]
  • Signature Verification: [Use stripe.webhooks.constructEvent()]
  • Error Handling: [400 for invalid signature, 500 for processing errors]
  • Response: [200 with {received: true}]

Clerk Endpoint

  • Path: [/api/webhooks/clerk / /webhooks/clerk]
  • Method: [POST]
  • Body Parser: [JSON]
  • Signature Verification: [Use Svix webhook verification]
  • Error Handling: [400 for invalid signature, 500 for processing errors]
  • Response: [200 with {success: true}]

Business Logic

Subscription Lifecycle

New Subscription

  1. Stripe Event: customer.subscription.created
  2. Database: Create subscription record
  3. User Update: Set plan, enable features
  4. Notifications: Send welcome email
  5. Additional: [Custom onboarding, setup, etc.]

Subscription Update

  1. Stripe Event: customer.subscription.updated
  2. Detect Change: [Upgrade, downgrade, quantity, status]
  3. Database: Update subscription record
  4. User Update: Adjust features, limits
  5. Notifications: [Email if plan changed]

Subscription Cancellation

  1. Stripe Event: customer.subscription.deleted
  2. Database: Update subscription status
  3. User Update: Downgrade to free plan
  4. Data Handling: [Archive, delete, or retain]
  5. Notifications: Cancellation confirmation

Payment Success

  1. Stripe Event: invoice.payment_succeeded
  2. Database: Record payment
  3. User Update: Extend subscription period
  4. Notifications: Send receipt

Payment Failure

  1. Stripe Event: invoice.payment_failed
  2. Database: Record failed payment
  3. User Update: [Grace period or suspend]
  4. Notifications: Payment failed alert
  5. Retry: [Stripe automatic retry]

User Lifecycle

User Registration

  1. Clerk Event: user.created
  2. Database: Create user record
  3. Stripe: Create customer (if needed)
  4. Defaults: Set free plan, initial credits
  5. Notifications: Welcome email

User Profile Update

  1. Clerk Event: user.updated
  2. Database: Update user fields
  3. Stripe: Sync customer data (if changed)

User Deletion

  1. Clerk Event: user.deleted
  2. Stripe: Cancel subscriptions
  3. Database: Soft delete or hard delete
  4. Cleanup: Remove user data per retention policy

Error Handling & Reliability

Idempotency

  • Event ID Tracking: [Store processed Stripe event IDs]
  • Storage: [Redis / Database table]
  • TTL: [7 days / 30 days]
  • Duplicate Handling: [Return 200 if already processed]

Error Recovery

  • Database Errors: [Retry with exponential backoff / Alert]
  • External API Errors: [Retry / Queue for manual review]
  • Partial Failures: [Rollback transaction / Continue]
  • Logging: [Log all errors with event details]

Monitoring

  • Metrics:
    • Webhooks received per provider
    • Processing success/failure rate
    • Processing duration
    • Failed event count
  • Alerts:
    • Signature verification failures
    • Processing failures > X%
    • Webhook endpoint down

Testing

Test Events

  • Stripe CLI: [Use Stripe CLI to send test events]
  • Clerk Dashboard: [Send test events from Clerk dashboard]
  • Mock Payloads: [Create mock event payloads for testing]

Test Cases

  • Stripe:

    • New subscription creation
    • Subscription upgrade/downgrade
    • Subscription cancellation
    • Successful payment
    • Failed payment
    • Invalid signature
  • Clerk:

    • User creation
    • User update
    • User deletion
    • Invalid signature

Code Generation Requirements

Generate a complete SaaS webhook integration including:

  1. Webhook Endpoints:

    • Stripe webhook endpoint with raw body parsing
    • Clerk webhook endpoint with JSON parsing
    • Signature verification for both
    • Event routing to handlers
    • Error handling and responses
  2. Stripe Event Handlers:

    • Handler for each subscription event
    • Handler for each payment event
    • Handler for customer events
    • Database operations (create, update, delete)
    • User feature updates
    • Email notifications
  3. Clerk Event Handlers:

    • Handler for user.created
    • Handler for user.updated
    • Handler for user.deleted
    • Handler for organization events (if applicable)
    • Database synchronization
    • Stripe customer creation/updates
  4. Database Schema:

    • Prisma/Drizzle schema for users
    • Schema for subscriptions
    • Schema for payments (optional)
    • Schema for organizations (if applicable)
    • Migrations
  5. Business Logic:

    • Subscription lifecycle management
    • Plan upgrade/downgrade logic
    • Feature enablement based on plan
    • Payment processing
    • User onboarding flow
  6. Idempotency Layer:

    • Event ID tracking (Redis or database)
    • Duplicate detection
    • TTL-based cleanup
  7. Email Notifications:

    • Welcome email template
    • Subscription confirmation
    • Payment receipt
    • Payment failed alert
    • Cancellation confirmation
  8. Testing Suite:

    • Unit tests for each event handler
    • Integration tests with mock webhooks
    • Test utilities for generating signatures
    • Sample event payloads
  9. Configuration:

    • Environment variables
    • Stripe webhook secret
    • Clerk webhook secret
    • Database connection
    • Email service configuration
  10. Documentation:

    • Webhook setup guide
    • Event handling flow diagrams
    • Database schema documentation
    • Testing guide
    • Troubleshooting guide

Output production-ready SaaS webhook integration following best practices with:

  • Secure signature verification for both Stripe and Clerk
  • Idempotent event processing
  • Comprehensive error handling
  • Database transactions for data consistency
  • Email notifications for key events
  • Proper plan and feature management
  • User and subscription lifecycle handling
  • Testing utilities and mock data
  • Clear documentation
  • Monitoring and alerting setup

Tags

webhooks
stripe
clerk
saas

Tested Models

gpt-4
claude-3-5-sonnet

Comments (0)

Sign in to leave a comment

Sign In
Webhook Handlers for SaaS | vibeprompt.directory