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:
- Create corresponding customer records in Stripe
- Maintain a link between Supabase users/organizations and Stripe customers
- Ensure all user metadata (organization, industry, region) is available in Stripe for billing and analytics
- 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
- Cloudflare Worker: Serverless function that receives webhooks and creates Stripe customers
- Webhook Security: Bearer token authentication between Supabase and Worker
- Environment Separation: Separate staging and production deployments with different secrets
- Data Sync: Full metadata transfer including name, organization, industry, and region
- 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
- Seamless User Experience: Stripe customer creation happens asynchronously without blocking signup
- Environment Flexibility: Easy to switch between staging and production Stripe accounts
- Maintainability: Webhook logic isolated in a single worker
- Scalability: Cloudflare Workers auto-scale with demand
- Cost Effective: Pay only for webhook invocations
- Monitoring: Built-in logging and error tracking via Cloudflare
- Data Consistency: All user metadata automatically synced to Stripe
Negative
- Additional Service: Introduces Cloudflare as a dependency
- Eventual Consistency: Stripe customer creation is asynchronous
- Webhook Complexity: Requires webhook configuration and monitoring
- Secret Management: Need to manage secrets across multiple services
Neutral
- Retry Logic: May need to implement webhook retry for failed Stripe API calls
- Monitoring: Requires monitoring of both Supabase webhooks and Cloudflare Workers
- 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
- User signs up with email, name, organization, industry, region
- Supabase creates user with metadata in
raw_user_meta_data - Database trigger creates organization record
- Webhook fires to Cloudflare Worker
- Worker creates Stripe customer with full metadata
- Worker updates organization with
stripe_customer_id
Migration Path
- Deploy Worker to staging environment
- Test with staging Stripe account
- Verify customer creation and data sync
- Deploy to production when ready
- Update webhook URLs and secrets
Alternatives Considered
-
Direct API Integration: Call Stripe during signup
- Rejected: Would block user signup if Stripe is down
- Rejected: Couples authentication flow with billing
-
Background Jobs: Use a job queue system
- Rejected: Requires additional infrastructure
- Rejected: More complex than webhook approach
-
Supabase Edge Functions: Use Supabase's own edge functions
- Rejected: Less mature than Cloudflare Workers
- Rejected: Vendor lock-in concerns
-
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]