Source:
ocean/docs/WEBHOOK_TESTING_BEST_PRACTICES.md| ✏️ Edit on GitHub
Webhook Testing Best Practices
1. Use Official CLI Tools
Stripe CLI for Local Testing
# Install Stripe CLI
brew install stripe/stripe-cli/stripe
# Login to Stripe
stripe login
# Forward webhooks to local endpoint
stripe listen --forward-to localhost:3000/api/webhooks/stripe
# Trigger test events
stripe trigger customer.created
Cloudflare Wrangler for Local Development
# Run worker locally
pnpm wrangler dev --env staging
# Tail production logs
pnpm wrangler tail --env production
2. Environment-Based Testing
Local Development
- Use Stripe CLI to forward webhooks to local endpoints
- Use
wrangler devto test Cloudflare Workers locally - Mock Supabase triggers with local test scripts
Staging Environment
- Use real webhook endpoints (e.g.,
https://ocean-stripe-webhook.staging.goldfish.io) - Use test API keys (Stripe test mode, Supabase staging project)
- Monitor with logging services
Production Environment
- Use monitoring and alerting (Sentry, Datadog, etc.)
- Implement webhook signature verification
- Add retry logic and idempotency
3. Testing Strategies
Unit Tests
// Test webhook payload parsing
describe('parseStripeWebhook', () => {
it('should parse customer.created event', () => {
const payload = {
/* mock payload */
}
const result = parseStripeWebhook(payload)
expect(result.customerId).toBeDefined()
})
})
Integration Tests
// Test with real API calls but test keys
describe('Stripe Integration', () => {
it('should create customer in Stripe', async () => {
const customer = await stripe.customers.create({
email: 'test@example.com',
metadata: { supabase_user_id: 'test-123' },
})
expect(customer.id).toMatch(/^cus_/)
})
})
End-to-End Tests
// Test complete flow with test data
describe('Signup Flow E2E', () => {
it('should sync user from Supabase to Stripe', async () => {
// 1. Create user in Supabase
// 2. Wait for webhook
// 3. Verify customer in Stripe
})
})
4. Webhook Security
Always Verify Signatures
const sig = request.headers.get('stripe-signature')
const event = stripe.webhooks.constructEvent(rawBody, sig, process.env.STRIPE_WEBHOOK_SECRET)
Implement Idempotency
// Store processed event IDs
const processed = await kv.get(`webhook:${event.id}`)
if (processed) return { status: 200, body: 'Already processed' }
Add Rate Limiting
// Use Cloudflare rate limiting or implement custom logic
const rateLimiter = new RateLimiter({
windowMs: 60000, // 1 minute
max: 100, // limit each IP to 100 requests per minute
})
5. Monitoring and Debugging
Structured Logging
console.log(
JSON.stringify({
event: 'webhook_received',
type: event.type,
customer_id: event.data.object.id,
timestamp: new Date().toISOString(),
environment: process.env.ENVIRONMENT,
})
)
Use Webhook Dashboards
- Stripe Dashboard → Developers → Webhooks → View logs
- Cloudflare Dashboard → Workers → View logs
- Supabase Dashboard → Logs → Edge logs
Implement Health Checks
// Add endpoint to verify webhook is responsive
if (request.url.includes('/health')) {
return new Response('OK', { status: 200 })
}
6. Testing Commands
Manual Testing with cURL
# Test webhook endpoint directly
curl -X POST https://ocean-stripe-webhook.staging.goldfish.io \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_SECRET" \
-d '{"type":"INSERT","table":"users","record":{"id":"test-123","email":"test@example.com"}}'
Stripe CLI Testing
# Listen and forward to staging
stripe listen --forward-to https://ocean-stripe-webhook.staging.goldfish.io
# Trigger specific events
stripe trigger customer.created
stripe trigger customer.updated
Database Testing
-- Manually trigger Supabase function
SELECT webhook_sync_user_to_stripe();
-- Check pg_net request logs
SELECT * FROM net._http_response ORDER BY created DESC LIMIT 10;
7. Common Pitfalls to Avoid
- Never hardcode secrets - Always use environment variables
- Don't skip signature verification - Security risk
- Avoid synchronous processing - Use queues for heavy operations
- Don't trust webhook data - Always validate and sanitize
- Never expose internal IDs - Map to external references
8. Recommended Tools
- Stripe CLI: Official tool for webhook testing
- ngrok: Expose local endpoints for testing
- Postman/Insomnia: API testing with webhook simulation
- Jest/Vitest: Unit and integration testing
- Playwright: E2E testing including webhook flows