Skip to main content

Source: ocean/docs/adr/0008-stripe-customer-sync-via-cloudflare-workers.md | ✏️ Edit on GitHub

ADR-0008: Stripe Customer Synchronization via Cloudflare Workers

Status

Superseded by ADR-0013

Context

Our application requires integration with Stripe for billing and subscription management. When users sign up through our Supabase authentication system, we need to:

  1. Create corresponding customer records in Stripe
  2. Maintain a link between Supabase users/organizations and Stripe customers
  3. Ensure all user metadata (organization, industry, region) is available in Stripe for billing and analytics
  4. Support both staging and production environments with different Stripe accounts

Currently, user data flows as follows:

  • User signs up → Supabase Auth (with metadata) → Database trigger creates organization

We need to extend this flow to include Stripe customer creation.

Decision

We will implement a Cloudflare Worker that acts as a webhook receiver to synchronize new Supabase users to Stripe customers.

Architecture

User Signup → Supabase Auth → Database Trigger → Organization Created

Supabase Webhook

Cloudflare Worker

Stripe Customer Created

Organization Updated with stripe_customer_id

Implementation Details

  1. Cloudflare Worker: Serverless function that receives webhooks and creates Stripe customers
  2. Webhook Security: Bearer token authentication between Supabase and Worker
  3. Environment Separation: Separate staging and production deployments with different secrets
  4. Data Sync: Full metadata transfer including name, organization, industry, and region
  5. Bi-directional Link: Stripe customer ID stored in organizations table

Technology Choices

  • Cloudflare Workers over traditional servers because:

    • Serverless, no infrastructure to manage
    • Global edge deployment
    • Built-in scalability
    • Cost-effective for webhook processing
    • Easy environment management
  • Webhook-based over direct API calls because:

    • Decouples user signup flow from Stripe integration
    • Allows for retry logic and error handling
    • Non-blocking user experience
    • Easier to monitor and debug

Consequences

Positive

  1. Seamless User Experience: Stripe customer creation happens asynchronously without blocking signup
  2. Environment Flexibility: Easy to switch between staging and production Stripe accounts
  3. Maintainability: Webhook logic isolated in a single worker
  4. Scalability: Cloudflare Workers auto-scale with demand
  5. Cost Effective: Pay only for webhook invocations
  6. Monitoring: Built-in logging and error tracking via Cloudflare
  7. Data Consistency: All user metadata automatically synced to Stripe

Negative

  1. Additional Service: Introduces Cloudflare as a dependency
  2. Eventual Consistency: Stripe customer creation is asynchronous
  3. Webhook Complexity: Requires webhook configuration and monitoring
  4. Secret Management: Need to manage secrets across multiple services

Neutral

  1. Retry Logic: May need to implement webhook retry for failed Stripe API calls
  2. Monitoring: Requires monitoring of both Supabase webhooks and Cloudflare Workers
  3. Testing: Need to test webhook flow in addition to application logic

Implementation Notes

Security Considerations

  • Webhook endpoints secured with bearer tokens
  • Stripe API keys stored as encrypted Worker secrets
  • Different secrets for staging and production environments
  • Service role keys used only in Worker, not exposed to client

Data Flow

  1. User signs up with email, name, organization, industry, region
  2. Supabase creates user with metadata in raw_user_meta_data
  3. Database trigger creates organization record
  4. Webhook fires to Cloudflare Worker
  5. Worker creates Stripe customer with full metadata
  6. Worker updates organization with stripe_customer_id

Migration Path

  1. Deploy Worker to staging environment
  2. Test with staging Stripe account
  3. Verify customer creation and data sync
  4. Deploy to production when ready
  5. Update webhook URLs and secrets

Alternatives Considered

  1. Direct API Integration: Call Stripe during signup

    • Rejected: Would block user signup if Stripe is down
    • Rejected: Couples authentication flow with billing
  2. Background Jobs: Use a job queue system

    • Rejected: Requires additional infrastructure
    • Rejected: More complex than webhook approach
  3. Supabase Edge Functions: Use Supabase's own edge functions

    • Rejected: Less mature than Cloudflare Workers
    • Rejected: Vendor lock-in concerns
  4. AWS Lambda: Use AWS serverless functions

    • Rejected: More complex deployment and configuration
    • Rejected: Cloudflare Workers have better DX

References

Date

2025-01-27

Authors

  • Development Team (via Claude)
  • Reviewed by: [Pending]