Change Plan API
Plan Change Preview
Integration Guide
Subscription Upgrade या Downgrade क्या है?
किसी customer के subscription plan को बदलकर उसे अलग-अलग tiers के बीच ले जाएँ, seat-based products के लिए quantity समायोजित करें, या नए product पर migrate करें। API आपके चुने हुए billing mode के आधार पर prorations और charges की स्वचालित गणना करता है।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
Plan Change Flow
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
- do_not_bill
- वर्तमान cycle के अप्रयुक्त हिस्से का समय शेष रहने के आधार पर prorated credit देता है
- फिर नए plan पर पूरे cycle का charge लेता है — नए plan की price कभी prorated नहीं होती
- Net charge = पूरा नया cycle − (शेष अंश × पूरा पुराना cycle)
Implement the Change Plan API
prorated_immediately, full_immediately, difference_immediately, or do_not_bill.null भेजने या एक खाली array भेजने से कोई भी मौजूदा ऐड-ऑन हट जाते हैं, इसलिए उन्हें बनाए रखने के लिए वर्तमान ऐड-ऑन शामिल करें।prevent_change: Keep subscription on current plan until payment succeedsapply_change(default): Apply plan change immediately regardless of payment outcome
allow_plan_change_via_payment_link capability (Settings → Subscriptions → Collect Plan Change Payments by Payment Link), effective_at: immediately और on_payment_failure: prevent_change आवश्यक हैं। Collecting Payment via a Checkout Link देखें। Preview route इसे अनदेखा करता है।- Not provided /
null— यदि नए product पर लागू हों, तोpreserve_on_plan_change=trueवाले मौजूदा discounts सुरक्षित रखे जाते हैं। [](empty array) — subscription से सभी मौजूदा discounts हटा देता है।["CODE_A", "CODE_B", ...]— किसी भी मौजूदा discount को इस stacked set से replace करता है।
discount_codes को प्राथमिकता दें। यह field backward compatibility के लिए अभी भी काम करता है, लेकिन उसी request में इसे discount_codes के साथ combine नहीं किया जा सकता।immediately(default): Plan change तुरंत लागू करेंnext_billing_date: Change को अगली billing date के लिए schedule करें। Billing period समाप्त होने तक customer अपना वर्तमान plan रखता है। Downgrades के लिए इसका उपयोग करें, ताकि customers billing period के अंत तक अपने वर्तमान plan के benefits बनाए रखें।
Handle Webhook Events
subscription.active: Plan change सफल, subscription updatedsubscription.plan_changed: Subscription plan changed (upgrade/downgrade/addon update)subscription.on_hold: Plan change charge विफल, renewals stoppedpayment.succeeded: Plan change का immediate charge सफलpayment.failed: Immediate charge विफल
Update Your Application State
- नए plan के आधार पर features grant/revoke करें
- नए plan के details के साथ customer dashboard update करें
- Plan changes के बारे में confirmation emails भेजें
- Audit purposes के लिए billing changes log करें
Test and Monitor
- अलग-अलग scenarios के साथ सभी proration modes test करें
- Verify करें कि webhook handling सही तरह काम कर रही है
- Plan change success rates monitor करें
- Failed plan changes के लिए alerts setup करें
Plan Changes का Preview लें
Plan change को commit करने से पहले, customers को ठीक-ठीक दिखाने के लिए Preview API का उपयोग करें कि उनसे कितना charge लिया जाएगा:- Node.js SDK
- Python SDK
Change Plan API
Active subscription के product, quantity और proration behavior को modify करने के लिए Change Plan API का उपयोग करें।Quick Start Examples
- Node.js SDK
- Python SDK
- Go SDK
- HTTP
200 OK लौटाता है — किसी भी charge के वास्तव में settle होने से पहले। Body (ChangePlanResponse) में क्या होगा, यह इस बात पर निर्भर करता है कि change कैसे collect किया गया:
collect_via_payment_link request के लिए, customer द्वारा payment पूरा करने तक subscription अपने वर्तमान plan पर रहती है।Webhook (payment.succeeded, payment.failed, subscription.plan_changed) के माध्यम से या GET /subscriptions/{subscription_id} के साथ subscription को दोबारा पढ़कर outcome की पुष्टि करें — payment-link case के लिए What Happens While the Link Is Unpaid देखें।Checkout Link के माध्यम से Payment Collect करना
Default रूप से, immediate plan change subscription के saved payment method से सीधे charge करता है। इसके बजाय customer को hosted checkout page पर भेजने के लिएcollect_via_payment_link: true सेट करें — यह तब उपयोगी है जब कोई saved payment method न हो या आप चाहते हों कि customer नई price को actively confirm करे।
Requirements
collect_via_payment_link: true तभी सफल होता है जब सभी निम्न शर्तें पूरी हों — अन्यथा request 422 के साथ fail होती है:
- Business में
allow_plan_change_via_payment_linkcapability enabled हो (Settings → Subscriptions → Collect Plan Change Payments by Payment Link)। effective_at,immediatelyहो (default)। Scheduled change (next_billing_date) को checkout page की आवश्यकता कभी नहीं होती।- Effective
on_payment_failure,prevent_changeपर resolve हो। इसे explicitly भेजना आवश्यक नहीं — यदि business-level default पहले सेprevent_changeहै, तो field छोड़ने पर यह शर्त पूरी हो जाती है। Explicitapply_change,422के साथ fail होता है।
collect_via_payment_link किसी भी immediate change पर लागू होता है जिसके परिणामस्वरूप charge होता है, downgrades सहित, बशर्ते ऊपर दी गई requirements पूरी हों।payment_link और अन्य checkout fields null के रूप में लौटते हैं और change तुरंत लागू हो जाता है। यह 422 नहीं है। Link request करने से पहले amount जाँचने के लिए Preview Plan Change को call करें।
- Node.js SDK
- Python SDK
- HTTP
जब Link Unpaid हो तो क्या होता है
- Subscription अपने वर्तमान plan पर रहती है —
product_id,recurring_pre_tax_amountऔरnext_billing_dateसभी link के paid होने तक अपरिवर्तित रहते हैं। - Link pending रहने के दौरान आगे की
change-planrequest,409 PendingPlanChangeExistsके साथ reject होती है। आवश्यकता होने पर scheduled change कोDELETE /subscriptions/{subscription_id}/change-plan/scheduledसे cancel करें, लेकिन वह endpoint pending payment-link change को cancel नहीं करता — केवल सफल payment या expiry ही ऐसा करता है। - Decline के बाद customer उसी checkout session पर card retry कर सकता है; नई
change-plancall retry path नहीं है। - यदि link कभी paid नहीं होता, तो
expires_onके बाद वह काम करना बंद कर देता है — subscription शीघ्र ही नए plan-change request को स्वीकार करने के लिए स्वतः free हो जाती है। - यदि कोई scheduled change पहले से मौजूद था और आप उसे
cancel_scheduled_change_plan: trueसे replace करते हैं, तो link unpaid रहने तक original schedule बना रहता है और link paid होने पर ही cancel होता है — उसी transaction में जिसमें नया plan लागू होता है।
Addons Manage करना
Subscription plans बदलते समय आप addons को भी modify कर सकते हैं:Discount Codes लागू करना
Subscription plans बदलते समय एक या अधिक stacked discount codes लागू करें (अधिकतम 20, array order में लागू):- Node.js SDK
- Python SDK
- HTTP
Plan Change पर Discount Behavior
discount_code field deprecated है, लेकिन backward compatibility के लिए अभी भी काम करता है — मौजूदा integrations को तुरंत बदलने की आवश्यकता नहीं है। इसे उसी request में discount_codes के साथ combine नहीं किया जा सकता। सुविधा के अनुसार array form पर migrate करें।Proration Modes
Plans बदलते समय customer को bill करने का तरीका चुनें:prorated_immediately
- वर्तमान cycle — base plan, quantity और add-ons — के अप्रयुक्त हिस्से का समय शेष रहने के आधार पर prorated credit देता है
- फिर नए plan, quantity और add-ons पर पूरे cycle का charge लेता है। Charge स्वयं कभी prorated नहीं होता
- Net immediate charge = (पूरा नया cycle) − (शेष अंश × पूरा पुराना cycle)
- यदि credit नए cycle charge से अधिक हो (जो downgrades में सामान्य है), तो अंतर subscription-scoped credit के रूप में future renewals के लिए रखा जाता है
- यदि trial में है, तो तुरंत charge करता है और अभी नए plan पर switch करता है
full_immediately
- नए plan की पूरी amount तुरंत charge करता है
- पुराने plan का शेष समय अनदेखा करता है — वर्तमान cycle के लिए कोई credit नहीं
prorated_immediately और difference_immediately का उपयोग करने वाले downgrades से बनाए गए credits subscription-scoped होते हैं और Credit-Based Billing entitlements से अलग होते हैं। वे उसी subscription के future renewals पर स्वतः लागू होते हैं और subscriptions के बीच transfer नहीं किए जा सकते।difference_immediately
- Upgrade: पुराने और नए plans के बीच price difference तुरंत charge करता है
- Downgrade: शेष value को subscription में internal credit के रूप में जोड़ता है और renewals पर स्वतः लागू करता है
do_not_bill
- कोई charges या credits calculate नहीं किए जाते
- Customer बिना किसी billing adjustment के तुरंत नए plan पर switch करता है
- Billing cycle अपरिवर्तित रहता है
- Courtesy migrations, free plan switches या cost differences को absorb करने के लिए उपयुक्त
Example Scenarios
इन canonical numbers का लगातार उपयोग करें:- Current plan: Basic at $30/month
- Upgrade target: Pro at $80/month
- Downgrade target (from Pro): Starter at $20/month
- Billing cycle: 30 days, started on January 1
- Plan change happens on January 16 (15 days remaining, 15 days used)
Upgrade: Basic ($30) → Pro ($80) with prorated_immediately
Upgrade: Basic ($30) → Pro ($80) with prorated_immediately
Downgrade: Pro ($80) → Starter ($20) with prorated_immediately
Downgrade: Pro ($80) → Starter ($20) with prorated_immediately
Upgrade: Basic ($30) → Pro ($80) with difference_immediately
Upgrade: Basic ($30) → Pro ($80) with difference_immediately
Downgrade: Pro ($80) → Starter ($20) with difference_immediately
Downgrade: Pro ($80) → Starter ($20) with difference_immediately
Upgrade: Basic ($30) → Pro ($80) with full_immediately
Upgrade: Basic ($30) → Pro ($80) with full_immediately
Mid-cycle upgrade with add-ons using prorated_immediately
Mid-cycle upgrade with add-ons using prorated_immediately
प्रत्येक Mode Billing को कैसे Process करता है
Payment Failures Handle करना
on_payment_failure parameter का उपयोग करके नियंत्रित करें कि plan change payment विफल होने पर क्या होगा।
Payment Failure Modes
- prevent_change (Recommended for critical upgrades)
- apply_change (Default)
- Plan change को “pending” के रूप में mark किया जाता है
- Customer अपने वर्तमान plan का access बनाए रखता है
- सफल payment के बाद ही subscription
activestate में जाती है - तब उपयोगी जब upgraded features देने से पहले payment सुनिश्चित करना हो
on_payment_failure parameter dashboard में configured business-level default setting का उपयोग करता है।प्रत्येक Mode का उपयोग कब करें
Business & Collection Defaults
Settings → Subscriptions के अंतर्गत business level पर default upgrade और downgrade behavior सेट करें। ये defaults सभी customer-portal plan changes पर लागू होते हैं और इन्हें per product collection override किया जा सकता है। Upgrades और downgrades के लिए अलग-अलग defaults मौजूद हैं:Resolution Order
किसी भी plan change के लिए प्रत्येक setting इस order में resolve होती है:Webhooks Handle करना
Plan changes और payments की पुष्टि करने के लिए webhooks के माध्यम से subscription state track करें।Handle करने योग्य Event Types
subscription.active: subscription activatedsubscription.plan_changed: subscription plan changed (upgrade/downgrade/addon changes)subscription.on_hold: charge failed, renewals stoppedsubscription.renewed: renewal succeededpayment.succeeded: plan change या renewal का payment सफलpayment.failed: payment failed
Signatures Verify करें और Intents Handle करें
- Next.js Route Handler
- Express.js
Best Practices
Plan Change Strategy
- Thoroughly test करें: Production से पहले plan changes को हमेशा test mode में test करें
- Proration सावधानी से चुनें: अपने business model के अनुरूप proration mode चुनें
- Failures को gracefully handle करें: उचित error handling और retry logic लागू करें
- Success rates monitor करें: Plan change success/failure rates track करें और issues की जाँच करें
Webhook Implementation
- Signatures verify करें: Authenticity सुनिश्चित करने के लिए webhook signatures को हमेशा validate करें
- Idempotency लागू करें: Duplicate webhook events को gracefully handle करें
- Asynchronously process करें: Heavy operations से webhook responses को block न करें
- सब कुछ log करें: Debugging और audit purposes के लिए detailed logs बनाए रखें
User Experience
- स्पष्ट रूप से communicate करें: Customers को billing changes और timing के बारे में सूचित करें
- Confirmations दें: सफल plan changes के लिए email confirmations भेजें
- Edge cases handle करें: Trial periods, prorations और failed payments पर विचार करें
- UI तुरंत update करें: अपने application interface में plan changes reflect करें
सामान्य समस्याएँ और समाधान
Subscription plan changes के दौरान आने वाली typical problems को resolve करें:Charge created but subscription not updated
Charge created but subscription not updated
- Webhook processing विफल या delayed है
- Webhooks प्राप्त होने के बाद application state update नहीं हुई
- State update के दौरान database transaction issues
- Retry logic के साथ webhook handling लागू करें
- State updates के लिए idempotent operations का उपयोग करें
- Missed webhook events detect और alert करने के लिए monitoring जोड़ें
- Verify करें कि webhook endpoint accessible है और सही response दे रहा है
Credits not applied after downgrade
Credits not applied after downgrade
- Proration mode expectations:
difference_immediatelyके साथ downgrades पूरी plan price difference को credit करते हैं, जबकिprorated_immediatelyपुराने cycle के अप्रयुक्त समय को credit करता है और फिर नए plan पर पूरे cycle का charge लेता है — इसलिए credit balance तभी बचता है जब वह नए plan price से अधिक हो - Credits subscription-specific होते हैं और subscriptions के बीच transfer नहीं होते
- Credit balance customer dashboard में दिखाई नहीं देता
- Automatic credits चाहने पर downgrades के लिए
difference_immediatelyका उपयोग करें - Customers को समझाएँ कि credits उसी subscription के future renewals पर लागू होते हैं
- Credit balances दिखाने के लिए customer portal लागू करें
- Applied credits देखने के लिए next invoice preview check करें
Webhook signature verification fails
Webhook signature verification fails
- Incorrect webhook secret key
- Signature verification से पहले raw request body modify की गई
- गलत signature verification algorithm
- Dashboard से सही
DODO_PAYMENTS_WEBHOOK_KEYउपयोग कर रहे हैं, यह verify करें - किसी भी JSON parsing middleware से पहले raw request body पढ़ें
- अपने platform के लिए standard webhook verification library का उपयोग करें
- Development environment में webhook signature verification test करें
Plan change fails with 422 error
Plan change fails with 422 error
- Invalid subscription ID या product ID
- Subscription active state में नहीं है
- Required parameters missing हैं
- Product plan changes के लिए available नहीं है
- Verify करें कि subscription मौजूद और active है
- Check करें कि product ID valid और available है
- सुनिश्चित करें कि सभी required parameters दिए गए हैं
- Parameter requirements के लिए API documentation review करें
Immediate charge fails during plan change
Immediate charge fails during plan change
- Customer के payment method में insufficient funds
- Payment method expired या invalid है
- Bank ने transaction decline कर दिया
- Fraud detection ने charge block कर दिया
payment.failedwebhook events को उचित रूप से handle करें- Customer को payment method update करने के लिए सूचित करें
- Temporary failures के लिए retry logic लागू करें
- Failed immediate charges के साथ plan changes allow करने पर विचार करें
Subscription on hold after plan change
Subscription on hold after plan change
on_hold state पर चली जाती हैWhat happens:
जब plan change charge विफल होता है, तो subscription स्वतः on_hold state में चली जाती है। Payment method update होने तक subscription स्वतः renew नहीं होगी।Solution: Subscription को reactivate करने के लिए payment method update करेंFailed plan change के बाद on_hold state से subscription reactivate करने के लिए:- Payment method update करें Update Payment Method API का उपयोग करके
- Automatic charge creation: API remaining dues के लिए charge स्वतः create करती है
- Invoice generation: Charge के लिए invoice generate होती है
- Payment processing: नए payment method का उपयोग करके payment process होता है
- Reactivation: सफल payment के बाद subscription
activestate में reactivate हो जाती है
subscription.on_hold: Subscription hold पर रखी गई (plan change charge विफल होने पर प्राप्त)payment.succeeded: Remaining dues का payment सफल (payment method update करने के बाद)subscription.active: सफल payment के बाद subscription reactivated
- Plan change charge विफल होने पर customers को तुरंत notify करें
- Payment method update करने के स्पष्ट instructions दें
- Reactivation status track करने के लिए webhook events monitor करें
- Temporary payment failures के लिए automatic retry logic लागू करने पर विचार करें
Update Payment Method API Reference
अपने Implementation का Testing
अपने subscription plan change implementation का thoroughly test करें:Set up test environment
- Test API keys और test products का उपयोग करें
- अलग-अलग plan types के साथ test subscriptions create करें
- Test webhook endpoint configure करें
- Monitoring और logging setup करें
Test different proration modes
- विभिन्न billing cycle positions के साथ
prorated_immediatelytest करें - Upgrades और downgrades के लिए
difference_immediatelytest करें - Billing cycles reset करने के लिए
full_immediatelytest करें - No-charge/no-credit plan switches के लिए
do_not_billtest करें - Verify करें कि credit calculations सही हैं
Test webhook handling
- Verify करें कि सभी relevant webhook events प्राप्त हो रहे हैं
- Webhook signature verification test करें
- Duplicate webhook events को gracefully handle करें
- Webhook processing failure scenarios test करें
Test error scenarios
- Invalid subscription IDs के साथ test करें
- Expired payment methods के साथ test करें
- Network failures और timeouts test करें
- Insufficient funds के साथ test करें
Monitor in production
- Failed plan changes के लिए alerts setup करें
- Webhook processing times monitor करें
- Plan change success rates track करें
- Plan change issues के लिए customer support tickets review करें
Error Handling
अपने implementation में common API errors को gracefully handle करें:HTTP Status Codes
200 OK
200 OK
ChangePlanResponse है जिसमें payment_id, payment_link, client_secret और expires_on हैं। सभी चार nullable हैं, इसलिए ordinary off-session change के लिए body {} के रूप में serialize होती है; सफल collect_via_payment_link request के लिए ये populated होते हैं, जो checkout handles लौटाती है — Collecting Payment via a Checkout Link देखें। यदि on_payment_failure=prevent_change है, तो payment सफल होने तक plan change pending रहती है।400 Bad Request
400 Bad Request
409 Conflict
409 Conflict
PendingPlanChangeExists)। Scheduled change के लिए नया change submit करने से पहले इसे DELETE /subscriptions/{subscription_id}/change-plan/scheduled से cancel करें। Pending payment-link change के लिए कोई cancel endpoint नहीं है — customer के pay करने या link expire होने के बाद subscription नया plan-change request स्वीकार करती है।422 Unprocessable Entity
422 Unprocessable Entity
collect_via_payment_link के लिए eligible नहीं है — business में capability enabled नहीं है, effective_at, immediately नहीं है, या on_payment_failure, prevent_change नहीं है। Requirements देखें। जो subscription ID मौजूद नहीं है या आपके account से संबंधित नहीं है, वह NOT_FOUND code के साथ 404 लौटाती है।500 Internal Server Error
500 Internal Server Error
Error Response Format
Errors एक JSON body लौटाती हैं जिसमेंcode और human-readable message होता है:
Next Steps
- Change Plan API review करें
- Credit-Based Billing explore करें
subscription.on_holdके लिए alerts implement करें- Webhook Integration Guide देखें