Skip to main content

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

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

تكامل API

جلسات الدفع

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

استجابة 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، راجع Subscription Webhooks.
استخدم subscription.updated للحصول على إشعارات فورية بشأن أي تغييرات في الاشتراك، والحفاظ على تزامن حالة تطبيقك دون إجراء polling على API.

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

تدفق الدفع الناجح يعتمد تسلسل webhook على ما إذا كان الاشتراك يتضمن فترة تجريبية. الفوترة الفورية (0 يومًا تجريبيًا):
  1. subscription.active: تتم المصادقة على التفويض ويُفعّل الاشتراك.
  2. payment.succeeded: يؤكد عملية التحصيل الأولى. توقّع وصوله خلال 2–10 دقائق من Checkout.
مع فترة تجريبية:
  1. عند بدء الفترة التجريبية (Checkout): يتم تشغيل 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، وفقًا لإعدادات فترة السماح) فقط عند انتهاء فترة السماح. راجع Subscription States.
  • عند تعليق الاشتراك، لن يتم تجديده تلقائيًا حتى يتم تحديث طريقة الدفع.
أفضل ممارسة: لتبسيط التنفيذ، نوصي بتتبّع أحداث الاشتراك بشكل أساسي لإدارة دورة حياة الاشتراك.
للاطلاع على شرح كامل لقراءة error_code/error_message، وتحديد وقت إعادة المحاولة، وعرض حالات الفشل للعملاء، راجع Handle Payment Failures.

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

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

2. full_immediately

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

3. difference_immediately

  • يدفع العميل الفرق فقط بين سعر الخطة القديمة وسعر الخطة الجديدة
  • لا يعتمد المبلغ على وقت إجراء التغيير ضمن الدورة. تكلف الترقية نفسها المبلغ ذاته في اليوم الأول واليوم التاسع والعشرين
  • عند الترقية، يُحصّل الفرق من العميل فورًا. مثلًا: $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 مهمل. لا يزال يعمل مع عمليات التكامل الحالية، لكن ينبغي لعمليات التكامل الجديدة إنشاء اشتراكات عند الطلب من خلال Checkout Session ‏(POST /checkouts) مع subscription_data.on_demand. راجع On-Demand Subscriptions Guide للتدفق الحالي.
لتحصيل رسوم اشتراك عند الطلب: بالنسبة إلى الرسوم اللاحقة، استخدم نقطة النهاية ‏POST /subscriptions//charge وحدد المبلغ المطلوب تحصيله من العميل لهذه المعاملة.
للاطلاع على دليل كامل خطوة بخطوة (يتضمن أمثلة على الطلب/الاستجابة وسياسات إعادة المحاولة الآمنة ومعالجة webhook)، راجع On-Demand Subscriptions Guide.

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

اجعل مدة الاشتراك أطول من تكرار الدفع. إذا ساوت مدة الاشتراك تكرار الدفع (مثلًا: الفترة = شهر واحد، والتكرار = شهر واحد)، يكون الاشتراك صالحًا لدورة واحدة ثم ينتقل إلى expired بدلًا من التجديد. للحصول على خطة شهرية مستمرة، عيّن مدة اشتراك طويلة (مثلًا 20 عامًا) مع تكرار دفع شهري.
تُثبّت العملة عند أول عملية تحصيل ناجحة. مرّر دائمًا billing_currency وbilling_address.country صراحةً عند إنشاء Checkout. إذا لم تُحددا، فسيتم اكتشافهما من IP العميل (Adaptive Currency)، وبمجرد تنفيذ الاشتراك أول عملية تحصيل، تُثبّت العملة طوال مدة الاشتراك. ولا يستطيع العميل تغييرها إذا سافر لاحقًا.
تتطلب الفترات التجريبية تفويضًا بقيمة $0، وليس رسومًا. عندما يتضمن الاشتراك فترة تجريبية، ينشئ بدء الفترة التجريبية تفويضًا بقيمة $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.00 بعملة USD. يرفض Checkout الإجمالي الأقل مع TOTAL_PAYMENT_AMOUNT_BELOW_MINIMUM_AMOUNT. ويجب أن تبلغ قيمة العملات الأخرى غير USD وEUR وGBP أيضًا $1.00 على الأقل؛ راجع Minimum Amounts. ويُرفض رسم عند الطلب product_price الأقل من 100 بوحدة العملة الأصغر مع product_price: value out of range. يُسمح بمنتج اشتراك مسعّر بقيمة $0 بالضبط؛ راجع Card-Optional at Zero Price. وللتصريح بالبطاقة دون تحصيل رسوم، استخدم إعداد mandate_only عند الطلب.

مرجع API ذي صلة

Create Subscription (Deprecated)

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

Change Subscription Plan

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

Update Payment Method

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

Patch Subscription

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