> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dodopayments.com/llms.txt
> Use this file to discover all available pages before exploring further.

# دليل تكامل الاشتراك

> سيساعدك هذا الدليل في دمج منتج اشتراك مدفوعات دودو في موقعك الإلكتروني.

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

لدمج واجهة برمجة تطبيقات مدفوعات دودو، ستحتاج إلى:

* حساب تاجر مدفوعات دودو
* بيانات اعتماد واجهة برمجة التطبيقات (مفتاح API ومفتاح سرية webhook) من لوحة التحكم

للحصول على دليل أكثر تفصيلاً حول المتطلبات الأساسية، تحقق من [هذا القسم](/developer-resources/integration-guide#dashboard-setup).

## تكامل واجهة برمجة التطبيقات

### جلسات الدفع

استخدم جلسات الدفع Checkout Sessions لبيع منتجات الاشتراك من خلال صفحة دفع مستضافة وآمنة. مرّر منتج الاشتراك الخاص بك في `product_cart` وأعد توجيه العملاء إلى `checkout_url`.

<Tip>
  **Mixed Checkout**: يمكنك دمج منتجات الاشتراك مع منتجات لمرة واحدة في نفس جلسة الدفع. يتيح ذلك حالات استخدام مثل رسوم الإعداد مع الاشتراكات، حزم الأجهزة مع برامج الخدمة السحابية، والمزيد. راجع [دليل جلسات الدفع](/developer-resources/checkout-session) للحصول على أمثلة.
</Tip>

<Tabs>
  <Tab title="Node.js SDK">
    ```javascript theme={null}
    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 session = await client.checkoutSessions.create({
        product_cart: [
          { product_id: 'prod_subscription_monthly', quantity: 1 }
        ],
        // Optional: configure trials for subscription products
        subscription_data: { trial_period_days: 14 },
        customer: {
          email: 'subscriber@example.com',
          name: 'Jane Doe',
        },
        return_url: 'https://example.com/success',
      });

      console.log(session.checkout_url);
    }

    main();
    ```
  </Tab>

  <Tab title="Python SDK">
    ```python theme={null}
    import os
    from dodopayments import DodoPayments

    client = DodoPayments(
        bearer_token=os.environ.get("DODO_PAYMENTS_API_KEY"),
        environment="test_mode",  # defaults to "live_mode"
    )

    session = client.checkout_sessions.create(
        product_cart=[
            {"product_id": "prod_subscription_monthly", "quantity": 1}
        ],
        subscription_data={"trial_period_days": 14},  # optional
        customer={
            "email": "subscriber@example.com",
            "name": "Jane Doe",
        },
        return_url="https://example.com/success",
    )

    print(session.checkout_url)
    ```
  </Tab>

  <Tab title="REST API">
    ```javascript theme={null}
    const response = await fetch('https://test.dodopayments.com/checkouts', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${process.env.DODO_PAYMENTS_API_KEY}`
      },
      body: JSON.stringify({
        product_cart: [
          { product_id: 'prod_subscription_monthly', quantity: 1 }
        ],
        subscription_data: { trial_period_days: 14 }, // optional
        customer: {
          email: 'subscriber@example.com',
          name: 'Jane Doe'
        },
        return_url: 'https://example.com/success'
      })
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const session = await response.json();
    console.log(session.checkout_url);
    ```
  </Tab>
</Tabs>

### استجابة واجهة برمجة التطبيقات

فيما يلي مثال على الاستجابة:

```json theme={null}
{
  "session_id": "cks_Gi6KGJ2zFJo9rq9Ukifwa",
  "checkout_url": "https://test.checkout.dodopayments.com/session/cks_Gi6KGJ2zFJo9rq9Ukifwa"
}
```

إعادة توجيه العميل إلى `checkout_url`.

### Webhooks

عند دمج الاشتراكات، ستستلم webhooks لمتابعة دورة حياة الاشتراك. تساعدك هذه webhooks في إدارة حالات الاشتراك وسيناريوهات الدفع بشكل فعال.

لإعداد نقطة نهاية webhook الخاصة بك، يُرجى اتباع [دليل التكامل التفصيلي](/developer-resources/integration-guide#implementing-webhooks).

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

تتبع الأحداث التالية في webhook تغييرات حالة الاشتراك:

1. **`subscription.active`** - تم تنشيط الاشتراك بنجاح.
2. **`subscription.updated`** - تم تحديث كائن الاشتراك (يتم تشغيله عند تغيير أي حقل).
3. **`subscription.on_hold`** - تم تعليق الاشتراك بسبب فشل التجديد.
4. **`subscription.failed`** - فشل إنشاء الاشتراك أثناء إنشاء التفويض.
5. **`subscription.renewed`** - تم تجديد الاشتراك لفترة الفوترة التالية.

لإدارة دورة حياة الاشتراكات بشكل موثوق، نوصي بتتبع هذه الأحداث الخاصة بالاشتراك.

<Tip>
  استخدم `subscription.updated` للحصول على إشعارات في الوقت الفعلي حول أي تغييرات في الاشتراك، مما يبقي حالة التطبيق متزامنة دون الاستطلاع من API.
</Tip>

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

**تدفق الدفع الناجح**

عند نجاح الدفع، ستستلم webhooks التالية:

1. `subscription.active` - يُشير إلى تنشيط الاشتراك
2. `payment.succeeded` - يُؤكد الدفع الأولي:
   * للفواتير الفورية (0 أيام تجربة): يُتوقع الاستلام خلال 2-10 دقائق
   * لأيام التجربة: بمجرد انتهائها
3. `subscription.renewed` - يُشير إلى خصم الدفع وتجديد الدورة القادمة. (بشكل أساسي، كلما تم خصم الدفع للمنتجات المشتركة، ستحصل على `subscription.renewed` webhook مع `payment.succeeded`)

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

1. فشل الاشتراك

* `subscription.failed` - فشل إنشاء الاشتراك بسبب فشل في إنشاء التفويض.
* `payment.failed` - يُشير إلى فشل الدفع.

2. تعليق الاشتراك

* `subscription.on_hold` - تم تعليق الاشتراك بسبب فشل تجديد الدفع أو فشل رسوم تغيير الخطة.
* عند تعليق الاشتراك، لن يتم تجديده تلقائيًا حتى يتم تحديث طريقة الدفع.

<Info>**أفضل ممارسة**: لتبسيط التنفيذ، نوصي بتتبع أحداث الاشتراك بشكل أساسي لإدارة دورة حياة الاشتراك.</Info>

<Tip>
  للحصول على إرشادات كاملة لقراءة `error_code`/`error_message`، وتحديد متى يتم إعادة المحاولة، وتوضيح الفشل للعملاء، انظر [تعامل مع فشل الدفع](/developer-resources/handle-payment-failures).
</Tip>

#### `subscription.failed` مقابل `subscription.on_hold`

هذان الحدثان سهلان في الخلط بينهما، لكنهما يتطلبان معالجة مختلفة تمامًا:

| الحدث                  | متى يتم تشغيله                                                | الحالة    | قابل للاسترداد؟ | ماذا تفعل                                                                                                |
| ---------------------- | ------------------------------------------------------------- | --------- | --------------- | -------------------------------------------------------------------------------------------------------- |
| `subscription.failed`  | لم يتم إنشاء التفويض **الأولي** عند **إنشاء** الاشتراك        | `failed`  | **لا — نهائي**  | لا تمنح وصولاً. اطلب من العميل بدء اشتراك **جديد** بطريقة دفع مختلفة.                                    |
| `subscription.on_hold` | فشل دفع **تجديد** (أو رسوم تغيير الخطة) على اشتراك نشط بالفعل | `on_hold` | **نعم**         | استرد عن طريق تحديث طريقة الدفع؛ راجع [التعامل مع تعليق الاشتراك](#handling-subscription-on-hold) أدناه. |

<Warning>
  `subscription.failed` نهائي — لا يمكن إعادة تنشيط الاشتراك. يجب على العميل إنشاء اشتراك جديد. لا تمنح الامتيازات عند حدوث هذا الحدث.
</Warning>

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

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

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

يتم وضع الاشتراك على تعليق عندما:

* **فشل دفع التجديد**: يفشل الشحن التلقائي للتجديد بسبب نقص الأموال أو انتهاء صلاحية البطاقة أو رفض من البنك
* **فشل رسوم تغيير الخطة**: فشل الشحن الفوري خلال الترقية/الخفض
* **فشل تفويض طريقة الدفع**: لا يمكن تفويض طريقة الدفع للرسوم المتكررة

<Warning>
  الاشتراكات في حالة `on_hold` لن يتم تجديدها تلقائيًا. يجب تحديث طريقة الدفع لإعادة تنشيط الاشتراك.
</Warning>

#### إعادة تنشيط الاشتراكات من حالة التعليق

لإعادة تنشيط اشتراك من حالة `on_hold`، استخدم API تحديث طريقة الدفع. يتم تلقائيًا:

1. إنشاء شحن للديون المتبقية
2. إنشاء فاتورة للشحن
3. معالجة الدفع باستخدام طريقة الدفع الجديدة
4. إعادة تنشيط الاشتراك إلى حالة `active` عند الدفع الناجح

<Steps>
  <Step title="Handle subscription.on_hold webhook">
    عند تلقي `subscription.on_hold` webhook، قم بتحديث حالة التطبيق الخاصة بك وإخطار العميل:

    ```javascript theme={null}
    // Webhook handler
    app.post('/webhooks/dodo', async (req, res) => {
      const event = req.body;
      
      if (event.type === 'subscription.on_hold') {
        const subscription = event.data;
        
        // Update subscription status in your database
        await updateSubscriptionStatus(subscription.subscription_id, 'on_hold');
        
        // Notify customer to update payment method
        await sendEmailToCustomer(subscription.customer_id, {
          subject: 'Payment Required - Subscription On Hold',
          message: 'Your subscription is on hold. Please update your payment method to continue service.'
        });
      }
      
      res.json({ received: true });
    });
    ```
  </Step>

  <Step title="Update payment method">
    عندما يكون العميل جاهزًا لتحديث طريقة الدفع الخاصة به، قم باستدعاء API تحديث طريقة الدفع:

    <CodeGroup>
      ```javascript Node.js theme={null}
      // Update with new payment method
      const response = await client.subscriptions.updatePaymentMethod(subscriptionId, {
        type: 'new',
        return_url: 'https://example.com/return'
      });

      // For on_hold subscriptions, a charge is automatically created
      if (response.payment_id) {
        console.log('Charge created for remaining dues:', response.payment_id);
        // Redirect customer to response.payment_link to complete payment
      }
      ```

      ```python Python theme={null}
      # Update with new payment method
      response = client.subscriptions.update_payment_method(
          subscription_id=subscription_id,
          type="new",
          return_url="https://example.com/return"
      )

      # For on_hold subscriptions, a charge is automatically created
      if response.payment_id:
          print("Charge created for remaining dues:", response.payment_id)
          # Redirect customer to response.payment_link to complete payment
      ```
    </CodeGroup>

    <Info>
      يمكنك أيضًا استخدام معرّف طريقة الدفع الحالية إذا كان لدى العميل طرق دفع محفوطة:

      ```javascript theme={null}
      await client.subscriptions.updatePaymentMethod(subscriptionId, {
        type: 'existing',
        payment_method_id: 'pm_abc123'
      });
      ```
    </Info>
  </Step>

  <Step title="Monitor webhook events">
    بعد تحديث طريقة الدفع، راقب هذه الأحداث في webhook:

    1. **`payment.succeeded`** - النجاح في شحن الديون المتبقية
    2. **`subscription.active`** - تم إعادة تنشيط الاشتراك

    ```javascript theme={null}
    if (event.type === 'payment.succeeded') {
      const payment = event.data;
      
      // Check if this payment is for an on_hold subscription
      if (payment.subscription_id) {
        // Wait for subscription.active webhook to confirm reactivation
      }
    }

    if (event.type === 'subscription.active') {
      const subscription = event.data;
      
      // Update subscription status in your database
      await updateSubscriptionStatus(subscription.subscription_id, 'active');
      
      // Restore customer access
      await restoreCustomerAccess(subscription.customer_id);
      
      // Notify customer of successful reactivation
      await sendEmailToCustomer(subscription.customer_id, {
        subject: 'Subscription Reactivated',
        message: 'Your subscription has been reactivated successfully.'
      });
    }
    ```
  </Step>
</Steps>

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

***

| الخاصية       | النوع  | مطلوب | الوصف                                                         |
| ------------- | ------ | ----- | ------------------------------------------------------------- |
| `business_id` | string | نعم   | المعرف الفريد للأعمال                                         |
| `timestamp`   | string | نعم   | الطابع الزمني عند حدوث الحدث (ليس بالضرورة نفسه وقت تسليمه)   |
| `type`        | string | نعم   | نوع الحدث. انظر [أنواع الأحداث](#event-types)                 |
| `data`        | object | نعم   | الحمولة الرئيسية للبيانات. انظر [كائن البيانات](#data-object) |

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

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

<Card title="Change Plan API Reference" icon="arrows-rotate" href="/api-reference/subscriptions/change-plan">
  لمزيد من المعلومات التفصيلية حول تغيير خطط الاشتراك، يُرجى الرجوع إلى وثائق API لتغيير الخطة.
</Card>

### خيارات التسعير المتناسب

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

#### 1. `prorated_immediately`

* يحسب المبلغ المتناسب بناءً على الوقت المتبقي في دورة الفوترة الحالية
* يخصم من العميل فقط الفرق بين الخطة القديمة والجديدة
* خلال فترة التجربة، سيتم نقل المستخدم مباشرة إلى الخطة الجديدة، مع تحصيل الرسوم من العميل في الحال

#### 2. `full_immediately`

* يخصم من العميل المبلغ الكامل للاشتراك للخطة الجديدة
* يتجاهل أي وقت متبقي أو ائتمانات من الخطة السابقة
* مفيد عند الرغبة في إعادة ضبط دورة الفوترة أو تحصيل المبلغ الكامل بغض النظر عن التسعير المتناسب

#### 3. `difference_immediately`

* عند الترقية، يتم خصم الفرق بين مبلغي الخطة على الفور من العميل.
* على سبيل المثال، إذا كانت الخطة الحالية 30 دولارًا وترقي العميل إلى 80 دولارًا، يتم خصم 50 دولارًا فورًا.
* عند التخفيض، يتم إضافة المبلغ غير المستخدم من الخطة الحالية كائتمان داخلي ويتم تطبيقه تلقائيًا على تجديدات الاشتراك المستقبلية.
* على سبيل المثال، إذا كانت الخطة الحالية 50 دولارًا وانتقل العميل إلى خطة 20 دولارًا، فإن المبلغ المتبقي 30 دولارًا يُضاف كائتمان ويُستخدم في دورة الفوترة التالية.

### السلوك

* عند استدعاء هذا API، يقوم Dodo Payments فورًا ببدء شحن استنادًا إلى خيار التسعير المتناسب المحدد
* إذا كان التغيير في الخطة خفضًا واستخدمت `prorated_immediately`، سيتم حساب الإئتمانات تلقائيًا وإضافتها إلى رصيد ائتمان الاشتراك. هذه الإئتمانات خاصة بذلك الاشتراك ولن تستخدم إلا لتعويض عمليات الدفع المتكررة المستقبلية لنفس الاشتراك
* خيار `full_immediately` يتجاوز حساب الإئتمانات ويخصم المبلغ الكامل للخطة الجديدة

<Tip>
  **اختر خيار التسعير المتناسب بعناية**: استخدم `prorated_immediately` للتسعير العادل الذي يُحسب الوقت غير المستخدم، أو `full_immediately` عندما تريد تحصيل المبلغ الكامل للخطة الجديدة بغض النظر عن دورة الفوترة الحالية.
</Tip>

### معالجة الشحن

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

## الاشتراكات حسب الطلب

<Info>
  تتيح لك الاشتراكات حسب الطلب تحصيل رسوم العملاء بمرونة، وليس فقط وفق جدول ثابت. تتوفر هذه الميزة لجميع الحسابات.
</Info>

**لإنشاء اشتراك حسب الطلب:**

لإنشاء اشتراك حسب الطلب، استخدم (POST /subscriptions)\[/api-reference/subscriptions/post-subscriptions] لنقطة نهاية API وقم بتضمين حقل `on_demand` في نص الطلب الخاص بك. يتيح لك هذا تفويض طريقة دفع بدون شحن فوري أو تحديد سعر بداية مخصص.

**لتحصيل رسوم اشتراك حسب الطلب:**

لإجراء شحنات لاحقة، استخدم نقطة النهاية [POST /subscriptions/{subscription_id}/charge](/api-reference/subscriptions/create-charge) وحدد المبلغ المراد خصمه من العميل لتلك المعاملة.

<Note>
  للحصول على دليل كامل خطوة بخطوة - بما في ذلك أمثلة الطلب/الاستجابة وسياسات المحاولة المأمونة ومعالجة webhook - راجع <a href="/developer-resources/ondemand-subscriptions">دليل الاشتراكات حسب الطلب</a>.
</Note>

## مرجع API ذو صلة

<CardGroup cols={2}>
  <Card title="Create Subscription" icon="code" href="/api-reference/subscriptions/post-subscriptions">
    مرجع API لإنشاء منتجات الاشتراك وإدارة دورة حياة الاشتراك
  </Card>

  <Card title="Change Subscription Plan" icon="arrows-rotate" href="/api-reference/subscriptions/change-plan">
    مرجع API لترقية أو تخفيض أو تغيير خطط الاشتراك مع خيارات التسعير المتناسب
  </Card>

  <Card title="Update Payment Method" icon="credit-card" href="/api-reference/subscriptions/update-payment-method">
    مرجع API لتحديث طرق الدفع وإعادة تنشيط الاشتراكات المعلقة
  </Card>

  <Card title="Patch Subscription" icon="pen" href="/api-reference/subscriptions/patch-subscriptions">
    مرجع API لتحديث تفاصيل الاشتراك والتكوين
  </Card>
</CardGroup>
