المتطلبات الأساسية
قبل البدء، تحتاج إلى:- حساب تاجر على Dodo Payments
- مفتاح API من Developer → API Keys في لوحة التحكم، محفوظ في
DODO_PAYMENTS_API_KEY - سر webhook من Developer → Webhooks، محفوظ في
DODO_PAYMENTS_WEBHOOK_KEY - منتج اشتراك واحد على الأقل تم إنشاؤه ضمن Products
تكامل API
جلسات الدفع
أنشئ اشتراكًا من خلال إنشاء جلسة دفع باستخدام منتج الاشتراك. يفوّض العميل طريقة دفع، ويتم تفعيل الاشتراك عند إكمال عملية الدفع.- Node.js SDK
- Python SDK
- REST API
استجابة API
تتضمن الاستجابةcheckout_url:
Webhooks
تُخطر Webhooks خادمك عند وقوع أحداث الاشتراك. أعد إعداد نقطة النهاية ضمن Developer → Webhooks في لوحة التحكم. لإعداد نقطة نهاية webhook، راجع Webhooks.أنواع أحداث الاشتراك
تتبّع هذه الأحداث لإدارة دورة حياة الاشتراك:subscription.active— تم تفعيل الاشتراكsubscription.updated— تغيّر أحد الحقول في الاشتراكsubscription.on_hold— فشلت عملية تجديد أو عملية تحصيل رسوم تغيير الخطةsubscription.failed— فشل إنشاء الاشتراك (نهائي؛ يجب على العميل الاشتراك مجددًا)subscription.renewed— نجحت عملية تحصيل رسوم متكررةsubscription.past_due— فشلت عملية التجديد وبدأت فترة السماح؛ ويحتفظ العميل بإمكانية الوصول حتىpast_due_ends_atsubscription.plan_changed— تمت ترقية الخطة أو تخفيضها أو تغييرهاsubscription.cancelled— أُلغي الاشتراكsubscription.expired— بلغ الاشتراك نهاية مدته
paused وunpaused وupdate_payment_method، راجع Subscription Webhooks.
سيناريوهات الدفع
تدفق الدفع الناجح يعتمد تسلسل webhook على ما إذا كان الاشتراك يتضمن فترة تجريبية. الفوترة الفورية (0 يومًا تجريبيًا):subscription.active: تتم المصادقة على التفويض ويُفعّل الاشتراك.payment.succeeded: يؤكد عملية التحصيل الأولى. توقّع وصوله خلال 2–10 دقائق من Checkout.
- عند بدء الفترة التجريبية (Checkout): يتم تشغيل
subscription.activeبعد التصريح بطريقة الدفع. لا يتم تحصيل أي رسوم متكررة بعد. تُؤجّل أول عملية تحصيل فعلية حتى انتهاء الفترة التجريبية. - عند انتهاء الفترة التجريبية: يُحصّل المبلغ المتكرر، وتتلقى
payment.succeededمعsubscription.renewed.
subscription.renewed: يتم تشغيله في كل دورة فوترة عند خصم دفعة التجديد، ودائمًا بالتزامن معpayment.succeeded. كما يتضمنnext_billing_dateالمحدّث.
عند خصم أموال فعليًا مقابل منتج اشتراك، تحصل على
subscription.renewed و payment.succeeded. استخدم subscription.renewed (بدلًا من payment.succeeded وحده) كإشارة لتمديد الوصول إلى الدورة التالية.- فشل الاشتراك
subscription.failed- فشل إنشاء الاشتراك بسبب تعذّر إنشاء التفويض.payment.failed- يشير إلى فشل الدفع.
- تعليق الاشتراك
subscription.on_hold- تم تعليق الاشتراك بسبب فشل دفعة التجديد أو فشل تحصيل رسوم تغيير الخطة. إذا كان نشاطك التجاري يوفّر فترة سماح، فإن التجديد الفاشل ينقل الاشتراك أولًا إلىpast_due(subscription.past_due)، ثم ينقله إلىon_hold(أوcancelled، وفقًا لإعدادات فترة السماح) فقط عند انتهاء فترة السماح. راجع Subscription States.- عند تعليق الاشتراك، لن يتم تجديده تلقائيًا حتى يتم تحديث طريقة الدفع.
أفضل ممارسة: لتبسيط التنفيذ، نوصي بتتبّع أحداث الاشتراك بشكل أساسي لإدارة دورة حياة الاشتراك.
subscription.failed مقابل subscription.on_hold
من السهل الخلط بين هذين الحدثين، لكنهما يتطلبان معالجة مختلفة جدًا:
معالجة الاشتراك المعلّق
عندما يدخل الاشتراك في حالةon_hold، يجب تحديث طريقة الدفع لإعادة تفعيله. يشرح هذا القسم متى يتم تعليق الاشتراكات وكيفية التعامل معها.
متى تُعلّق الاشتراكات
يتم تعليق الاشتراك عندما:- تفشل دفعة التجديد: تفشل رسوم التجديد التلقائي بسبب عدم كفاية الأموال أو انتهاء صلاحية البطاقة أو رفض البنك
- تفشل رسوم تغيير الخطة: تفشل رسوم فورية أثناء ترقية الخطة أو تخفيضها
- تفشل المصادقة على طريقة الدفع: يتعذّر التصريح بطريقة الدفع للرسوم المتكررة
إعادة تفعيل الاشتراكات المعلّقة
لإعادة تفعيل اشتراك في حالةon_hold، استخدم Update Payment Method API. سيقوم ذلك تلقائيًا بما يلي:
- إنشاء رسوم للمبالغ المستحقة المتبقية
- إنشاء فاتورة للرسوم
- معالجة الدفع باستخدام طريقة الدفع الجديدة
- إعادة تفعيل الاشتراك إلى حالة
activeعند نجاح الدفع
1
Handle subscription.on_hold webhook
عند استلام webhook من نوع
subscription.on_hold، حدّث حالة تطبيقك وأخطر العميل:2
Update payment method
عندما يكون العميل مستعدًا لتحديث طريقة الدفع، استدعِ Update Payment Method API:
يمكنك أيضًا استخدام معرّف طريقة دفع موجود إذا كان العميل قد حفظ طرق دفع:
3
Monitor webhook events
بعد تحديث طريقة الدفع، راقب أحداث webhook التالية:
payment.succeeded- نجحت رسوم المبالغ المستحقة المتبقيةsubscription.active- أُعيد تفعيل الاشتراك
نموذج لحمولة حدث اشتراك
تغيير خطط الاشتراك
يمكنك ترقية خطة الاشتراك أو تخفيضها باستخدام نقطة نهاية change plan API. يتيح لك ذلك تعديل منتج الاشتراك والكمية ومعالجة proration.Change Plan API Reference
خيارات Proration
عند تغيير خطط الاشتراك، لديك أربعة خيارات لمعالجة الرسوم الفورية:1. prorated_immediately
- يخصم الجزء غير المستخدم من دورة الفوترة الحالية، محسوبًا تناسبيًا وفق الوقت المتبقي. يغطي الرصيد الخطة الأساسية والكمية وأي إضافات
- ثم يفرض رسوم دورة كاملة بالخطة والكمية والإضافات الجديدة. ولا تُحسب الرسوم نفسها تناسبيًا مطلقًا
- صافي الرسوم الفورية = (الدورة الجديدة الكاملة) ناقص (الكسر المتبقي × الدورة القديمة الكاملة). إذا كان الرصيد أكبر، يُحتفظ بالفرق كرَصيد خاص بالاشتراك للتجديدات المستقبلية
- أثناء الفترة التجريبية، ينقل هذا المستخدم فورًا إلى الخطة الجديدة، مع تحصيل الرسوم من العميل مباشرة
2. full_immediately
- يفرض على العميل كامل مبلغ الاشتراك للخطة الجديدة دون رصيد للدورة السابقة
- سواء عند الترقية أو التخفيض، يدفع العميل سعر الخطة الجديدة بالكامل من البداية
- مفيد عندما تريد تحصيل المبلغ الكامل بغض النظر عن الوقت المتبقي في الخطة القديمة
3. difference_immediately
- يدفع العميل الفرق فقط بين سعر الخطة القديمة وسعر الخطة الجديدة
- لا يعتمد المبلغ على وقت إجراء التغيير ضمن الدورة. تكلف الترقية نفسها المبلغ ذاته في اليوم الأول واليوم التاسع والعشرين
- عند الترقية، يُحصّل الفرق من العميل فورًا. مثلًا: $30/شهريًا → $80/شهريًا = يُحصّل $50 فورًا
- عند التخفيض، يُخزّن فرق السعر كرصيد خاص بالاشتراك ويُطبّق تلقائيًا على التجديدات المستقبلية. مثلًا: $50/شهريًا → $20/شهريًا = يُخزّن $30 كرصيد
4. do_not_bill
- يطبّق تغيير الخطة فورًا، لكنه لا يفرض أي رسوم وقت التغيير. ويمكن استخدام الخطة والكمية والإضافات الجديدة مباشرة
- بما أنه لا يتم تحصيل أي رسوم الآن، تمنح الترقية العميل الخطة الأعلى مجانًا لبقية الدورة الحالية. ويصبح التخفيض ساريًا فورًا دون رصيد للجزء غير المستخدم من الدورة التي سبق للعميل دفعها
- لا تُرصّد الإضافات الممنوحة عبر
do_not_billعند تغيير الخطة لاحقًا، لأنها لم تُحتسب رسومها أصلًا. ويحصّل التغيير اللاحق رسوم كمية الإضافة الجديدة بالكامل - تُفرض رسوم الخطة المحدّثة (والكمية/الإضافات) عند التجديد المجدول التالي، مع الحفاظ على تاريخ الفوترة الأصلي
السلوك
- عند استدعاء API هذا، يبدأ Dodo Payments فورًا تحصيل رسوم وفق خيار proration المحدد
- مع
prorated_immediately، يُحسب رصيد الجزء غير المستخدم من الدورة الحالية عند كل تغيير، سواء أكان ترقية أم تخفيضًا. إذا تجاوز الرصيد رسوم الدورة الجديدة، يُضاف الباقي إلى رصيد الاشتراك. وتخص هذه الأرصدة الاشتراكَ وحده، ولا تُستخدم إلا لمقابلة الدفعات المتكررة المستقبلية للاشتراك نفسه - مع
difference_immediately، يكون الصافي دائمًا فرق السعر الدقيق. وفي حالات التخفيض، يُخزّن الفائض كرَصيد خاص بالاشتراك، كما فيprorated_immediately - يتجاوز خيار
full_immediatelyحسابات الرصيد ويفرض كامل مبلغ الخطة الجديدة - يطبّق خيار
do_not_billالتغيير فورًا، لكنه يؤجّل الفوترة إلى تاريخ التجديد التالي المحفوظ
معالجة الرسوم
- تكتمل معالجة الرسوم الفورية التي تبدأ عند تغيير الخطة عادةً خلال أقل من دقيقتين
- إذا فشلت هذه الرسوم الفورية لأي سبب، يُعلّق الاشتراك تلقائيًا حتى حل المشكلة
الاشتراكات عند الطلب
تتيح لك الاشتراكات عند الطلب تحصيل الرسوم من العملاء بمرونة، وليس وفق جدول ثابت فقط. تتوفر هذه الميزة لجميع الحسابات.
subscription_data.on_demand في نص الطلب. يتيح لك ذلك التصريح بطريقة الدفع دون تحصيل فوري، أو تعيين سعر ابتدائي مخصص.
لتحصيل رسوم اشتراك عند الطلب:
بالنسبة إلى الرسوم اللاحقة، استخدم نقطة النهاية POST /subscriptions//charge وحدد المبلغ المطلوب تحصيله من العميل لهذه المعاملة.
للاطلاع على دليل كامل خطوة بخطوة (يتضمن أمثلة على الطلب/الاستجابة وسياسات إعادة المحاولة الآمنة ومعالجة webhook)، راجع On-Demand Subscriptions Guide.
أهم الأمور التي يجب معرفتها عن فوترة الاشتراكات
تتطلب الفترات التجريبية تفويضًا بقيمة $0، وليس رسومًا. عندما يتضمن الاشتراك فترة تجريبية، ينشئ بدء الفترة التجريبية تفويضًا بقيمة $0 لحفظ البطاقة؛ وتحدث أول عملية تحصيل فعلية عند انتهاء الفترة التجريبية. في قائمة المدفوعات، يظهر الاشتراك خلال فترة تجريبية مجانية مع دفعة واحدة بالضبط بقيمة
total_amount تساوي 0. أما الفترة التجريبية المدفوعة فتحصّل trial_amount مقدمًا بدلًا من ذلك.دورة حياة الاشتراك:
past_due = فشل التجديد وفترة السماح جارية (ويحتفظ العميل بإمكانية الوصول). on_hold = فشل التجديد (قابل للاسترداد: اطلب من العميل تحديث طريقة الدفع؛ وتُطبّق محاولات dunning). expired = انتهت المدة دون تجديد ولا يمكن إعادة تفعيله. يجب على العميل الاشتراك مجددًا. cancelled = انتهى بواسطة العميل أو التاجر. معظم حالات فشل التجديد هي عمليات رفض من جهة المُصدر (عدم كفاية الأموال أو رفض البطاقة)، وليست خطأً من Dodo.