Overview
Tresa Contafy uses Stripe webhooks to notify your application about subscription lifecycle events in real-time. Webhooks are HTTP callbacks that Stripe sends to your server when events occur.Webhooks are required for proper subscription management. They ensure your application stays synchronized with Stripe’s payment and subscription state.
Webhook Events
The API handles the following Stripe webhook events:checkout.session.completed
Fired when a user completes the Stripe checkout process. Actions:- Creates or updates subscription in database
- Extracts plan and billing information
- Records customer and subscription IDs
- Marks trial as used if applicable
- Records promotion code redemption
customer.subscription.updated
Fired when a subscription changes (upgrade, downgrade, renewal). Actions:- Updates subscription plan and price
- Updates billing period dates
- Updates cancellation status
- Records plan changes
customer.subscription.deleted
Fired when a subscription is cancelled or expires. Actions:- Marks subscription as CANCELLED
- Creates automatic FREE subscription
- Records cancellation date
- Downgrades user to FREE plan
invoice.payment_succeeded
Fired when a subscription renewal payment succeeds. Actions:- Updates subscription status to ACTIVE
- Updates billing period dates
- Records successful payment
invoice.payment_failed
Fired when a subscription renewal payment fails. Actions:- Updates subscription status to PAST_DUE
- Notifies user of payment failure
- May restrict features depending on configuration
Webhook Endpoint
The webhook endpoint is:Setting Up Webhooks
Create webhook in Stripe Dashboard
- Go to Stripe Dashboard > Developers > Webhooks
- Click “Add endpoint”
- Enter your webhook URL:
https://api.contafy.com/api/webhooks/stripe - Select API version (use latest)
Select events to listen to
Add these events:
checkout.session.completedcustomer.subscription.updatedcustomer.subscription.deletedinvoice.payment_succeededinvoice.payment_failed
Copy webhook signing secret
After creating the webhook, Stripe provides a signing secret starting with
whsec_.Copy this and add it to your environment:Webhook Signature Verification
The API automatically verifies webhook signatures using Stripe’s SDK:Missing Signature
Invalid Signature
Webhook Security
Raw Body Required
Stripe signature verification requires the raw request body. The server usesexpress.raw() middleware:
The webhook endpoint receives a raw buffer, not parsed JSON. This is required for signature verification.
Environment Variables
Configure these environment variables:Event Logging
All webhook events are automatically logged to thepayment_events table:
Webhook Response
Always return200 OK to acknowledge receipt:
- Initial retry: 5 minutes
- Subsequent retries: Up to 3 days
- Automatic disable after 30 days of failures
Testing Webhooks
Using Stripe CLI
Install Stripe CLI and forward events to your local server:Using Stripe Dashboard
Send test webhook events from Stripe Dashboard > Webhooks:- Click on your webhook endpoint
- Click “Send test webhook”
- Select event type
- Click “Send test webhook”
Webhook Flow
Handling Subscription Changes
Upgrade Flow
- User creates checkout session for higher plan
- Webhook:
checkout.session.completed - Webhook:
customer.subscription.updated - Subscription immediately upgraded
- Prorated charge applied
Downgrade Flow
- User changes plan in Customer Portal
- Webhook:
customer.subscription.updatedwithcancel_at_period_end: false - Current plan remains active until period end
- New plan activates at next billing cycle
Cancellation Flow
- User cancels in Customer Portal
- Webhook:
customer.subscription.updatedwithcancel_at_period_end: true - Subscription active until period end
- Webhook:
customer.subscription.deletedat period end - Automatic downgrade to FREE plan
Error Handling
Webhook handlers include comprehensive error handling:- Error is logged to console
- HTTP 500 returned to Stripe
- Stripe automatically retries the webhook
- PaymentEvent still recorded with error details
Monitoring Webhooks
Stripe Dashboard
Monitor webhook delivery in Stripe Dashboard > Webhooks:- View success/failure rates
- Inspect individual webhook attempts
- See retry history
- Resend failed webhooks manually
Application Logs
All webhook events are logged with structured data:Best Practices
- Always verify signatures: Never skip signature verification
- Return 200 quickly: Process webhooks asynchronously if needed
- Handle idempotency: Use
stripe_event_idto prevent duplicate processing - Log everything: Store webhook events for debugging and auditing
- Test thoroughly: Use Stripe CLI to test all event types
- Monitor failures: Set up alerts for webhook failures in Stripe Dashboard
- Handle retries: Ensure your webhook handler is idempotent
- Secure the endpoint: Keep your webhook secret confidential
Common Issues
Webhook Not Receiving Events
Signature Verification Failed
- Check that
STRIPE_WEBHOOK_SECRETis correct - Verify webhook endpoint uses
express.raw()middleware - Ensure no middleware modifies the request body before webhook handler
Duplicate Events
Stripe may send the same event multiple times. Handle idempotency:Next Steps
- Manage subscriptions via API
- Handle rate limits for webhook endpoints
- Review Stripe webhook documentation