Change Plan API
Plan Change Preview
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
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
- 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.prevent_change: Keep subscription on current plan until payment succeedsapply_change(default): Apply plan change immediately regardless of payment outcome
preserve_on_plan_change=true، فسيتم الحفاظ على الخصم الحالي (إذا كان قابلاً للتطبيق على المنتج الجديد).Handle Webhook Events
subscription.active: تغيير الخطة ناجح، تم تحديث الاشتراكsubscription.plan_changed: تم تغيير خطة الاشتراك (ترقية/ تخفيض/ تحديث إضافات)subscription.on_hold: فشل شحن تغيير الخطة، تم إيقاف الاشتراك مؤقتاًpayment.succeeded: نجاح شحن فوري لتغيير الخطةpayment.failed: فشل الشحن الفوري
Update Your Application State
- منح/إلغاء الميزات استناداً إلى الخطة الجديدة
- تحديث لوحة تحكم العملاء بتفاصيل الخطة الجديدة
- إرسال رسائل بريد إلكتروني تأكيدية حول تغيير الخطة
- تسجيل تغييرات الفواتير لأغراض التدقيق
معاينة تغييرات الخطة
قبل الالتزام بتغيير الخطة، استخدم الـ Preview API لعرض ما سيتم تحصيله من العملاء بالتحديد:- Node.js SDK
- Python SDK
API تغيير الخطة
استخدم API تغيير الخطة لتعديل المنتج والكمية وسلوك النسبة للاشتراك النشط.أمثلة بداية سريعة
- Node.js SDK
- Python SDK
- Go SDK
- HTTP
invoice_id وpayment_id تُرجع فقط عند إنشاء شحن فوري و/أو فاتورة أثناء تغيير الخطة. اعتمد دائماً على أحداث webhook (مثل payment.succeeded، subscription.plan_changed) لتأكيد النتائج.إدارة الإضافات
عند تغيير خطط الاشتراك، يمكنك أيضاً تعديل الإضافات:تطبيق رموز الخصم
يمكنك تطبيق رمز خصم عند تغيير خطط الاشتراك. هذا مفيد لتقديم أسعار ترويجية على الترقيات أو النقل.- Node.js SDK
- Python SDK
- HTTP
سلوك الخصم عند تغيير الخطة
| السيناريو | السلوك |
|---|---|
discount_code تم تقديمه | يتم التحقق وتطبيق الخصم على الخطة الجديدة. |
لم يتم تقديم أي رمز، الخصم الحالي مع preserve_on_plan_change=true | يتم تلقائياً الحفاظ على الخصم الحالي إذا كان قابلاً للتطبيق على المنتج الجديد. |
| لم يتم تقديم أي رمز، لا يوجد خصم قابل للحفظ | لا يتم تطبيق أي خصم على الخطة الجديدة. |
أوضاع النسبة
اختر كيفية فوترت العميل عند تغيير الخطط:prorated_immediately
- تفرض رسوم على الفرق الجزئي في الدورة الحالية
- إذا كانت تحت التجربة، تفرض الرسوم فوراً وتتحول إلى الخطة الجديدة الآن
- خفض: قد يُنشئ رصيداً بنسبة معينة يُطبق على التجديدات القادمة
full_immediately
- تفرض الرسوم الكاملة للخطة الجديدة فوراً
- تتجاهل الوقت المتبقي من الخطة القديمة
difference_immediately مخصصة للاشتراك ومتميزة عن الفوترة القائمة على الائتمان. تُطبق تلقائياً على التجديدات المستقبلية لنفس الاشتراك ولا يمكن نقلها بين الاشتراكات.difference_immediately
- ترقية: تُفرض رسوم الفروق السعرية بين الخطط القديمة والجديدة فوراً
- تخفيض: تُضاف القيمة المتبقية كرصيد داخلي للاشتراك وتُطبق تلقائياً على التجديدات
| الميزة | prorated_immediately | difference_immediately | full_immediately |
|---|---|---|---|
| رسوم الترقية | الفرق النسبي لأيام الباقية | الفرق السعري الكامل بين الخطط | السعر الكامل للخطة الجديدة |
| رصيد التخفيض | رصيد نسبي لأيام الباقية | الفرق السعري الكامل كرصيد | لا رصيد |
| دورة الفوترة | لم يتغير | لم يتغير | يعيد الضبط إلى اليوم |
| سلوك التجربة | ينهي التجربة، يفرض الرسوم فوراً | ينهي التجربة، يفرض الرسوم فوراً | ينهي التجربة، يفرض المبلغ الكامل |
| الأفضل لـ | فوترة عادلة مستندة إلى الوقت | حساب بسيط للترقية/التخفيض | إعادة ضبط دورات الفوترة |
| التعقيد | متوسط (حساب اليوم) | منخفض (الطرح البسيط) | منخفض (الرسوم الكاملة) |
سيناريوهات مثال
استخدم هذه الأرقام القياسية باستمرار:- الخطة الحالية: أساسي بسعر 30 دولار/شهراً
- هدف الترقية: محترف بسعر 80 دولار/شهراً
- هدف التخفيض (من المحترف): مبتدئ بسعر 20 دولار/شهراً
- دورة الفوترة: 30 يوماً، بدأت في 1 يناير
- تغيير الخطة يحدث في 16 يناير (15 يوماً متبقة، 15 يوماً مستخدمة)
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
كيف يعالج كل نمط الفوترة
التعامل مع فشل الدفع
تحكم فيما يحدث عندما يفشل دفع تغيير الخطة باستخدام المعلمةon_payment_failure.
أوضاع فشل الدفع
- prevent_change (Recommended for critical upgrades)
- apply_change (Default)
- يتم تحديد تغيير الخطة كـ “معلق”
- يحتفظ العميل بالوصول إلى خطته الحالية
- ينتقل الاشتراك إلى حالة
activeفقط بعد الدفع الناجح - مفيد عندما ترغب في ضمان الدفع قبل منح الميزات المترقية
on_payment_failure إعدادك الافتراضي للمستوى التجاري الذي تم تهيئته في لوحة التحكم.متى تستخدم كل نمط
| السيناريو | النمط الموصى به | السبب |
|---|---|---|
| الترقية إلى ميزات مميزة | prevent_change | ضمان الدفع قبل منح الوصول |
| زيادة الكمية (مزيد من المقاعد) | prevent_change | منع الاستخدام بدون الدفع |
| تخفيض الخطط | apply_change | العميل يقلل الإنفاق |
| العملاء المؤسسيون الموثوق بهم | apply_change | مخاطر عدم الدفع منخفضة |
| التحويل من تجربة إلى مدفوع | prevent_change | لحظة دفع حرجة |
التعامل مع webhooks
تتبع حالة الاشتراك من خلال webhooks لتأكيد تغييرات الخطة والمدفوعات.أنواع الأحداث للتعامل معها
subscription.active: تفعيل الاشتراكsubscription.plan_changed: تم تغيير خطة الاشتراك (ترقية/تخفيض/تغييرات الإضافات)subscription.on_hold: فشل الشحن، تم إيقاف الاشتراك مؤقتاًsubscription.renewed: تجديد نجاحpayment.succeeded: دفعة ناجحة لتغيير الخطة أو التجديدpayment.failed: فشل الدفع
التحقق من التوقيعات ومعالجة النوايا
- Next.js Route Handler
- Express.js
أفضل الممارسات
اتبع هذه التوصيات لإجراء تغييرات موثوقة في خطط الاشتراك:إستراتيجية تغيير الخطة
- اختبر بدقة: دائما اختبر تغييرات الخطة في وضع الاختبار قبل الإنتاج
- اختر النسبة بعناية: حدد نمط النسبة الذي يتماشى مع نموذج عملك
- تعامل مع الفشل برشاقة: نفذ معالجة الأخطاء المناسبة ومنطق المحاولة مرة أخرى
- راقب معدلات النجاح: تتبع معدلات نجاح/فشل تغيير الخطة وتحقيق في المشاكل
تنفيذ Webhook
- تحقق من التوقيعات: تحقق دائماً من توقيعات webhook لضمان الأصالة
- نفذ التفرد: تعامل بلطف مع أحداث webhook المكررة
- معالجة غير متزامنة: لا تعيقة استجابات webhook بعمليات ثقيلة
- سجل كل شيء: حافظ على سجلات مفصلة لأغراض التصحيح والتدقيق
تجربة المستخدم
- تواصل بوضوح: أعلم العملاء بتغييرات الفوترة والوقت
- قدّم التأكيدات: أرسل تأكيدات بريد إلكتروني لتغييرات الخطة الناجحة
- تعامل مع الحالات الحدية: استخدم فترات التجربة، النسب، والمدفوعات الفاشلة
- حدّث الواجهة فوراً: عكس تغييرات الخطة في واجهة تطبيقك
مشكلات شائعة وحلول
حل المشكلات الشائعة التي تواجهها أثناء تغييرات خطط الاشتراك:Charge created but subscription not updated
Charge created but subscription not updated
- فشل أو تأخرت معالجة webhook
- لم يتم تحديث حالة التطبيق بعد تلقي webhooks
- مشاكل في معاملات قاعدة البيانات أثناء تحديث الحالة
- تنفيذ معالجة webhook قوية مع منطق المحاولة مرة أخرى
- استخدام عمليات متكررة لتحديث الحالة
- إضافة رصد للكشف عن أحداث webhook المفقودة وتنبيهها
- تأكد من أن نقطة نهاية webhook قابلة للوصول وتستجيب بشكل صحيح
Credits not applied after downgrade
Credits not applied after downgrade
- توقعات نمط النسبة: التخفيضات ترصد الفرق الكامل في سعر الخطة مع
difference_immediately، بينما قالبprorated_immediatelyيُنشئ رصيداً نسبياً بناءً على الوقت المتبقي في الدورة - الأرصدة مخصصة للاشتراك ولا تنتقل بين الاشتراكات
- رصيد الحساب غير مرئي في لوحة تحكم العميل
- استخدم
difference_immediatelyللتخفيضات عندما تريد الأرصدة التلقائية - اشرح للعملاء أن الأرصدة تنطبق على التجديدات المستقبلية لنفس الاشتراك
- تنفيذ بوابة عملاء لعرض أرصدة الحسابات
- تحقق من معاينة الفاتورة التالية لرؤية الأرصدة المطبقة
Webhook signature verification fails
Webhook signature verification fails
- مفتاح سري غير صحيح لل webhook
- تم تعديل جسم الطلب الخام قبل التحقق من التوقيع
- خوارزمية تحقق التوقيع غير صحيحة
- تأكد أنك تستخدم
DODO_WEBHOOK_SECRETالصحيح من لوحة التحكم - اقرأ جسم الطلب الخام قبل أي وسيط JSON parsing
- استخدم مكتبة التحقق القياسية لل webhook لمنصتك
- اختبر التحقق من توقيع webhook في بيئة التطوير
Plan change fails with 422 error
Plan change fails with 422 error
- معرف اشتراك غير صالح أو معرف منتج
- الاشتراك ليس في حالة نشطة
- المعلمات المطلوبة مفقودة
- المنتج غير متاح لتغييرات الخطة
- تحقق من وجود الاشتراك وأنه نشط
- تحقق من أن معرف المنتج صالح ومتاح
- تأكد من تقديم جميع المعلمات المطلوبة
- راجع وثائق API لمتطلبات المعاملات
Immediate charge fails during plan change
Immediate charge fails during plan change
- أموال غير كافية على طريقة دفع العميل
- طريقة الدفع منتهية أو غير صالحة
- البنك رفض المعاملة
- كشف عن احتيال أوقف الشحن
- تعامل مع أحداث
payment.failedبشكل مناسب - قم بإخطار العميل لتحديث طريقة الدفع
- تنفيذ منطق المحاولة مرة أخرى للفشل المؤقت
- ضع في اعتبارك السماح بتغييرات الخطة مع الشحنات الفورية الفاشلة
Subscription on hold after plan change
Subscription on hold after plan change
on_holdماذا يحدث:
عند فشل شحن تغيير الخطة، يتحول الاشتراك تلقائياً إلى حالة on_hold. لن يتم تجديد الاشتراك تلقائياً حتى يتم تحديث طريقة الدفع.الحل: تحديث طريقة الدفع لإعادة تفعيل الاشتراكلإعادة تفعيل الاشتراك من حالة on_hold بعد فشل تغيير الخطة:- تحديث طريقة الدفع باستخدام API تحديث طريقة الدفع
- إنشاء شحن تلقائي: يقوم ال API تلقائياً بإنشاء شحن للمستحقات المتبقية
- توليد الفاتورة: يتم توليد فاتورة للشحن
- معالجة الدفع: يعالج الدفع باستخدام طريقة الدفع الجديدة
- إعادة التفعيل: عند النجاح في الدفع، يعاد تفعيل الاشتراك إلى الحالة
active
subscription.on_hold: تم وضع الاشتراك مؤقتاً (يُتلقى عند فشل شحن تغيير الخطة)payment.succeeded: نجاح الدفع للمستحقات المتبقية (بعد تحديث طريقة الدفع)subscription.active: إعادة تفعيل الاشتراك بعد الدفع الناجح
- قم بإخطار العملاء فوراً عند فشل شحن تغيير الخطة
- تقديم تعليمات واضحة حول كيفية تحديث طريقة الدفع
- راقب أحداث webhook لمتابعة حالة إعادة التفعيل
- ضع في اعتبارك تنفيذ منطق المحاولة التلقائية لفشل الدفع المؤقت
Update Payment Method API Reference
اختبار تنفيذك
اتبع هذه الخطوات لاختبار تنفيذ تغيير خطة الاشتراك الخاص بك بدقة:Set up test environment
- استخدم مفاتيح API التجريبية والمنتجات التجريبية
- إنشئ اشتراكات تجريبية بأنواع خطط مختلفة
- قم بتكوين نقطة نهاية webhook التجريبية
- إعداد المراقبة وتسجيل البيانات
Test different proration modes
- اختبار
prorated_immediatelyمع مواضع مختلفة لدورة الفوترة - اختبار
difference_immediatelyللترقيات والتخفيضات - اختبار
full_immediatelyلإعادة ضبط دورات الفوترة - التحقق من صحة حسابات الرصيد
Test webhook handling
- تحقق من استلام جميع أحداث webhook ذات الصلة
- اختبار تحقق توقيع webhook
- تعامل برفق مع أحداث webhook المكررة
- اختبار سيناريوهات فشل معالجة webhook
Test error scenarios
- اختبار باستخدام معرفات اشتراك غير صالحة
- اختبار بطرق دفع منتهية
- اختبار إخفاقات الشبكة والانقطاعات الزمنية
- اختبار بأموال غير كافية
معالجة الأخطاء
تعامل مع أخطاء API الشائعة برشاقة في تنفيذك:رموز حالة HTTP
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
تنسيق الاستجابة عن الخطأ
الخطوات التالية
- مراجعة Change Plan API
- استكشاف الفوترة القائمة على الائتمان
- تنفيذ التنبيهات لـ
subscription.on_hold - اطلع على دليل دمج Webhook