Change Plan API Reference
Subscription Integration Guide
What is a subscription upgrade or downgrade?
Changing plans lets you move a customer between subscription tiers or quantities. Use it to:- Align pricing with usage or features
- Move from monthly to annual (or vice versa)
- Adjust quantity for seat-based products
When to use plan changes
- Upgrade when a customer needs more features, usage, or seats
- Downgrade when usage decreases
- Migrate users to a new product or price without cancelling their subscription
Prerequisites
Before implementing subscription plan changes, ensure you have:- A Dodo Payments merchant account with active subscription products
- API credentials (API key and webhook secret key) from the dashboard
- An existing active subscription to modify
- Webhook endpoint configured to handle subscription events
Step-by-Step Implementation Guide
Follow this comprehensive guide to implement subscription plan changes in your application:Understand Plan Change Requirements
- Which subscription products can be changed to which others
- What proration mode fits your business model
- How to handle failed plan changes gracefully
- Which webhook events to track for state management
Choose Your Proration Strategy
- prorated_immediately
- difference_immediately
- full_immediately
- Calculates exact prorated amount based on remaining cycle time
- Charges a prorated amount based on unused time remaining in the cycle
- Provides transparent billing to customers
Implement the Change Plan API
prorated_immediately
, full_immediately
, or difference_immediately
.Handle Webhook Events
subscription.active
: Plan change successful, subscription updatedsubscription.plan_changed
: Subscription plan changed (upgrade/downgrade/addon update)subscription.on_hold
: Plan change charge failed, subscription pausedpayment.succeeded
: Immediate charge for plan change succeededpayment.failed
: Immediate charge failed
Update Your Application State
- Grant/revoke features based on new plan
- Update customer dashboard with new plan details
- Send confirmation emails about plan changes
- Log billing changes for audit purposes
Test and Monitor
- Test all proration modes with different scenarios
- Verify webhook handling works correctly
- Monitor plan change success rates
- Set up alerts for failed plan changes
Change Plan API
Use the Change Plan API to modify product, quantity, and proration behavior for an active subscription.Quick start examples
- Node.js SDK
- Python SDK
- Go SDK
- HTTP
invoice_id
and payment_id
are returned only when an immediate charge and/or invoice is created during the plan change. Always rely on webhook events (e.g., payment.succeeded
, subscription.plan_changed
) to confirm outcomes.subscription.on_hold
until payment succeeds.Managing Addons
When changing subscription plans, you can also modify addons:Proration modes
Choose how to bill the customer when changing plans:prorated_immediately
- Charges for the partial difference in the current cycle
- If in trial, charges immediately and switches to the new plan now
- Downgrade: may generate a prorated credit applied to future renewals
full_immediately
- Charges the full amount of the new plan immediately
- Ignores remaining time from the old plan
difference_immediately
are subscription-scoped and distinct from Customer Credits. They automatically apply to future renewals of the same subscription and are not transferable between subscriptions.difference_immediately
- Upgrade: immediately charge the price difference between old and new plans
- Downgrade: add remaining value as internal credit to the subscription and auto-apply on renewals
Example scenarios
Upgrade: Basic ($30) → Pro ($80) with difference_immediately
Upgrade: Basic ($30) → Pro ($80) with difference_immediately
Downgrade: Plus ($50) → Starter ($20) with difference_immediately
Downgrade: Plus ($50) → Starter ($20) with difference_immediately
Upgrade mid-cycle with prorated_immediately
Upgrade mid-cycle with prorated_immediately
Reset billing with full_immediately
Reset billing with full_immediately
prorated_immediately
for fair-time accounting; choose full_immediately
to restart billing; use difference_immediately
for simple upgrades and automatic credit on downgrades.Handling webhooks
Track subscription state through webhooks to confirm plan changes and payments.Event types to handle
subscription.active
: subscription activatedsubscription.plan_changed
: subscription plan changed (upgrade/downgrade/addon changes)subscription.on_hold
: charge failed, subscription pausedsubscription.renewed
: renewal succeededpayment.succeeded
: payment for plan change or renewal succeededpayment.failed
: payment failed
Verify signatures and handle intents
- Next.js Route Handler
- Express.js
Best Practices
Follow these recommendations for reliable subscription plan changes:Plan Change Strategy
- Test thoroughly: Always test plan changes in test mode before production
- Choose proration carefully: Select the proration mode that aligns with your business model
- Handle failures gracefully: Implement proper error handling and retry logic
- Monitor success rates: Track plan change success/failure rates and investigate issues
Webhook Implementation
- Verify signatures: Always validate webhook signatures to ensure authenticity
- Implement idempotency: Handle duplicate webhook events gracefully
- Process asynchronously: Don’t block webhook responses with heavy operations
- Log everything: Maintain detailed logs for debugging and audit purposes
User Experience
- Communicate clearly: Inform customers about billing changes and timing
- Provide confirmations: Send email confirmations for successful plan changes
- Handle edge cases: Consider trial periods, prorations, and failed payments
- Update UI immediately: Reflect plan changes in your application interface
Common Issues and Solutions
Resolve typical problems encountered during subscription plan changes:Charge created but subscription not updated
Charge created but subscription not updated
- Webhook processing failed or was delayed
- Application state not updated after receiving webhooks
- Database transaction issues during state update
- Implement robust webhook handling with retry logic
- Use idempotent operations for state updates
- Add monitoring to detect and alert on missed webhook events
- Verify webhook endpoint is accessible and responding correctly
Credits not applied after downgrade
Credits not applied after downgrade
- Proration mode expectations: downgrades credit the full plan price difference with
difference_immediately
, whileprorated_immediately
creates a prorated credit based on remaining time in the cycle - Credits are subscription-specific and don’t transfer between subscriptions
- Credit balance not visible in customer dashboard
- Use
difference_immediately
for downgrades when you want automatic credits - Explain to customers that credits apply to future renewals of the same subscription
- Implement customer portal to show credit balances
- Check next invoice preview to see applied credits
Webhook signature verification fails
Webhook signature verification fails
- Incorrect webhook secret key
- Raw request body modified before signature verification
- Wrong signature verification algorithm
- Verify you’re using the correct
DODO_WEBHOOK_SECRET
from dashboard - Read raw request body before any JSON parsing middleware
- Use the standard webhook verification library for your platform
- Test webhook signature verification in development environment
Plan change fails with 422 error
Plan change fails with 422 error
- Invalid subscription ID or product ID
- Subscription not in active state
- Missing required parameters
- Product not available for plan changes
- Verify subscription exists and is active
- Check product ID is valid and available
- Ensure all required parameters are provided
- Review API documentation for parameter requirements
Immediate charge fails during plan change
Immediate charge fails during plan change
- Insufficient funds on customer’s payment method
- Payment method expired or invalid
- Bank declined the transaction
- Fraud detection blocked the charge
- Handle
payment.failed
webhook events appropriately - Notify customer to update payment method
- Implement retry logic for temporary failures
- Consider allowing plan changes with failed immediate charges
Testing Your Implementation
Follow these steps to thoroughly test your subscription plan change implementation:Set up test environment
- Use test API keys and test products
- Create test subscriptions with different plan types
- Configure test webhook endpoint
- Set up monitoring and logging
Test different proration modes
- Test
prorated_immediately
with various billing cycle positions - Test
difference_immediately
for upgrades and downgrades - Test
full_immediately
to reset billing cycles - Verify credit calculations are correct
Test webhook handling
- Verify all relevant webhook events are received
- Test webhook signature verification
- Handle duplicate webhook events gracefully
- Test webhook processing failure scenarios
Test error scenarios
- Test with invalid subscription IDs
- Test with expired payment methods
- Test network failures and timeouts
- Test with insufficient funds
Monitor in production
- Set up alerts for failed plan changes
- Monitor webhook processing times
- Track plan change success rates
- Review customer support tickets for plan change issues
Error Handling
Handle common API errors gracefully in your implementation:HTTP Status Codes
200 OK
200 OK
400 Bad Request
400 Bad Request
401 Unauthorized
401 Unauthorized
404 Not Found
404 Not Found
422 Unprocessable Entity
422 Unprocessable Entity
500 Internal Server Error
500 Internal Server Error
Error Response Format
Next steps
- Review the Change Plan API
- Explore Customer Credits
- Implement alerts for
subscription.on_hold
- Check out our Webhook Integration Guide