Skip to main content

Change Plan API

Full API docs for updating subscriptions.

Plan Change Preview

See charge amounts before changing plans.

Integration Guide

Step-by-step subscription setup.

What Is a Subscription Upgrade or Downgrade?

Change a customer’s subscription plan to move them between tiers, adjust quantity for seat-based products, or migrate to a new product. The API automatically calculates prorations and charges based on your chosen billing mode.
Plan changes can trigger an immediate charge depending on the proration mode you choose.

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
For detailed setup instructions, see the Integration Guide.

Step-by-Step Implementation Guide

Follow this comprehensive guide to implement subscription plan changes in your application:
1

Understand Plan Change Requirements

Before implementing, determine:
  • 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
Test plan changes thoroughly in test mode before implementing in production.
2

Choose Your Proration Strategy

Select the billing approach that aligns with your business needs:
Best for: SaaS applications that want to credit unused time on the old plan.
  • Credits the unused portion of the current cycle, prorated by time remaining
  • Then charges a full cycle at the new plan — the new plan price is never prorated
  • Net charge = full new cycle − (remaining fraction × full old cycle)
3

Implement the Change Plan API

Use the Change Plan API to modify subscription details:
string
مطلوب
The ID of the active subscription to modify.
string
مطلوب
معرّف المنتج الجديد الذي سيتم تغيير الاشتراك إليه.
integer
مطلوب
عدد الوحدات للخطة الجديدة (للمنتجات القائمة على المقاعد).
string
مطلوب
كيفية التعامل مع الفوترة الفورية: prorated_immediately أو full_immediately أو difference_immediately أو do_not_bill.
array
الإضافات الاختيارية للخطة الجديدة. يؤدي حذف هذا الحقل أو إرسال null أو إرسال مصفوفة فارغة إلى إزالة أي إضافات موجودة، لذا يجب تضمين الإضافات الحالية للاحتفاظ بها.
string
يتحكم في السلوك عند فشل دفعة تغيير الخطة:
  • prevent_change: إبقاء الاشتراك على الخطة الحالية حتى نجاح الدفع
  • apply_change (الافتراضي): تطبيق تغيير الخطة فورًا بصرف النظر عن نتيجة الدفع
If not specified, uses the business-level default setting.
تحصيل مبلغ تغيير الخطة عبر رابط دفع بدلًا من خصم المبلغ من طريقة الدفع المحفوظة للاشتراك. يدفع العميل في صفحة دفع مستضافة.Requires the business’s allow_plan_change_via_payment_link capability (Settings → Subscriptions → Collect Plan Change Payments by Payment Link), effective_at: immediately, and on_payment_failure: prevent_change. See Collecting Payment via a Checkout Link. Ignored by the preview route.
string
عنوان URL الذي يستقبل العميل بعد دفع رابط الدفع. يضيف إعادة التوجيه subscription_id وpayment_id وstatus. يتطلب collect_via_payment_link: true؛ وإلا يفشل الطلب مع 422. راجع إعادة توجيه العميل بعد الدفع.
إلغاء رابط الدفع غير المدفوع الخاص بتغيير خطة معلّق، بحيث يحل هذا الطلب محله. تُرجع الدفعة المدفوعة أو الجارية 409. راجع استبدال رابط دفع معلّق. يتجاهل مسار المعاينة هذا الحقل.
array
رموز خصم متسلسلة اختيارية لتطبيقها على الخطة الجديدة (بحد أقصى 20، وتُطبّق بترتيب المصفوفة). يعتمد السلوك على القيمة التي تمررها:
  • غير مقدمة / null — يتم الاحتفاظ بالخصومات الحالية التي تحتوي على preserve_on_plan_change=true إذا كانت تنطبق على المنتج الجديد.
  • [] (مصفوفة فارغة) — إزالة جميع الخصومات الحالية من الاشتراك.
  • ["CODE_A", "CODE_B", ...] — استبدال أي خصومات حالية بهذه المجموعة المتسلسلة.
string
مهمل
مهمل — يُفضّل استخدام discount_codes للتكاملات الجديدة. يظل هذا الحقل يعمل للتوافق مع الإصدارات السابقة، لكن لا يمكن دمجه مع discount_codes في الطلب نفسه.
string
افتراضي:"immediately"
متى يتم تطبيق تغيير الخطة:
  • immediately (الافتراضي): تطبيق تغيير الخطة فورًا
  • next_billing_date: جدولة التغيير لموعد الفوترة التالي. يحتفظ العميل بخطته الحالية حتى انتهاء فترة الفوترة. استخدم هذا الخيار للتخفيضات كي يحتفظ العملاء بمزايا خطتهم الحالية حتى نهاية فترة الفوترة.
4

Handle Webhook Events

أعد إعداد معالجة webhook لتتبع نتائج تغيير الخطة:
  • subscription.active: نجاح تغيير الخطة وتحديث الاشتراك
  • subscription.plan_changed: تغيير خطة الاشتراك (ترقية/تخفيض/تحديث الإضافة)
  • subscription.on_hold: فشل تحصيل مبلغ تغيير الخطة وإيقاف التجديدات
  • payment.succeeded: نجاح التحصيل الفوري لتغيير الخطة
  • payment.failed: فشل التحصيل الفوري
تحقق دائمًا من توقيعات webhook وطبّق معالجة idempotent للأحداث.
5

Update Your Application State

حدّث تطبيقك استنادًا إلى أحداث webhook:
  • منح الميزات أو سحبها بناءً على الخطة الجديدة
  • تحديث لوحة تحكم العميل بتفاصيل الخطة الجديدة
  • إرسال رسائل بريد إلكتروني لتأكيد تغييرات الخطة
  • تسجيل تغييرات الفوترة لأغراض التدقيق
6

Test and Monitor

اختبر تطبيقك بدقة:
  • اختبر جميع أوضاع proration في سيناريوهات مختلفة
  • تحقق من عمل معالجة webhook بصورة صحيحة
  • راقب معدلات نجاح تغيير الخطة
  • أعد إعداد تنبيهات لتغييرات الخطة الفاشلة
أصبح تطبيق تغيير خطة الاشتراك جاهزًا للاستخدام في بيئة الإنتاج.

معاينة تغييرات الخطة

قبل اعتماد تغيير الخطة، استخدم Preview API لعرض المبلغ الذي سيُحصّل من العملاء بدقة:
استخدم Preview API لإنشاء مربعات حوار للتأكيد تعرض للعملاء المبلغ الدقيق الذي سيُحصّل منهم قبل تأكيد تغيير الخطة.
في immediate_charge.summary، يمثل customer_credits صافي التغيير في رصيد ائتمان العميل، بعملة customer_credits_currency. وهذه هي عملة محفظة ائتمان العميل، وهي عملة الاشتراك. وقد تختلف عن currency في الملخص، الذي ينطبق على total_amount وtax. على سبيل المثال، يرى العميل الذي يدفع بالروبية الهندية مقابل اشتراك بالدولار أرصدة ائتمانية بالدولار.

Change Plan API

استخدم Change Plan API لتعديل المنتج والكمية وسلوك proration لاشتراك نشط.

أمثلة البدء السريع

يُرجع تغيير الخطة الناجح 200 OK فورًا — قبل تسوية أي مبلغ فعليًا. ويعتمد محتوى الجسم (ChangePlanResponse) على طريقة تحصيل التغيير:
يؤكد هذا الرد قبول الطلب، وليس نجاح التحصيل. في حالة التحصيل الفوري العادي، تُحسم النتيجة خارج الجلسة مباشرة بعد الاستدعاء. أما في طلب collect_via_payment_link، فيبقى الاشتراك على خطته الحالية حتى يكمل العميل الدفع.أكد النتيجة عبر webhook (payment.succeeded وpayment.failed وsubscription.plan_changed)، أو أعد قراءة الاشتراك باستخدام GET /subscriptions/{subscription_id} — راجع ما يحدث أثناء عدم دفع الرابط لحالة رابط الدفع.
إذا فشل التحصيل الفوري، فقد ينتقل الاشتراك إلى subscription.on_hold حتى نجاح الدفع.

تحصيل الدفع عبر رابط Checkout

افتراضيًا، يخصم تغيير الخطة الفوري المبلغ مباشرةً من طريقة الدفع المحفوظة للاشتراك. اضبط collect_via_payment_link: true لإرسال العميل إلى صفحة checkout مستضافة بدلًا من ذلك — وهذا مفيد عند عدم وجود طريقة دفع محفوظة أو عند رغبتك في أن يؤكد العميل السعر الجديد بنفسه.
يشغّل هذا الخيار مفتاح تحصيل دفعات تغيير الخطة عبر رابط الدفع في الإعدادات ← الاشتراكات، الذي يوجّه مسار تغيير الخطة في Customer Portal عبر checkout.

المتطلبات

ينجح collect_via_payment_link: true فقط عند تحقق جميع الشروط التالية — وإلا يفشل الطلب مع 422:
  • يجب تفعيل قدرة allow_plan_change_via_payment_link للنشاط التجاري (الإعدادات ← الاشتراكات ← تحصيل دفعات تغيير الخطة عبر رابط الدفع).
  • يجب أن تكون effective_at هي immediately (الافتراضية). لا يحتاج التغيير المجدول (next_billing_date) إلى صفحة checkout.
  • يجب أن يعيّن الطلب on_payment_failure: prevent_change. ويفشل apply_change الصريح مع 422.
ينطبق collect_via_payment_link على أي تغيير فوري ينتج عنه تحصيل، بما في ذلك التخفيضات، ما دامت المتطلبات أعلاه مستوفاة.
إذا كان صافي التغيير صفراً أو رصيداً دائناً، فلن يُصدر رابط دفع: يصبح payment_link وتعود حقول checkout الأخرى null، ويُطبّق التغيير فورًا. هذا ليس 422. استدعِ Preview Plan Change أولًا للتحقق من المبلغ قبل طلب رابط.
يُرجع الطلب الناجح معرّفات checkout:

ما يحدث أثناء عدم دفع الرابط

  • يبقى الاشتراك على خطته الحالية — ولا يتغير product_id أو recurring_pre_tax_amount أو next_billing_date حتى دفع الرابط.
  • يُرفض أي طلب change-plan إضافي مع 409 PendingPlanChangeExists أثناء تعليق الرابط. لاستبدال التغيير المعلّق، أرسل الطلب الجديد مع cancel_older_payment_link: true. راجع استبدال رابط دفع معلّق.
  • لإعادة المحاولة بعد رفض الدفع، استدعِ change-plan مجددًا للحصول على رابط جديد.
  • إذا لم يُدفع الرابط مطلقًا، فسيتوقف عن العمل بعد expires_on — ويصبح الاشتراك متاحًا تلقائيًا لقبول طلب تغيير خطة جديد بعد ذلك بوقت قصير.
  • إذا كان هناك تغيير مجدول مسبقًا واستبدلته بـ cancel_scheduled_change_plan: true، يظل الجدول الأصلي قائمًا أثناء عدم دفع الرابط ولا يُلغى إلا بعد دفع الرابط — في المعاملة نفسها التي تطبّق الخطة الجديدة.
بعد إصدار تغيير فوري عبر رابط دفع، يُحظر كل طلب تغيير خطة لاحق على ذلك الاشتراك — بما في ذلك المعاينة الخالية من الآثار الجانبية — حتى تُحسم حالة الرابط. ويمكن لطلب change-plan استبدال الرابط بتعيين cancel_older_payment_link: true. وتتجاهل المعاينة هذا الحقل، لذلك تظل المعاينة محظورة.

إعادة توجيه العميل بعد الدفع

اضبط return_url لإعادة العميل إلى موقعك بعد دفع الرابط:
بعد checkout، ينتقل العميل إلى return_url باستخدام معلمات query التالية: عند فشل الدفع، يظل الاشتراك نشطًا على خطته الحالية. وقد تُطبّق الخطة الجديدة بعد إعادة التوجيه بقليل، عند وصول webhook الدفع، لذا أعد قراءة الاشتراك قبل عرض الخطة الجديدة. يتطلب return_url وجود collect_via_payment_link: true. وبدونه يفشل الطلب مع 422.

استبدال رابط دفع معلّق

إذا غادر العميل checkout دون الدفع، فعيّن cancel_older_payment_link: true في طلب change-plan التالي. تلغي Dodo Payments الرابط غير المدفوع، ويستبدل تغيير الخطة الجديد التغيير المعلّق. ولا يقبل الرابط الملغى أي دفعة، حتى من صفحة checkout مفتوحة مسبقًا.
يُتحقق من صحة الطلب قبل إلغاء الرابط، لذلك يحافظ الطلب غير الصالح على رابط العميل. ولا يُلغى الرابط إلا إذا لم يبدأ العميل الدفع: يُصدر كل طلب change-plan فاتورة خاصة به. ويُلغى تغيير الخطة المستبدل وفاتورته. وإذا لم يكن هناك تغيير خطة معلّق، فلن يكون لـ cancel_older_payment_link أي تأثير.
قد يفشل فحص يُجرى بعد التحقق، مثل الحد الأدنى لمبلغ التحصيل، بعد إلغاء الرابط. عندئذ يبقى الاشتراك على خطته الحالية دون رابط مفتوح. أرسل الطلب مجددًا لإصدار رابط جديد.

إدارة Addons

عند تغيير خطط الاشتراك، يمكنك أيضًا تعديل الإضافات:
تُدرج الإضافات في حساب proration وتُحصّل وفق وضع proration المحدد.

تطبيق رموز الخصم

طبّق رمز خصم متسلسلًا واحدًا أو أكثر عند تغيير خطط الاشتراك (بحد أقصى 20، وتُطبّق بترتيب المصفوفة):

سلوك الخصم عند تغيير الخطة

حقل discount_code المفرد في نقطة النهاية هذه مهمل لكنه لا يزال يعمل للتوافق مع الإصدارات السابقة — ولا تحتاج التكاملات الحالية إلى التغيير فورًا. ولا يمكن دمجه مع discount_codes في الطلب نفسه. انقل التكامل إلى صيغة المصفوفة عندما يناسبك.
استخدم Preview Plan Change API مع discount_codes لعرض المبلغ الذي سيوفره العملاء بدقة قبل تأكيد تغيير الخطة.

أوضاع Proration

اختر كيفية فوترة العميل عند تغيير الخطط:

prorated_immediately

  • إضافة رصيد للجزء غير المستخدم من الدورة الحالية — الخطة الأساسية والكمية والإضافات — محسوبًا تناسبيًا وفق الوقت المتبقي
  • ثم تحصيل دورة كاملة بالخطة والكمية والإضافات الجديدة. ولا يُحسب مبلغ التحصيل نفسه تناسبيًا
  • صافي التحصيل الفوري = (الدورة الجديدة الكاملة) − (الكسر المتبقي × الدورة القديمة الكاملة)
  • إذا تجاوز الرصيد مبلغ الدورة الجديدة (وهو شائع في التخفيضات)، يُحتفظ بالفرق كرصيد خاص بالاشتراك للتجديدات المستقبلية
  • أثناء الفترة التجريبية، يتم التحصيل فورًا والتبديل إلى الخطة الجديدة الآن

full_immediately

  • تحصيل المبلغ الكامل للخطة الجديدة فورًا
  • تجاهل الوقت المتبقي من الخطة القديمة — لا يوجد رصيد للدورة الحالية
الأرصدة التي ينشئها prorated_immediately وتلك الناتجة عن التخفيضات باستخدام difference_immediately تكون خاصة بالاشتراك، وهي منفصلة عن استحقاقات Credit-Based Billing. وتُطبّق تلقائيًا على التجديدات المستقبلية للاشتراك نفسه، ولا يمكن نقلها بين الاشتراكات.

difference_immediately

  • الترقية: تحصيل فرق السعر بين الخطتين القديمة والجديدة فورًا
  • التخفيض: إضافة القيمة المتبقية كرصيد داخلي إلى الاشتراك وتطبيقها تلقائيًا عند التجديد

do_not_bill

  • لا تُحسب أي تحصيلات أو أرصدة
  • ينتقل العميل إلى الخطة الجديدة فورًا دون تعديل في الفوترة
  • تبقى دورة الفوترة دون تغيير
  • مناسب لعمليات النقل المجانية أو المجاملة أو استيعاب فروق التكلفة

أمثلة على السيناريوهات

استخدم هذه الأرقام الأساسية باستمرار:
  • الخطة الحالية: Basic بسعر $30/شهر
  • هدف الترقية: Pro بسعر $80/شهر
  • هدف التخفيض (من Pro): Starter بسعر $20/شهر
  • دورة الفوترة: 30 يومًا، بدأت في 1 يناير
  • يحدث تغيير الخطة في 16 يناير (15 يومًا متبقية، و15 يومًا مستخدمة)

كيفية معالجة كل وضع للفوترة

اختر prorated_immediately لإضافة رصيد للوقت غير المستخدم في الخطة القديمة مع تحصيل دورة كاملة من الخطة الجديدة؛ واختر full_immediately لإعادة بدء الفوترة؛ واستخدم difference_immediately للترقيات البسيطة وإضافة رصيد تلقائية عند التخفيضات؛ أو استخدم do_not_bill لتبديل الخطط دون أي تعديل في الفوترة.

معالجة حالات فشل الدفع

تحكم في ما يحدث عند فشل دفعة تغيير الخطة باستخدام المعلمة on_payment_failure.

أوضاع فشل الدفع

إذا لم تُحدّد، تستخدم المعلمة on_payment_failure إعدادك الافتراضي على مستوى النشاط التجاري والمكوّن في لوحة التحكم.

متى تستخدم كل وضع

الإعدادات الافتراضية للنشاط التجاري والتحصيل

عيّن سلوك الترقية والتخفيض الافتراضي على مستوى النشاط التجاري ضمن الإعدادات ← الاشتراكات. وتنطبق هذه الإعدادات الافتراضية على جميع تغييرات الخطة في بوابة العملاء، ويمكن تجاوزها لكل مجموعة منتجات. توجد إعدادات افتراضية منفصلة للترقيات والتخفيضات: اضبط الإعدادات الافتراضية للنشاط التجاري ضمن الإعدادات ← الاشتراكات، وتجاوزات المجموعات في كل مجموعة منتجات. كل حقل في المجموعة مستقل — اتركه دون تعيين ليرث الإعداد الافتراضي للنشاط التجاري، أو عيّن قيمة لتجاوز ذلك الإعداد.

ترتيب تحديد القيمة

بالنسبة إلى أي تغيير خطة، تُحدّد قيمة كل إعداد بالترتيب التالي:
تتغلب القيمة الممررة صراحةً إلى Change Plan API دائمًا على غيرها. ولا تصبح الإعدادات الافتراضية للنشاط التجاري والمجموعة فعالة إلا عند عدم توفير قيمة صريحة — وهذا هو الحال لجميع تغييرات الخطة التي تبدأ من بوابة العملاء.
إعداد شائع: أبقِ الترقيات على immediately + difference_immediately كي يدفع العملاء الفرق ويحصلوا على الوصول فورًا، وأبقِ التخفيضات على next_billing_date كي يحتفظ العملاء بخطتهم الحالية حتى انتهاء الدورة.

معالجة Webhooks

تتبّع حالة الاشتراك عبر webhooks لتأكيد تغييرات الخطة والمدفوعات.

أنواع الأحداث التي يجب معالجتها

  • subscription.active: تفعيل الاشتراك
  • subscription.plan_changed: تغيير خطة الاشتراك (ترقية/تخفيض/تغييرات الإضافات)
  • subscription.on_hold: فشل التحصيل وإيقاف التجديدات
  • subscription.renewed: نجاح التجديد
  • payment.succeeded: نجاح الدفع الخاص بتغيير الخطة أو التجديد
  • payment.failed: فشل الدفع
أنشئ منطق الأعمال استنادًا إلى أحداث الاشتراك، واستخدم أحداث الدفع للتأكيد والمطابقة.

التحقق من التوقيعات ومعالجة النوايا

للاطلاع على مخططات payload التفصيلية، راجع payloads الخاصة بـ Subscription webhook وpayloads الخاصة بـ Payment webhook.

أفضل الممارسات

استراتيجية تغيير الخطة

  • اختبر بدقة: اختبر دائمًا تغييرات الخطة في وضع الاختبار قبل الإنتاج
  • اختر proration بعناية: حدّد وضع proration المتوافق مع نموذج نشاطك التجاري
  • تعامل مع حالات الفشل بسلاسة: طبّق معالجة مناسبة للأخطاء ومنطقًا لإعادة المحاولة
  • راقب معدلات النجاح: تتبّع معدلات نجاح وفشل تغيير الخطة وحقق في المشكلات

تطبيق Webhook

  • تحقق من التوقيعات: تحقق دائمًا من توقيعات webhook لضمان الأصالة
  • طبّق idempotency: عالج أحداث webhook المكررة بسلاسة
  • عالج الأحداث بشكل غير متزامن: لا تحظر استجابات webhook بعمليات ثقيلة
  • سجّل كل شيء: احتفظ بسجلات مفصلة لتصحيح الأخطاء وأغراض التدقيق

تجربة المستخدم

  • تواصل بوضوح: أبلغ العملاء بتغييرات الفوترة وتوقيتها
  • وفّر التأكيدات: أرسل رسائل بريد إلكتروني لتأكيد تغييرات الخطة الناجحة
  • تعامل مع الحالات الحدّية: ضع الفترات التجريبية وproration والمدفوعات الفاشلة في الاعتبار
  • حدّث الواجهة فورًا: اعكس تغييرات الخطة في واجهة تطبيقك

المشكلات الشائعة والحلول

حل المشكلات المعتادة التي تحدث أثناء تغييرات خطة الاشتراك:
الأعراض: ينجح استدعاء API لكن يظل الاشتراك على الخطة القديمةالأسباب الشائعة:
  • فشلت معالجة webhook أو تأخرت
  • لم تُحدّث حالة التطبيق بعد استلام webhooks
  • مشكلات في معاملة قاعدة البيانات أثناء تحديث الحالة
الحلول:
  • طبّق معالجة webhook مع منطق لإعادة المحاولة
  • استخدم عمليات idempotent لتحديث الحالة
  • أضف المراقبة لاكتشاف أحداث webhook الفائتة والتنبيه إليها
  • تحقق من إمكانية الوصول إلى نقطة نهاية webhook واستجابتها بصورة صحيحة
الأعراض: يخفض العميل خطته لكنه لا يرى رصيدًا ائتمانيًاالأسباب الشائعة:
  • توقعات وضع proration: تمنح التخفيضات رصيد فرق سعر الخطة الكامل باستخدام difference_immediately، بينما يمنح prorated_immediately رصيد الوقت غير المستخدم في الدورة القديمة ثم يحصّل دورة كاملة بالخطة الجديدة — لذلك لا يبقى رصيد إلا عندما يتجاوز ذلك الرصيد سعر الخطة الجديدة
  • الأرصدة خاصة بالاشتراك ولا تنتقل بين الاشتراكات
  • رصيد الائتمان غير ظاهر في لوحة تحكم العميل
الحلول:
  • استخدم difference_immediately للتخفيضات عندما تريد أرصدة تلقائية
  • وضّح للعملاء أن الأرصدة تُطبّق على التجديدات المستقبلية للاشتراك نفسه
  • طبّق Customer Portal لعرض الأرصدة الائتمانية
  • تحقق من معاينة الفاتورة التالية لرؤية الأرصدة المطبّقة
الأعراض: رُفضت أحداث webhook بسبب توقيع غير صالحالأسباب الشائعة:
  • مفتاح webhook السري غير صحيح
  • تعديل جسم الطلب الخام قبل التحقق من التوقيع
  • خوارزمية تحقق من التوقيع غير صحيحة
الحلول:
  • تحقق من استخدام DODO_PAYMENTS_WEBHOOK_KEY الصحيح من لوحة التحكم
  • اقرأ جسم الطلب الخام قبل أي middleware لتحليل JSON
  • استخدم مكتبة التحقق القياسية من webhook لمنصتك
  • اختبر التحقق من توقيع webhook في بيئة التطوير
الأعراض: تُرجع API خطأ 422 Unprocessable Entityالأسباب الشائعة:
  • معرّف اشتراك أو منتج غير صالح
  • الاشتراك ليس في حالة نشطة
  • معلمات مطلوبة مفقودة
  • المنتج غير متاح لتغييرات الخطة
الحلول:
  • تحقق من وجود الاشتراك وكونه نشطًا
  • تحقق من صلاحية معرّف المنتج وتوفره
  • تأكد من توفير جميع المعلمات المطلوبة
  • راجع وثائق API لمعرفة متطلبات المعلمات
الأعراض: بدأ تغيير الخطة لكن فشل التحصيل الفوريالأسباب الشائعة:
  • عدم كفاية الأموال في طريقة دفع العميل
  • انتهاء صلاحية طريقة الدفع أو عدم صلاحيتها
  • رفض البنك للمعاملة
  • حظر التحصيل بواسطة اكتشاف الاحتيال
الحلول:
  • عالج أحداث webhook الخاصة بـ payment.failed بصورة مناسبة
  • أبلغ العميل بتحديث طريقة الدفع
  • طبّق منطق إعادة المحاولة لحالات الفشل المؤقتة
  • فكّر في السماح بتغييرات الخطة مع فشل التحصيلات الفورية
الأعراض: فشلت دفعة تغيير الخطة وانتقل الاشتراك إلى حالة on_holdما يحدث: عند فشل تحصيل تغيير الخطة، يُوضَع الاشتراك تلقائيًا في حالة on_hold. ولن يُجدّد الاشتراك تلقائيًا حتى تُحدّث طريقة الدفع.الحل: حدّث طريقة الدفع لإعادة تفعيل الاشتراكلإعادة تفعيل اشتراك من حالة on_hold بعد فشل تغيير الخطة:
  1. حدّث طريقة الدفع باستخدام Update Payment Method API
  2. إنشاء التحصيل تلقائيًا: تنشئ API تحصيلًا تلقائيًا للمبالغ المستحقة المتبقية
  3. إنشاء الفاتورة: تُنشأ فاتورة للتحصيل
  4. معالجة الدفع: تُعالج الدفعة باستخدام طريقة الدفع الجديدة
  5. إعادة التفعيل: عند نجاح الدفع، يُعاد تفعيل الاشتراك إلى حالة active
أحداث webhook التي يجب مراقبتها:
  • subscription.on_hold: وضع الاشتراك قيد التعليق (يُستلم عند فشل تحصيل تغيير الخطة)
  • payment.succeeded: نجاح دفع المبالغ المستحقة المتبقية (بعد تحديث طريقة الدفع)
  • subscription.active: إعادة تفعيل الاشتراك بعد نجاح الدفع
أفضل الممارسات:
  • أبلغ العملاء فورًا عند فشل تحصيل تغيير الخطة
  • وفّر تعليمات واضحة حول كيفية تحديث طريقة الدفع
  • راقب أحداث webhook لتتبع حالة إعادة التفعيل
  • فكّر في تطبيق منطق إعادة المحاولة التلقائية لفشل الدفع المؤقت

Update Payment Method API Reference

اطّلع على وثائق API الكاملة لتحديث طرق الدفع وإعادة تفعيل الاشتراكات.

اختبار تطبيقك

اختبر تطبيق تغيير خطة الاشتراك بدقة:
1

Set up test environment

  • استخدم مفاتيح API ومنتجات الاختبار
  • أنشئ اشتراكات اختبار بأنواع خطط مختلفة
  • اضبط نقطة نهاية webhook للاختبار
  • أعد إعداد المراقبة والتسجيل
2

Test different proration modes

  • اختبر prorated_immediately مع مواضع مختلفة في دورة الفوترة
  • اختبر difference_immediately للترقيات والتخفيضات
  • اختبر full_immediately لإعادة ضبط دورات الفوترة
  • اختبر do_not_bill لتبديلات الخطط دون تحصيل أو رصيد
  • تحقق من صحة حسابات الأرصدة
3

Test webhook handling

  • تحقق من استلام جميع أحداث webhook ذات الصلة
  • اختبر التحقق من توقيع webhook
  • عالج أحداث webhook المكررة بسلاسة
  • اختبر سيناريوهات فشل معالجة webhook
4

Test error scenarios

  • اختبر باستخدام معرّفات اشتراك غير صالحة
  • اختبر باستخدام طرق دفع منتهية الصلاحية
  • اختبر حالات فشل الشبكة وانتهاء المهلة
  • اختبر باستخدام أموال غير كافية
5

Monitor in production

  • أعد إعداد تنبيهات لتغييرات الخطة الفاشلة
  • راقب أوقات معالجة webhook
  • تتبّع معدلات نجاح تغيير الخطة
  • راجع تذاكر دعم العملاء بحثًا عن مشكلات تغيير الخطة

معالجة الأخطاء

عالج أخطاء API الشائعة بسلاسة في تطبيقك:

رموز حالة HTTP

تمت معالجة طلب تغيير الخطة بنجاح. جسم الاستجابة هو ChangePlanResponse مع payment_id وpayment_link وclient_secret وexpires_on. وجميعها الأربعة قابلة لأن تكون null، لذلك يُسلسل الجسم كـ {} في حالة التغيير العادي خارج الجلسة؛ وتُملأ عند نجاح طلب collect_via_payment_link، الذي يُرجع معرّفات checkout — راجع تحصيل الدفع عبر رابط Checkout. وإذا كان on_payment_failure=prevent_change، يظل تغيير الخطة معلّقًا حتى نجاح الدفع.
معلمات الطلب غير صالحة. تحقق من توفير جميع الحقول المطلوبة وتنسيقها بصورة صحيحة.
مفتاح API غير صالح أو مفقود. تحقق من صحة DODO_PAYMENTS_API_KEY وامتلاكه الأذونات المناسبة.
يوجد تغيير خطة معلّق بالفعل لهذا الاشتراك (PendingPlanChangeExists). بالنسبة إلى تغيير مجدول، ألغِه باستخدام DELETE /subscriptions/{subscription_id}/change-plan/scheduled قبل إرسال تغيير جديد. وبالنسبة إلى تغيير عبر رابط دفع معلّق، أرسل الطلب الجديد مع cancel_older_payment_link: true لاستبداله. راجع استبدال رابط دفع معلّق.عند استخدام cancel_older_payment_link: true، يعني 409 أن العميل يدفع الرابط السابق الآن (PLAN_CHANGE_PAYMENT_IN_PROGRESS) أو دفعه بالفعل (PLAN_CHANGE_PAYMENT_ALREADY_COMPLETED).
عند استخدام cancel_older_payment_link: true، تعذر إلغاء رابط الدفع السابق (PLAN_CHANGE_LINK_CANCEL_FAILED). لم يتغير شيء، ويمكنك إعادة محاولة الطلب.
الاشتراك غير نشط أو عند الطلب، أو أن الطلب غير مؤهل لـ collect_via_payment_link — إذ لم يفعّل النشاط التجاري القدرة، أو أن effective_at ليست immediately، أو أن on_payment_failure ليست prevent_change. راجع المتطلبات. ويُرجع معرّف الاشتراك غير الموجود أو غير التابع لحسابك 404 مع رمز NOT_FOUND.
حدث خطأ في الخادم. أعد محاولة الطلب بعد تأخير قصير.

تنسيق استجابة الخطأ

تُرجع الأخطاء جسم JSON يحتوي على code وmessage قابل للقراءة البشرية:
راجع رموز الخطأ للاطلاع على القائمة الكاملة.

الخطوات التالية

آخر تعديل في ٨ أكتوبر ٢٠٢٦