Overview
SkillRise uses webhooks from Clerk and Razorpay to sync data and process payments. Webhooks allow external services to notify your server when events occur.Active Webhooks
Webhook Security
All webhooks use cryptographic signatures to verify authenticity:- Clerk: Uses Svix for signature verification
- Razorpay: Uses HMAC-SHA256 signatures
Clerk Webhooks
Setup
1
Configure webhook in Clerk Dashboard
- Go to Webhooks → Add Endpoint
- URL:
https://your-domain.com/clerk - Subscribe to:
user.created,user.updated,user.deleted - Copy the Signing Secret
2
Add secret to environment
server/.env
Implementation
server/controllers/webhooks.js
Headers
Clerk sends these headers for verification:Razorpay Webhooks
Setup
1
Configure webhook in Razorpay Dashboard
- Go to Settings → Webhooks → Add New Webhook
- URL:
https://your-domain.com/razorpay - Events:
payment.captured - Click Create Webhook
- Copy the Webhook Secret
2
Add secret to environment
server/.env
Implementation
server/controllers/webhooks.js
Critical: Raw Body Requirement
server/server.js
express.json()parses and re-stringifies the body, changing bytes- Signature verification will fail if bytes are modified
express.raw()preserves the exact bytes as a Buffer
Headers
Razorpay sends this header:Signature Verification Deep Dive
Clerk (Svix)
Clerk uses the Svix library for webhook signatures:- Signature matches expected HMAC
- Timestamp is recent (prevents replay attacks)
- Message ID hasn’t been seen before (prevents duplicate processing)
Razorpay (HMAC-SHA256)
Razorpay uses standard HMAC-SHA256:timingSafeEqual?
- Prevents timing attacks
- Regular
===comparison leaks information through timing timingSafeEqualalways takes the same time, regardless of where strings differ
Webhook Resilience
Idempotency
Webhooks may be delivered multiple times. Make handlers idempotent:Error Handling
- Return
200 OKto acknowledge successful processing - Return
400for invalid signatures (don’t retry) - Return
500for transient errors (service will retry) - Log all errors for debugging
Retry Logic
Both Clerk and Razorpay retry failed webhooks:Testing Webhooks Locally
Using ngrok
1
Install ngrok
2
Start your server
3
Expose localhost
4
Update webhook URLs
- Clerk:
https://abc123.ngrok.io/clerk - Razorpay:
https://abc123.ngrok.io/razorpay
5
Test webhooks
- Clerk: Create a user in Clerk Dashboard
- Razorpay: Make a test payment
- Check server logs and database
Using Webhook Testing Tools
Clerk:- Go to Webhooks → Your endpoint → Testing
- Click Send Example to send test events
- Use Webhook.site to inspect payloads
- Copy payload and replay via curl:
Monitoring Webhooks
Log All Events
Track Failures
Dashboard Monitoring
Clerk:- Go to Webhooks → Your endpoint → Logs
- View recent deliveries, status codes, and retry attempts
- Go to Settings → Webhooks → Click your webhook
- View Recent Deliveries with response codes
Common Issues
Signature verification fails
Signature verification fails
Clerk:
- Verify
CLERK_WEBHOOK_SECRETmatches Clerk Dashboard - Check headers:
svix-id,svix-timestamp,svix-signature - Ensure you’re stringifying the body:
JSON.stringify(req.body)
- Verify
RAZORPAY_WEBHOOK_SECRETmatches Razorpay Dashboard - Critical: Use
express.raw(), notexpress.json() - Register webhook route before
express.json()middleware
Webhooks not received
Webhooks not received
- Check firewall/security groups allow incoming HTTPS
- Verify URL is correct (no typos, correct protocol)
- Test with ngrok to rule out network issues
- Check webhook is subscribed to correct events
Duplicate events
Duplicate events
- Make handlers idempotent (use
upsertinstead ofcreate) - Track processed webhook IDs to skip duplicates
- Use database unique constraints
Events out of order
Events out of order
- Webhooks may arrive out of order
- Use timestamps to order events
- Design handlers to be order-independent
Security Checklist
1
Always verify signatures
Never process webhook events without cryptographic verification.
2
Use HTTPS in production
Webhook providers require HTTPS for security.
3
Validate event structure
Use Zod or similar to validate webhook payloads before processing.
4
Rate limiting
Apply rate limits to webhook endpoints to prevent abuse.
5
Secret rotation
Rotate webhook secrets periodically (every 90 days).
6
Monitor failures
Set up alerts for webhook failures (email, Slack, etc.).
Resources
Clerk Webhooks
Clerk webhook documentation
Razorpay Webhooks
Razorpay webhook guide
Svix
Svix webhook platform (used by Clerk)
ngrok
Expose localhost for testing