Stripe Webhook Setup
Stripe Webhook Setup
✅ Implemented - Stripe webhook handler is implemented at
/api/billing/webhookwith signature verification and event processing.
Learn how to configure Stripe webhooks for AllureLMS to receive real-time billing events and subscription updates.
Overview
This guide covers:
- Understanding Stripe webhooks
- Configuring webhook endpoints
- Webhook event types
- Signature verification
- Testing webhooks
Prerequisites
- Stripe account
- Admin access to Stripe Dashboard
- Understanding of webhooks
- (Optional) Webhook testing tool (ngrok, etc.)
Understanding Stripe Webhooks
What are Webhooks?
Webhooks are HTTP callbacks that notify your application when events occur in Stripe:
- Subscription created/updated
- Payment succeeded/failed
- Invoice created/paid
- Customer updated
Why Use Webhooks?
- Real-time Updates: Immediate notification of events
- Reliability: Automatic retry on failure
- Event History: Complete audit trail
- Automation: Trigger actions based on events
Configuring Webhooks
Step 1: Get Webhook Endpoint URL
Your AllureLMS webhook endpoint:
https://your-domain.com/api/billing/webhook
Step 2: Configure in Stripe Dashboard
- Log in to Stripe Dashboard
- Navigate to Developers → Webhooks
- Click Add Endpoint
- Enter endpoint URL:
https://your-domain.com/api/billing/webhook - Select events to listen to (see below)
- Click Add Endpoint
- Copy the Signing Secret
Step 3: Set Environment Variable
✅ Implemented - The webhook handler uses
STRIPE_WEBHOOK_SECRETenvironment variable for signature verification.
Set the webhook signing secret:
STRIPE_WEBHOOK_SECRET=whsec_...
Required Environment Variables:
STRIPE_SECRET_KEY: Stripe API secret key (for creating customers, subscriptions)STRIPE_WEBHOOK_SECRET: Webhook signing secret from Stripe DashboardNEXT_PUBLIC_APP_URL: Base URL of your application (for redirect URLs)
Webhook Events
Required Events
✅ Implemented - The webhook handler processes these events:
Subscribe to these events for full functionality:
Subscription Events:
- ✅
customer.subscription.updated- Updates subscription status - ✅
customer.subscription.deleted- Marks subscription as canceled
Payment Events:
- ✅
checkout.session.completed- Activates subscription after payment - ✅
invoice.payment_failed- Sets subscription status topast_due
Customer Events:
- 🚧
customer.created- Planned for future implementation - 🚧
customer.updated- Planned for future implementation - 🚧
customer.deleted- Planned for future implementation
Event Handling
AllureLMS handles these events automatically:
- ✅ Creates/updates subscription records in
tenant_pricingtable - ✅ Updates tenant pricing status (active, past_due, canceled)
- ✅ Handles payment failures by setting status to
past_due - ✅ Updates checkout session status in
billing_checkout_sessionstable
Signature Verification
Why Verify?
Webhook signature verification ensures:
- Request is from Stripe
- Request hasn't been tampered with
- Request is authentic
How It Works
Stripe signs each webhook with HMAC-SHA256:
- Stripe creates signature from payload + secret
- Signature sent in
Stripe-Signatureheader - AllureLMS verifies signature matches
- Request processed if valid
Verification Code
const crypto = require('crypto');
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
function verifyWebhookSignature(payload, signature, secret) {
const elements = signature.split(',');
const signatureHash = elements.find(el => el.startsWith('v1='));
if (!signatureHash) {
return false;
}
const expectedSignature = signatureHash.split('=')[1];
const hmac = crypto.createHmac('sha256', secret);
hmac.update(payload);
const computedSignature = hmac.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expectedSignature, 'hex'),
Buffer.from(computedSignature, 'hex')
);
}
Webhook Handler
AllureLMS Webhook Endpoint
The webhook endpoint at /api/billing/webhook handles:
- Signature Verification: Verifies request authenticity
- Event Parsing: Parses Stripe event
- Event Handling: Processes event based on type
- Database Updates: Updates subscription/pricing records
- Response: Returns 200 OK to Stripe
Event Processing
// Example event processing
switch (event.type) {
case 'checkout.session.completed':
await handleCheckoutCompleted(event.data.object);
break;
case 'customer.subscription.updated':
await handleSubscriptionUpdated(event.data.object);
break;
case 'invoice.payment_succeeded':
await handlePaymentSucceeded(event.data.object);
break;
// ... more event types
}
Testing Webhooks
Using Stripe CLI
1. Install Stripe CLI:
# macOS
brew install stripe/stripe-cli/stripe
# Linux/Windows
# Download from https://stripe.com/docs/stripe-cli
2. Login:
stripe login
3. Forward Webhooks:
stripe listen --forward-to http://localhost:3000/api/billing/webhook
4. Trigger Test Event:
stripe trigger checkout.session.completed
Using ngrok
1. Install ngrok:
# Download from https://ngrok.com
2. Start ngrok:
ngrok http 3000
3. Use ngrok URL in Stripe:
https://abc123.ngrok.io/api/billing/webhook
4. Test in Stripe Dashboard:
- Go to Webhooks → Your Endpoint
- Click "Send test webhook"
- Select event type
- Send test
Webhook Security
Best Practices
- HTTPS Only: Always use HTTPS for webhooks
- Verify Signatures: Always verify webhook signatures
- Idempotency: Handle duplicate webhook deliveries
- Timeout Handling: Implement proper timeouts
- Error Handling: Log errors and retry logic
Signature Verification
Always verify signatures:
// In webhook handler
const signature = request.headers.get('stripe-signature');
const isValid = verifyWebhookSignature(
requestBody,
signature,
process.env.STRIPE_WEBHOOK_SECRET
);
if (!isValid) {
return new Response('Invalid signature', { status: 401 });
}
Troubleshooting
Webhooks Not Received
Problem: Webhooks not arriving
- Solution: Check webhook endpoint URL is correct
- Check: Verify endpoint is accessible (HTTPS)
- Try: Test with Stripe CLI or ngrok
- Check: Review Stripe webhook logs
Signature Verification Fails
Problem: "Invalid signature" error
- Solution: Verify
STRIPE_WEBHOOK_SECRETmatches Stripe - Check: Ensure using correct signing secret
- Try: Regenerate webhook secret in Stripe
- Check: Verify raw body is used for signature
Events Not Processing
Problem: Webhook received but not processed
- Solution: Check webhook handler logs
- Check: Verify event type is handled
- Try: Review event processing logic
- Check: Ensure database updates are working
Related Documentation
- Subscribing to Plans - Subscription flow
- Managing Subscriptions - Subscription management
- Webhook Integration Advanced - Advanced webhooks
Next Steps
- Webhook Integration Advanced → Advanced webhook patterns
- Managing Subscriptions → Manage subscriptions
- API Security → Security best practices
Next: Reporting Guides → Learn about reports