الانتقال إلى المحتوى الرئيسي

نظرة عامة

تتيح لك الاشتراكات عند الطلب تفويض وسيلة الدفع الخاصة بالعميل مرة واحدة ثم تحصيل مبالغ متغيرة كلما احتجت، بدلاً من جدول زمني ثابت. هذه الميزة متاحة لجميع الحسابات - لا حاجة لموافقة. استخدم هذا الدليل لـ:
  • إنشاء اشتراك عند الطلب (تفويض تفويض مع سعر أولي اختياري)
  • تحفيز الرسوم اللاحقة بمبالغ مخصصة
  • تتبع النتائج باستخدام الويب هوكس
لإعداد اشتراك عام، راجع دليل تكامل الاشتراك.

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

  • حساب تاجر دودي بايمنتس ومفتاح API
  • سر الويب هوك مُعد ونقطة نهاية لاستقبال الأحداث
  • منتج اشتراك في كتالوجك
إذا كنت ترغب في أن يوافق العميل على التفويض عبر صفحة الدفع المستضافة، فقم بتعيين payment_link: true وقدم return_url.

كيف تعمل الاشتراكات عند الطلب

  1. تنشئ اشتراكًا باستخدام الكائن on_demand لتفويض وسيلة الدفع وجمع رسوم أولية اختيارية.
  2. لاحقًا، تنشئ رسومًا على ذلك الاشتراك بمبالغ مخصصة باستخدام نقطة النهاية المخصصة للرسوم.
  3. تراقب الـ webhooks (مثل payment.succeeded، payment.failed) لتحديث نظامك.

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

نقطة النهاية: POST /checkouts حقول الطلب الرئيسية (الجسم):
يرجى العثور عليها في إنشاء جلسة الخروج

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

import DodoPayments from 'dodopayments';

const client = new DodoPayments({
  bearerToken: process.env.DODO_PAYMENTS_API_KEY,
  environment: 'test_mode', // defaults to 'live_mode'
});

async function main() {
  const subscription = await client.checkoutSessions.create({
    product_cart: [{ product_id: 'pdt_123', quantity: 1 }],
    billing_address:  { city: 'SF', country: 'US', state: 'CA', street: '1 Market St', zipcode: '94105' },
    customer: { customer_id: 'cus_123' },
    return_url: 'https://example.com/billing/success',
    subscription_data: {
        on_demand: {
            mandate_only: true // set false to collect an initial charge
            // product_price: 1000, // optional: charge $10.00 now if mandate_only is false
            // product_currency: 'USD',
            // product_description: 'Custom initial charge',
            // adaptive_currency_fees_inclusive: false,
        }
    }
  });

  console.log(subscription.checkout_url);
}

main().catch(console.error);
Success
{
  "session_id": "cks_123",
  "checkout_url": "https://test.checkout.dodopayments.com/session/cks123"
}

تحصيل اشتراك عند الطلب

بعد تفويض التفويض، قم بإنشاء رسوم حسب الحاجة. نقطة النهاية: POST /subscriptions/{subscription_id}/charge حقول الطلب الرئيسية (الجسم):
product_price
integer
مطلوب
المبلغ الذي سيتم تحصيله (بوحدة العملة الأصغر). مثال: لتحصيل 25.00$، مرّر 2500.
product_currency
string
تجاوز العملة الاختياري للرسوم.
product_description
string
تجاوز الوصف الاختياري لهذا الرسم.
adaptive_currency_fees_inclusive
boolean
إذا كانت القيمة صحيحة، يتضمن ذلك رسوم العملة التكيفية ضمن product_price. إذا كانت خاطئة، تُضاف الرسوم فوقها.
metadata
object
بيانات وصفية إضافية للدفع. إذا تم حذفها، يتم استخدام البيانات الوصفية للاشتراك.
import DodoPayments from 'dodopayments';

const client = new DodoPayments({ bearerToken: process.env.DODO_PAYMENTS_API_KEY });

async function chargeNow(subscriptionId) {
  const res = await client.subscriptions.charge(subscriptionId, { product_price: 2500 });
  console.log(res.payment_id);
}

chargeNow('sub_123').catch(console.error);
Success
{ "payment_id": "pay_abc123" }
قد تفشل عملية تحصيل رسوم اشتراك غير عند الطلب. تأكد من أن الاشتراك يحتوي على on_demand: true في تفاصيله قبل التحصيل.

محاولات الدفع

قد يقوم نظام كشف الاحتيال لدينا بحظر أنماط المحاولة العدوانية (ويمكن أن يحددها كنماذج اختبار بطاقات محتملة). اتبع سياسة إعادة المحاولة الآمنة.
يمكن لأنماط إعادة المحاولة المتتالية أن تُعتبر احتيالية أو اختبار بطاقة مشبوه من قبل أنظمة المخاطر والمعالجات لدينا. تجنب عمليات إعادة المحاولة المتجمعة؛ اتبع جدول التراجع وإرشادات تنسيق الوقت أدناه.

مبادئ سياسة إعادة المحاولة الآمنة

  • آلية التراجع: استخدم تراجعًا أسيًا بين المحاولات.
  • حدود المحاولات: حدد إجمالي المحاولات (بحد أقصى 3–4 محاولات).
  • الترشيح الذكي: أعد المحاولة فقط عند حالات الفشل القابلة لإعادة المحاولة (مثل أخطاء الشبكة/المُصدر، نقص الرصيد)؛ لا تعيد المحاولة أبدًا بعد الرفض القاطع.
  • منع اختبار البطاقات: لا تعيد المحاولة عند فشل مثل DO_NOT_HONOR، STOLEN_CARD، LOST_CARD، PICKUP_CARD، FRAUDULENT، AUTHENTICATION_FAILURE.
  • تنويع البيانات الوصفية (اختياري): إذا كنت تدير نظام إعادة المحاولة الخاص بك، فميِّز المحاولات عبر البيانات الوصفية (على سبيل المثال retry_attempt).

جدول إعادة المحاولة المقترح (الاشتراكات)

  • المحاولة الأولى: فورية عند إنشاء الرسوم
  • المحاولة الثانية: بعد 3 أيام
  • المحاولة الثالثة: بعد 7 أيام أخرى (10 أيام إجمالاً)
  • المحاولة الرابعة (الأخيرة): بعد 7 أيام أخرى (17 يومًا إجمالاً)
الخطوة النهائية: إذا لم يتم الدفع بعد، قم بوضع علامة على الاشتراك كغير مدفوع أو قم بإلغائه، بناءً على سياستك. قم بإخطار العميل خلال الفترة الزمنية لتحديث وسيلة الدفع الخاصة بهم.

تجنب المحاولات المتفجرة؛ التوافق مع وقت التفويض

  • اربط المحاولات بإشارة الوقت الأصلية للتفويض لتجنب سلوك ” burst ” عبر محفظتك.
  • مثال: إذا بدأ العميل تجربة أو تفويضًا في الساعة 1:10 ظهرًا اليوم، فقم بجدولة محاولات المتابعة في الساعة 1:10 ظهرًا في الأيام التالية وفقًا لجدول التراجع (مثلاً +3 أيام → 1:10 ظهرًا، +7 أيام → 1:10 ظهرًا).
  • بدلاً من ذلك، إذا كنت تخزن وقت آخر دفعة ناجحة T، فحدد المحاولة التالية عند T + X days للحفاظ على تزامن وقت اليوم.
المنطقة الزمنية والتوقيت الصيفي: استخدم معيار وقت ثابت للجدولة وحوّله للعرض فقط للحفاظ على الفترات.

رموز الرفض التي يجب ألا تعيد المحاولة عليها

  • STOLEN_CARD
  • DO_NOT_HONOR
  • FRAUDULENT
  • PICKUP_CARD
  • AUTHENTICATION_FAILURE
  • LOST_CARD
للحصول على قائمة شاملة بأسباب الرفض وما إذا كان يمكن للمستخدم تصحيحها، راجع وثائق Transaction Failures.
أعد المحاولة فقط عند المشاكل المؤقتة/اللطيفة (مثل insufficient_funds، issuer_unavailable، processing_error، انتهاء مهلة الشبكة). إذا تكرر نفس الرفض، أوقف المزيد من المحاولات.

إرشادات التنفيذ (بدون كود)

  • استخدم جدولًا زمنيًا/صفًا يحفظ الطوابع الزمنية الدقيقة؛ احسب المحاولة التالية في نفس فرق وقت اليوم (مثلاً T + 3 days في نفس HH:MM).
  • احتفظ بآخر طابع زمني لدفعة ناجحة T وارجع إليه لحساب المحاولة التالية؛ لا تجمع عدة اشتراكات في نفس اللحظة.
  • قيّم دائمًا سبب الرفض الأخير؛ أوقف المحاولات في حال الرفض القاطع المدرج في قائمة التجاهل أعلاه.
  • حدد عدد المحاولات المتزامنة لكل عميل ولكل حساب لتجنب الارتفاعات غير المقصودة.
  • تواصَل بشكل استباقي: أرسل بريدًا إلكترونيًا/رسالة نصية للعميل لتحديث وسيلة الدفع قبل المحاولة المجدولة التالية.
  • استخدم البيانات الوصفية للمراقبة فقط (مثل retry_attempt)؛ لا تحاول “مراوغة” أنظمة المخاطر/الاحتيال بتدوير حقول غير ذات مغزى.

تتبع النتائج باستخدام الويب هوكس

قم بتنفيذ معالجة الويب هوك لتتبع رحلة العميل. راجع تنفيذ الويب هوكس.
  • subscription.active: تم تفويض التفويض وتم تفعيل الاشتراك
  • subscription.failed: فشل الإنشاء (مثل فشل التفويض)
  • subscription.on_hold: تم وضع الاشتراك في حالة تعليق (مثل الحالة غير المدفوعة)
  • payment.succeeded: تم تحصيل الرسوم بنجاح
  • payment.failed: فشل تحصيل الرسوم
بالنسبة لتدفقات عند الطلب، ركز على payment.succeeded وpayment.failed لمطابقة الرسوم المعتمدة على الاستخدام.

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

1

Create in test mode

استخدم مفتاح API الاختبار الخاص بك لإنشاء الاشتراك باستخدام payment_link: true، ثم افتح الرابط وأكمل التفويض.
2

Trigger a charge

استدع نقطة نهاية الرسوم بمبلغ صغير product_price (مثل 100) وتحقق من حصولك على payment.succeeded.
3

Go live

حوّل إلى مفتاح API الحي بعد التحقق من الأحداث وتحديثات الحالة الداخلية.

استكشاف الأخطاء وإصلاحها

  • 422 Invalid Request: تأكد من تقديم on_demand.mandate_only عند الإنشاء وproduct_price للرسوم.
  • Currency errors: إذا قمت بتجاوز product_currency، فتأكد من دعمه لحسابك وعميلك.
  • No webhooks received: تحقق من تكوين عنوان URL للويب هوك وسر التوقيع الخاص بك.