11 KiB
Dodo Payments Webhooks Setup Guide
This guide explains how to configure Dodo Payments webhooks for the Shopify AI App Builder to handle payment events automatically, including failed payments, disputes, refunds, and subscription cancellations.
Overview
The webhook system handles these events:
- payment_succeeded: Process successful payments (top-ups, PAYG)
- payment_failed: Cancel subscription on failed payments
- payment_cancelled: Handle cancelled payments
- payment_processing: Handle processing payments
- payment_dispute_created: Cancel subscription when a dispute is opened
- dispute_accepted: Handle accepted disputes
- dispute_cancelled: Handle cancelled disputes
- dispute_challenged: Handle challenged disputes
- dispute_expired: Handle expired disputes
- dispute_lost: Handle lost disputes
- dispute_won: Handle won disputes
- charge_refunded: Log refund events
- refund_failed: Handle failed refunds
- subscription_canceled: Downgrade user to hobby plan
- subscription_payment_failed: Cancel subscription on recurring payment failures
- subscription_active: Activate subscription
- subscription_expired: Handle expired subscriptions
- subscription_on_hold: Handle subscriptions on hold
- subscription_plan_changed: Handle plan changes
- subscription_renewed: Handle subscription renewals
- subscription_updated: Handle subscription updates
Prerequisites
Before setting up webhooks, ensure you have:
- Dodo Payments account configured (see
dodo.md) - Your application deployed and accessible via public URL
- Dodo API key and environment configured
Step 1: Generate a Webhook Secret Key
- Log in to your Dodo Payments dashboard
- Navigate to Developer → Webhooks
- Click Create Webhook Secret
- Copy the generated webhook secret key (starts with
whsec_)
Example webhook secret: whsec_abc123def456ghi789jkl012mno345pqr
Step 2: Configure Environment Variable
Add the webhook secret to your environment configuration:
# Add to your .env file or deployment environment variables
DODO_PAYMENTS_WEBHOOK_KEY=whsec_abc123def456ghi789jkl012mno345pqr
Important: Restart your application after adding this variable.
Step 3: Determine Your Webhook URL
Your webhook URL will be:
https://your-domain.com/webhooks/dodo
Examples:
- Production:
https://plugincompass.ai/webhooks/dodo - Staging:
https://staging.plugincompass.ai/webhooks/dodo - Local development: Use a tunneling service like ngrok
Local Development with ngrok
If testing locally, use ngrok to expose your local server:
# Install ngrok if needed: https://ngrok.com/download
# Start ngrok (assuming your app runs on port 4000)
ngrok http 4000
# This will give you a URL like: https://abc123.ngrok.io
# Your webhook URL will be: https://abc123.ngrok.io/webhooks/dodo
Step 4: Register Webhook in Dodo Dashboard
- Navigate to Developer → Webhooks in Dodo Payments dashboard
- Click Add Webhook or Create Webhook
- Fill in the webhook details:
- Webhook URL:
https://your-domain.com/webhooks/dodo - Events to send: Select all events:
- ✅
payment.succeeded - ✅
payment.failed - ✅
payment.cancelled - ✅
payment.processing - ✅
payment.dispute.created - ✅
dispute.accepted - ✅
dispute.cancelled - ✅
dispute.challenged - ✅
dispute.expired - ✅
dispute.lost - ✅
dispute.won - ✅
charge.refunded - ✅
refund.failed - ✅
subscription.canceled - ✅
subscription.payment.failed - ✅
subscription.active - ✅
subscription.expired - ✅
subscription.on_hold - ✅
subscription.plan_changed - ✅
subscription.renewed - ✅
subscription.updated
- ✅
- Secret: Paste your webhook secret key (from Step 1)
- Webhook URL:
- Click Save or Create Webhook
Step 5: Test Webhook Configuration
Verify Webhook Endpoint
Check that your webhook endpoint is accessible:
curl -X POST https://your-domain.com/webhooks/dodo \
-H "Content-Type: application/json" \
-d '{"test": true}'
Expected response: {"received": true} (with HTTP 200 status)
Send Test Webhook
In the Dodo dashboard:
- Find your newly created webhook
- Click Send Test Event
- Select an event type (e.g.,
payment.succeeded) - Check your application logs for webhook receipt
You should see log entries like:
[2026-01-20T16:30:45.123Z] Dodo webhook received {"type":"payment.succeeded","id":"evt_..."}
Step 6: Monitor Webhook Logs
Application Logs
Your application logs webhook events with the following format:
[timestamp] Dodo webhook received {"type":"event_type","id":"event_id"}
[timestamp] payment_succeeded: top-up processed via webhook {"userId":"...","tokens":...}
[timestamp] payment_failed: subscription cancelled {"userId":"...","email":"..."}
Dodo Dashboard Logs
Monitor webhook delivery in the Dodo dashboard:
- Navigate to Developer → Webhooks
- Click on your webhook
- View delivery history and retry failed events
Webhook Event Handlers
payment_succeeded
- Processes successful one-time payments
- Adds tokens for top-ups
- Clears PAYG billing balance
- Logs the event
- Email sent to user with confirmation
payment_failed
- Cancels the user's subscription
- Downgrades to hobby plan
- Logs the cancellation reason
- Email sent to user
payment_cancelled
- Logs cancelled payments
- Email sent to user
payment_processing
- Logs processing payments
payment_dispute_created
- Immediately cancels the user's subscription
- Downgrades to hobby plan
- Logs the dispute ID and reason
- Email sent to user
dispute_accepted
- Handles accepted disputes
- Email sent to user
dispute_cancelled
- Handles cancelled disputes
- Email sent to user
dispute_challenged
- Handles challenged disputes
- Email sent to user
dispute_expired
- Handles expired disputes
- Email sent to user
dispute_lost
- Handles lost disputes
- Email sent to user
dispute_won
- Handles won disputes
- Email sent to user
charge_refunded
- Logs refund events
- No automatic action (manual review recommended)
- Tracks refunded amounts
- Email sent to user
refund_failed
- Handles failed refunds
- Email sent to user
subscription_canceled
- Downgrades user to hobby plan
- Clears subscription data
- Logs the cancellation
- Email sent to user
subscription_payment_failed
- Cancels subscription on recurring payment failure
- Downgrades to hobby plan
- Logs the failure event
- Email sent to user
subscription_active
- Activates subscription
- Updates billing status
- Email sent to user
subscription_expired
- Downgrades user to hobby plan
- Logs expiration
- Email sent to user
subscription_on_hold
- Places subscription on hold
- Updates billing status
- Email sent to user
subscription_plan_changed
- Updates user plan
- Logs plan change
- Email sent to user
subscription_renewed
- Marks subscription as renewed
- Updates renewal date
- Email sent to user
subscription_updated
- Updates subscription details
- Logs updates
Error Handling
The webhook endpoint:
- Always returns HTTP 200 to acknowledge receipt
- Logs all errors for debugging
- Continues processing even if individual events fail
- Uses timing-safe signature verification
Common Issues
Issue: Invalid signature error
- Cause: Webhook secret mismatch
- Solution: Verify
DODO_PAYMENTS_WEBHOOK_KEYmatches Dodo dashboard
Issue: Webhook not received
- Cause: URL not publicly accessible or firewall blocking
- Solution: Check URL accessibility and firewall settings
Issue: User not found in webhook
- Cause: Missing userId in payment metadata
- Solution: Ensure checkout sessions include userId in metadata
Security Best Practices
- Always use HTTPS: Webhooks must use HTTPS in production
- Verify signatures: The application validates webhook signatures
- Keep secrets secure: Never commit webhook secrets to version control
- Monitor logs: Regularly review webhook logs for suspicious activity
- Rate limiting: Dodo handles webhook delivery retries automatically
Webhook Signature Verification
The application uses HMAC-SHA256 signature verification:
const signature = req.headers['dodo-signature'];
const expectedSignature = `sha256=${crypto.createHmac('sha256', DODO_WEBHOOK_KEY).update(rawBody).digest('hex')}`;
If verification fails, the webhook returns HTTP 401.
Testing Different Scenarios
Test Failed Payment
- Create a test subscription
- Use a test card that will fail (e.g., expired card)
- Observe subscription cancellation in logs
Test Dispute Handling
- Create a test payment
- Create a test dispute in Dodo dashboard
- Observe subscription cancellation
Test Refund
- Create a test payment
- Process a refund in Dodo dashboard
- Observe refund logging
Troubleshooting
Check Webhook Delivery Status
In Dodo dashboard, view webhook delivery logs for:
- Delivery attempts
- Response codes
- Error messages
Enable Debug Logging
Add to your environment temporarily:
LOG_LEVEL=debug
Verify Metadata in Checkout Sessions
Ensure your checkout sessions include metadata:
{
metadata: {
userId: 'user-uuid',
type: 'subscription|topup|payg',
tokens: 100000
}
}
Production Checklist
- Webhook secret configured in environment
- Webhook endpoint accessible via HTTPS
- All event types enabled in Dodo dashboard
- Test webhooks sent successfully
- Application logs show webhook receipt
- Failed payments trigger subscription cancellation
- Cancelled payments are logged
- Processing payments are tracked
- Disputes trigger subscription cancellation
- Dispute accepted events are handled
- Dispute cancelled events are handled
- Dispute challenged events are handled
- Dispute expired events are handled
- Dispute lost events are handled
- Dispute won events are handled
- Refunds are logged correctly
- Failed refunds are handled
- Subscription cancellations downgrade users correctly
- Subscription payment failures trigger cancellation
- Subscription active events activate subscriptions
- Subscription expired events downgrade users
- Subscription on hold events are handled
- Subscription plan changed events update plans
- Subscription renewed events update renewal dates
- Subscription updated events update subscription details
- Email notifications are sent for all appropriate events
Webhook Reference
Endpoint
POST /webhooks/dodo
Headers
Content-Type: application/json
dodo-signature: sha256=...
Event Payload Structure
{
"id": "evt_abc123",
"type": "payment_succeeded",
"data": {
"id": "pay_xyz789",
"amount": 7500,
"currency": "usd",
"status": "succeeded",
"metadata": {
"userId": "user-uuid",
"type": "subscription"
}
},
"created_at": "2026-01-20T16:30:45Z"
}
Support
- Dodo Payments Documentation: https://docs.dodopayments.com
- Dodo Support: Contact via Dodo dashboard
- Application Issues: Check application logs first, then review this guide
Updates
Last updated: January 20, 2026