Skip to main content

المتطلبات الأساسية

قبل البدء، تحتاج إلى:
  • حساب تاجر على Dodo Payments
  • مفتاح API من Developer → API Keys في لوحة التحكم، محفوظ في DODO_PAYMENTS_API_KEY
  • سر webhook من Developer → Webhooks، محفوظ في DODO_PAYMENTS_WEBHOOK_KEY
  • منتج اشتراك واحد على الأقل تم إنشاؤه ضمن Products
لمزيد من التفاصيل، راجع متطلبات دليل التكامل.

تكامل API

جلسات الدفع

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

استجابة API

تتضمن الاستجابة checkout_url:
أعد توجيه العميل إلى عنوان URL هذا. يفوّض العميل طريقة الدفع ويتم تفعيل الاشتراك.

Webhooks

تُخطر webhooks خادمك عند وقوع أحداث الاشتراك. أعد إعداد نقطة النهاية ضمن Developer → Webhooks في لوحة التحكم. لإعداد نقطة نهاية webhook، راجع Webhooks.

أنواع أحداث الاشتراك

تتبّع هذه الأحداث لإدارة دورة حياة الاشتراك:
  1. subscription.active — تم تفعيل الاشتراك
  2. subscription.updated — تغيّر حقل في الاشتراك
  3. subscription.on_hold — فشلت عملية تحصيل رسوم التجديد أو تغيير الخطة
  4. subscription.failed — فشل إنشاء الاشتراك (نهائي؛ يجب على العميل الاشتراك مجددًا)
  5. subscription.renewed — نجحت عملية تحصيل رسوم متكررة
  6. subscription.past_due — فشل التجديد وبدأت فترة السماح؛ يحتفظ العميل بإمكانية الوصول حتى past_due_ends_at
  7. subscription.plan_changed — تمت ترقية الخطة أو تخفيضها أو تغييرها
  8. subscription.cancelled — أُلغي الاشتراك
  9. subscription.expired — وصل الاشتراك إلى نهاية مدته
هذه هي الأحداث الأساسية. للحصول على القائمة الكاملة، بما في ذلك paused وunpaused وupdate_payment_method، راجع Webhooks الاشتراكات.
استخدم subscription.updated للحصول على إشعارات في الوقت الفعلي حول أي تغييرات في الاشتراك، والحفاظ على مزامنة حالة تطبيقك دون إجراء polling على API.

سيناريوهات الدفع

تدفق الدفع الناجح يعتمد تسلسل webhook على ما إذا كان الاشتراك يتضمن فترة تجريبية. الفوترة الفورية (0 يوم تجريبي):
  1. subscription.active: تتم الموافقة على التفويض وتفعيل الاشتراك.
  2. payment.succeeded: يؤكد عملية التحصيل الأولى. توقّع هذا الحدث خلال دقيقتين إلى 10 دقائق من إتمام الدفع.
مع فترة تجريبية:
  1. عند بدء الفترة التجريبية (الدفع): يتم تشغيل subscription.active بعد تفويض طريقة الدفع. لا يتم تحصيل رسوم متكررة بعد. ويتم تأجيل أول عملية تحصيل فعلية حتى انتهاء الفترة التجريبية.
  2. عند انتهاء الفترة التجريبية: يتم تحصيل المبلغ المتكرر، وتتلقى payment.succeeded مع subscription.renewed.
كل عملية تجديد لاحقة:
  • subscription.renewed: يتم تشغيله في كل دورة فوترة عند خصم دفعة التجديد، ودائمًا بالتزامن مع payment.succeeded. كما يتضمن next_billing_date المحدّث.
عند خصم الأموال فعليًا مقابل منتج اشتراك، ستتلقى subscription.renewed و payment.succeeded. استخدم subscription.renewed، بدلًا من payment.succeeded وحده، كإشارة لتمديد الوصول للدورة التالية.
سيناريوهات فشل الدفع
  1. فشل الاشتراك
  • subscription.failed - فشل إنشاء الاشتراك بسبب تعذّر إنشاء التفويض.
  • payment.failed - يشير إلى فشل الدفع.
  1. تعليق الاشتراك
  • subscription.on_hold - تم تعليق الاشتراك بسبب فشل دفعة التجديد أو فشل رسوم تغيير الخطة. إذا كان لنشاطك التجاري فترة سماح، فإن التجديد الفاشل ينقل الاشتراك أولًا إلى past_due (subscription.past_due)، ثم ينقله إلى on_hold (أو cancelled، حسب إعدادات فترة السماح) فقط عند انتهاء فترة السماح. راجع حالات الاشتراك.
  • عند تعليق الاشتراك، لن يتم تجديده تلقائيًا حتى يتم تحديث طريقة الدفع.
أفضل ممارسة: لتبسيط التنفيذ، نوصي بتتبّع أحداث الاشتراك بشكل أساسي لإدارة دورة حياة الاشتراك.
للحصول على شرح كامل لقراءة error_code/error_message، وتحديد وقت إعادة المحاولة، وعرض حالات الفشل للعملاء، راجع التعامل مع حالات فشل الدفع.

subscription.failed مقابل subscription.on_hold

من السهل الخلط بين هذين الحدثين، لكنهما يتطلبان أسلوبين مختلفين تمامًا في التعامل:
subscription.failed نهائي. لا يمكن إعادة تفعيل الاشتراك. يجب على العميل إنشاء اشتراك جديد. لا تمنح الاستحقاقات مطلقًا عند تشغيل هذا الحدث.

التعامل مع الاشتراك المعلّق

عندما يدخل الاشتراك في حالة on_hold، يجب تحديث طريقة الدفع لإعادة تفعيله. يوضّح هذا القسم متى يتم تعليق الاشتراكات وكيفية التعامل معها.

متى يتم تعليق الاشتراكات

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

إعادة تفعيل الاشتراكات المعلّقة

لإعادة تفعيل اشتراك في حالة on_hold، استخدم Update Payment Method API. يؤدي ذلك تلقائيًا إلى:
  1. إنشاء رسوم للمبالغ المستحقة المتبقية
  2. إنشاء فاتورة للرسوم
  3. معالجة الدفع باستخدام طريقة الدفع الجديدة
  4. إعادة تفعيل الاشتراك إلى حالة active عند نجاح الدفع
1

Handle subscription.on_hold webhook

عند تلقي webhook من نوع subscription.on_hold، حدّث حالة تطبيقك وأخطر العميل:
2

Update payment method

عندما يصبح العميل مستعدًا لتحديث طريقة الدفع، استدعِ Update Payment Method API:
يمكنك أيضًا استخدام معرّف طريقة دفع موجود إذا كان العميل قد حفظ طرق دفع:
3

Monitor webhook events

بعد تحديث طريقة الدفع، راقب أحداث webhook التالية:
  1. payment.succeeded - نجحت الرسوم الخاصة بالمبالغ المستحقة المتبقية
  2. subscription.active - تمت إعادة تفعيل الاشتراك

نموذج حمولة حدث اشتراك


تغيير خطط الاشتراك

يمكنك ترقية خطة الاشتراك أو تخفيضها باستخدام نقطة نهاية change plan API. يتيح لك ذلك تعديل منتج الاشتراك والكمية والتعامل مع proration.

Change Plan API Reference

للحصول على معلومات تفصيلية حول تغيير خطط الاشتراك، يُرجى الرجوع إلى وثائق Change Plan API.

خيارات Proration

عند تغيير خطط الاشتراك، لديك أربعة خيارات للتعامل مع الرسوم الفورية:

1. prorated_immediately

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

2. full_immediately

  • يفرض على العميل كامل مبلغ الاشتراك للخطة الجديدة دون رصيد للدورة السابقة
  • سواء عند الترقية أو التخفيض، يدفع العميل سعر الخطة الجديدة بالكامل من البداية
  • مفيد عندما تريد تحصيل المبلغ الكامل بغض النظر عن الوقت المتبقي في الخطة القديمة

3. difference_immediately

  • يدفع العميل الفرق فقط بين سعر الخطة القديمة وسعر الخطة الجديدة
  • لا يعتمد المبلغ على وقت إجراء التغيير ضمن الدورة. تكلف الترقية نفسها المبلغ نفسه في اليوم الأول واليوم 29
  • عند الترقية، يُفرض على العميل الفرق فورًا. على سبيل المثال، $30/شهريًا → $80/شهريًا = يتم تحصيل $50 فورًا
  • عند التخفيض، يُخزّن فرق السعر كرصيد مرتبط بالاشتراك ويُطبّق تلقائيًا على التجديدات المستقبلية. على سبيل المثال، $50/شهريًا → $20/شهريًا = يتم تخزين $30 كرصيد

4. do_not_bill

  • يطبّق تغيير الخطة فورًا، لكنه لا يفرض أي رسوم وقت التغيير. ويمكن استخدام الخطة والكمية والإضافات الجديدة مباشرة
  • بما أنه لا يتم تحصيل أي رسوم الآن، تمنح الترقية العميل الخطة الأعلى مجانًا لبقية الدورة الحالية. ويصبح التخفيض ساريًا فورًا دون رصيد للجزء غير المستخدم من الدورة التي دفع العميل مقابلها مسبقًا
  • لا تتم إضافة رصيد للإضافات الممنوحة عبر do_not_bill عند تغيير الخطة لاحقًا، لأنها لم تُفوتر أصلًا. ويؤدي التغيير اللاحق إلى فوترة كمية الإضافة الجديدة بالكامل
  • تتم فوترة الخطة المحدّثة (والكمية/الإضافات) عند التجديد المجدول التالي، مع الحفاظ على تاريخ الفوترة الأصلي
تؤدي أوضاع “التحصيل الآن” الثلاثة إلى إعادة ضبط دورة الفوترة. ينقل كل من prorated_immediately وdifference_immediately وfull_immediately قيمة next_billing_date الخاصة بالاشتراك إلى تاريخ التغيير. أما do_not_bill وحده فيحافظ على تاريخ التجديد الأصلي، لكنه لا يفرض أي رسوم فورية.

السلوك

  • عند استدعاء API هذا، يبدأ Dodo Payments فورًا عملية تحصيل استنادًا إلى خيار proration الذي اخترته
  • مع prorated_immediately، يتم احتساب رصيد الجزء غير المستخدم من الدورة الحالية عند كل تغيير، سواء كانت ترقية أو تخفيضًا. وإذا تجاوز الرصيد رسوم الدورة الجديدة، تُضاف القيمة المتبقية إلى رصيد الاشتراك. وتكون هذه الأرصدة خاصة بالاشتراك ولن تُستخدم إلا لمقاصة الدفعات المتكررة المستقبلية للاشتراك نفسه
  • مع difference_immediately، يكون الصافي دائمًا مساويًا تمامًا لفرق السعر. وفي حالة التخفيض، يُخزّن الفرق الزائد كرصيد مرتبط بالاشتراك، كما في prorated_immediately
  • يتجاوز خيار full_immediately حسابات الرصيد ويفرض كامل مبلغ الخطة الجديدة
  • يطبّق خيار do_not_bill التغيير فورًا، لكنه يؤجل الفوترة إلى تاريخ التجديد التالي، مع الحفاظ على هذا التاريخ
اختيار وضع proration:
  • difference_immediately — يدفع العميل فرق السعر. الخيار الأكثر قابلية للتنبؤ؛ فالرسوم نفسها بغض النظر عن وقت إجراء التغيير ضمن الدورة.
  • prorated_immediately — يحصل العميل على رصيد مقابل الوقت غير المستخدم فقط من الدورة الحالية. تختلف الرسوم حسب وقت إجراء التغيير ضمن الدورة.
  • full_immediately — يدفع العميل كامل مبلغ الخطة الجديدة. لا يوجد رصيد للدورة السابقة.
  • do_not_bill — لا توجد رسوم الآن. تتم فوترة الخطة الجديدة عند التجديد التالي. وهو الوضع الوحيد الذي يحافظ على تاريخ الفوترة الأصلي.

معالجة الرسوم

  • تكتمل معالجة الرسوم الفورية التي تبدأ عند تغيير الخطة عادةً خلال أقل من دقيقتين
  • إذا فشلت هذه الرسوم الفورية لأي سبب، يتم تعليق الاشتراك تلقائيًا حتى حل المشكلة

الاشتراكات عند الطلب

تتيح لك الاشتراكات عند الطلب تحصيل الرسوم من العملاء بمرونة، وليس وفق جدول ثابت فقط. هذه الميزة متاحة لجميع الحسابات.
لإنشاء اشتراك عند الطلب: لإنشاء اشتراك عند الطلب، استخدم نقطة نهاية API ‏POST /checkouts وأدرج الحقل subscription_data.on_demand في نص الطلب. يتيح لك ذلك تفويض طريقة دفع دون تحصيل فوري، أو تحديد سعر ابتدائي مخصص.
POST /subscriptions مهمل. لا يزال يعمل مع عمليات التكامل الحالية، لكن ينبغي لعمليات التكامل الجديدة إنشاء الاشتراكات عند الطلب من خلال جلسة دفع ‏(POST /checkouts) مع subscription_data.on_demand. راجع دليل الاشتراكات عند الطلب للتدفق الحالي.
لتحصيل رسوم اشتراك عند الطلب: بالنسبة إلى الرسوم اللاحقة، استخدم نقطة النهاية ‏POST /subscriptions//charge وحدد المبلغ الذي تريد تحصيله من العميل لهذه المعاملة.
للحصول على دليل كامل خطوة بخطوة (يتضمن أمثلة على الطلبات/الاستجابات وسياسات إعادة المحاولة الآمنة والتعامل مع webhooks)، راجع دليل الاشتراكات عند الطلب.

أمور أساسية يجب معرفتها حول فوترة الاشتراكات

اجعل مدة الاشتراك أطول من تكرار الدفع. إذا ساوت مدة الاشتراك تكرار الدفع (مثلًا: المدة = شهر واحد، والتكرار = شهر واحد)، يكون الاشتراك صالحًا لدورة واحدة فقط، ثم ينتقل إلى expired بدلًا من التجديد. للحصول على خطة شهرية مستمرة، حدّد مدة اشتراك طويلة (مثلًا 20 عامًا) مع تكرار دفع شهري.
تُثبّت العملة عند أول عملية تحصيل ناجحة. مرّر دائمًا billing_currency وbilling_address.country بشكل صريح عند إنشاء الدفع. وإذا لم تُحددا، فسيتم اكتشافهما من عنوان IP الخاص بالعميل (Adaptive Currency)، وبمجرد تنفيذ أول عملية تحصيل للاشتراك تُثبّت العملة طوال مدة الاشتراك. ولا يستطيع العميل الذي يسافر لاحقًا تغييرها.
تتطلب الفترات التجريبية تفويضًا بقيمة $0، وليس تحصيلًا. عندما يتضمن الاشتراك فترة تجريبية، ينشئ بدء الفترة التجريبية تفويض mandate بقيمة $0 لحفظ البطاقة؛ وتحدث أول عملية تحصيل فعلية عند انتهاء الفترة التجريبية. في قائمة المدفوعات، يظهر الاشتراك خلال فترة تجريبية مجانية مع دفعة واحدة بالضبط بقيمة total_amount تساوي 0. أما الفترة التجريبية المدفوعة فتحصّل trial_amount مقدمًا بدلًا من ذلك.
دورة حياة الاشتراك: past_due = فشل التجديد وفترة السماح قيد التشغيل (ويحتفظ العميل بإمكانية الوصول). on_hold = فشل التجديد (قابل للاسترداد: اطلب من العميل تحديث طريقة الدفع؛ وتنطبق محاولات dunning). expired = انتهت المدة دون تجديد ولا يمكن إعادة تفعيله. يجب على العميل الاشتراك مجددًا. cancelled = انتهى من جانب العميل أو التاجر. معظم حالات فشل التجديد هي عمليات رفض من جهة مُصدر البطاقة (عدم كفاية الرصيد أو رفض البطاقة)، وليست خطأً من Dodo.
تعمل البطاقات الهندية باستخدام تفويض RBI الإلكتروني. قد تستغرق الرسوم خارج الجلسة (التجديدات ورسوم تغيير الخطة) نحو 48 ساعة لتسويتها، وتتطلب عمليات الخصم التلقائي المتكررة التي تتجاوز ₹15,000 مصادقة جديدة من العميل (لذلك لا يمكن لترقية تتجاوز هذا الحد استخدام التفويض الحالي). أثناء وجود عملية تحصيل واحدة في حالة processing، تفشل عملية تحصيل ثانية على الاشتراك نفسه مع الرسالة “Cannot create new charge as previous payment is not successful yet.” أما البطاقات غير الهندية فتُؤكّد المعاملات شبه فورًا.
تحتوي رسوم الاشتراك على حد أدنى قدره $1 (أو ما يعادله بالعملة). تُرفض المبالغ من نوع $0.01–$0.99 باستخدام product_price: value out of range. يُسمح بمنتج اشتراك سعره $0 بالضبط؛ راجع البطاقة اختيارية عند السعر الصفري. لتفويض بطاقة دون تحصيل رسوم منها، استخدم إعداد mandate_only عند الطلب.

مرجع API ذي صلة

Create Subscription (Deprecated)

API قديم لإنشاء اشتراك مباشرةً. استخدم جلسات الدفع لعمليات التكامل الجديدة

Change Subscription Plan

مرجع API لترقية خطط الاشتراك أو تخفيضها أو تغييرها باستخدام خيارات proration

Update Payment Method

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

Patch Subscription

مرجع API لتحديث تفاصيل الاشتراك وإعداداته
آخر تعديل في ٢٦ سبتمبر ٢٠٢٦