> ## 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.

# موصل إكسبريس

> تعلم كيفية دمج مدفوعات دودو مع مشروع موجه تطبيق إكسبريس الخاص بك باستخدام موصل إكسبريس. يغطي الدفع، بوابة العملاء، الويب هوكس، وإعداد البيئة الآمنة.

<CardGroup cols={2}>
  <Card title="Checkout Handler" icon="cart-shopping" href="#checkout-route-handler">
    قم بدمج صفحة دفع Dodo Payments في تطبيق Express الخاص بك.
  </Card>

  <Card title="Customer Portal" icon="user" href="#customer-portal-route-handler">
    اسمح للعملاء بإدارة الاشتراكات والتفاصيل.
  </Card>

  <Card title="Webhooks" icon="bell" href="#webhook-route-handler">
    استقبل وعاالج أحداث webhook الخاصة بـ Dodo Payments.
  </Card>
</CardGroup>

## التثبيت

<Steps>
  <Step title="Install the package">
    قم بتشغيل الأمر التالي في جذر المشروع الخاص بك:

    ```bash theme={null}
    npm install @dodopayments/express
    ```
  </Step>

  <Step title="Set up environment variables">
    قم بإنشاء ملف <code>.env</code> في جذر المشروع الخاص بك:

    ```env expandable theme={null}
    DODO_PAYMENTS_API_KEY=your-api-key
    DODO_PAYMENTS_WEBHOOK_KEY=your-webhook-secret
    DODO_PAYMENTS_ENVIRONMENT="test_mode" or "live_mode"
    DODO_PAYMENTS_RETURN_URL=your-return-url
    ```

    <Warning>
      لا تُدرِج ملف <code>.env</code> أو الأسرار في نظام التحكم بالإصدارات.
    </Warning>
  </Step>
</Steps>

## أمثلة معالجات المسار

<Tabs>
  <Tab title="Checkout Handler">
    <Info>
      استخدم هذه المعالجة لدمج صفحة دفع Dodo Payments في تطبيق Express الخاص بك. تدعم تدفقات الدفع الثابتة (GET) والديناميكية (POST) والجلسات (POST).
    </Info>

    <CodeGroup>
      ```typescript Express Route Handler expandable theme={null}
      import { checkoutHandler } from '@dodopayments/express';

      app.get('/api/checkout', checkoutHandler({
          bearerToken: process.env.DODO_PAYMENTS_API_KEY,
          returnUrl: process.env.DODO_PAYMENTS_RETURN_URL,
          environment: process.env.DODO_PAYMENTS_ENVIRONMENT,
          type: "static"
      }))

      app.post('/api/checkout', checkoutHandler({
          bearerToken: process.env.DODO_PAYMENTS_API_KEY,
          returnUrl: process.env.DODO_PAYMENTS_RETURN_URL,
          environment: process.env.DODO_PAYMENTS_ENVIRONMENT,
          type: "dynamic"
      }))

      app.post('/api/checkout', checkoutHandler({
          bearerToken: process.env.DODO_PAYMENTS_API_KEY,
          returnUrl: process.env.DODO_PAYMENTS_RETURN_URL,
          environment: process.env.DODO_PAYMENTS_ENVIRONMENT,
          type: "session"
      }))
      ```
    </CodeGroup>

    <CodeGroup>
      ```curl Static Checkout Curl example expandable theme={null}
      curl --request GET \
      --url 'https://example.com/api/checkout?productId=pdt_fqJhl7pxKWiLhwQR042rh' \
      --header 'User-Agent: insomnia/11.2.0' \
      --cookie mode=test
      ```
    </CodeGroup>

    <CodeGroup>
      ```curl Dynamic Checkout Curl example expandable theme={null}
      curl --request POST \
      --url https://example.com/api/checkout \
      --header 'Content-Type: application/json' \
      --header 'User-Agent: insomnia/11.2.0' \
      --cookie mode=test \
      --data '{
      "billing": {
        "city": "Texas",
        "country": "US",
        "state": "Texas",
        "street": "56, hhh",
        "zipcode": "560000"
      },
      "customer": {
        "email": "test@example.com",
        	"name": "test"
      },
      "metadata": {},
      "payment_link": true,
        "product_id": "pdt_QMDuvLkbVzCRWRQjLNcs",
        "quantity": 1,
        "billing_currency": "USD",
        "discount_codes": ["IKHZ23M9GQ"],
        "return_url": "https://example.com",
        "trial_period_days": 10
      }'
      ```
    </CodeGroup>

    <CodeGroup>
      ```curl Checkout Session Curl example expandable theme={null}
      curl --request POST \
      --url https://example.com/api/checkout \
      --header 'Content-Type: application/json' \
      --header 'User-Agent: insomnia/11.2.0' \
      --cookie mode=test \
      --data '{
      "product_cart": [
        {
          "product_id": "pdt_QMDuvLkbVzCRWRQjLNcs",
          "quantity": 1
        }
      ],
      "customer": {
        "email": "test@example.com",
        "name": "test"
      },
      "return_url": "https://example.com/success"
      }'
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Customer Portal Handler">
    <Info>
      استخدم هذه المعالجة للسماح للعملاء بإدارة اشتراكاتهم وتفاصيلهم عبر بوابة عملاء Dodo Payments.
    </Info>

    <CodeGroup>
      ```typescript Express Route Handler expandable theme={null}
      import { CustomerPortal } from "@dodopayments/express";

      app.get('/api/customer-portal', CustomerPortal({
          bearerToken: process.env.DODO_PAYMENTS_API_KEY,
          environment: process.env.DODO_PAYMENTS_ENVIRONMENT,
      }))
      ```
    </CodeGroup>

    <CodeGroup>
      ```curl Customer Portal Curl example expandable theme={null}
      curl --request GET \
      --url 'https://example.com/api/customer-portal?customer_id=cus_9VuW4K7O3GHwasENg31m&send_email=true' \
      --header 'User-Agent: insomnia/11.2.0' \
      --cookie mode=test
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Webhook Handler">
    <Info>
      استخدم هذه المعالجة لاستقبال ومعالجة أحداث webhook الخاصة بـ Dodo Payments بأمان في تطبيق Express الخاص بك.
    </Info>

    <CodeGroup>
      ```typescript Express Route Handler expandable theme={null}
      import { Webhooks } from "@dodopayments/express";

      app.post('/api/webhook',Webhooks({
          webhookKey: process.env.DODO_PAYMENTS_WEBHOOK_KEY,
          onPayload: async (payload) => {
              // handle the payload
          },
          // ... other event handlers for granular control
      }))
      ```
    </CodeGroup>
  </Tab>
</Tabs>

## معالج مسار الدفع

<Info>
  تدعم Dodo Payments ثلاثة أنواع من تدفقات الدفع لدمج المدفوعات في موقعك، ويدعم هذا الموصل جميع أنواع تدفقات الدفع.
</Info>

* **روابط الدفع الثابتة:** روابط قابلة للمشاركة على الفور لجمع المدفوعات بسرعة وبدون كود.
* **روابط الدفع الديناميكية:** توليد روابط دفع برمجياً مع تفاصيل مخصصة باستخدام API أو SDKs.
* **جلسات الدفع:** إنشاء تجارب دفع آمنة وقابلة للتخصيص مع عربات منتجات مُعدة مسبقاً وتفاصيل العملاء.

<AccordionGroup>
  <Accordion title="Static Checkout (GET)">
    ### معلمات الاستعلام

    <ParamField query="productId" type="string" required>
      معرّف المنتج (مثلاً <code>?productId=pdt\_nZuwz45WAs64n3l07zpQR</code>).
    </ParamField>

    <ParamField query="quantity" type="integer">
      كمية المنتج.
    </ParamField>

    <ParamField query="fullName" type="string">
      الاسم الكامل للعميل.
    </ParamField>

    <ParamField query="firstName" type="string">
      الاسم الأول للعميل.
    </ParamField>

    <ParamField query="lastName" type="string">
      اسم العائلة للعميل.
    </ParamField>

    <ParamField query="email" type="string">
      البريد الإلكتروني للعميل.
    </ParamField>

    <ParamField query="country" type="string">
      بلد العميل.
    </ParamField>

    <ParamField query="addressLine" type="string">
      سطر عنوان العميل.
    </ParamField>

    <ParamField query="city" type="string">
      مدينة العميل.
    </ParamField>

    <ParamField query="state" type="string">
      الولاية/المقاطعة الخاصة بالعميل.
    </ParamField>

    <ParamField query="zipCode" type="string">
      الرمز البريدي/البريدي الخاص بالعميل.
    </ParamField>

    <ParamField query="disableFullName" type="boolean">
      تعطيل حقل الاسم الكامل.
    </ParamField>

    <ParamField query="disableFirstName" type="boolean">
      تعطيل حقل الاسم الأول.
    </ParamField>

    <ParamField query="disableLastName" type="boolean">
      تعطيل حقل اسم العائلة.
    </ParamField>

    <ParamField query="disableEmail" type="boolean">
      تعطيل حقل البريد الإلكتروني.
    </ParamField>

    <ParamField query="disableCountry" type="boolean">
      تعطيل حقل البلد.
    </ParamField>

    <ParamField query="disableAddressLine" type="boolean">
      تعطيل حقل سطر العنوان.
    </ParamField>

    <ParamField query="disableCity" type="boolean">
      تعطيل حقل المدينة.
    </ParamField>

    <ParamField query="disableState" type="boolean">
      تعطيل حقل الولاية.
    </ParamField>

    <ParamField query="disableZipCode" type="boolean">
      تعطيل حقل الرمز البريدي.
    </ParamField>

    <ParamField query="paymentCurrency" type="string">
      حدد عملة الدفع (مثلاً <code>USD</code>).
    </ParamField>

    <ParamField query="showCurrencySelector" type="boolean">
      عرض محدد العملة.
    </ParamField>

    <ParamField query="paymentAmount" type="integer">
      حدد مبلغ الدفع (مثلاً <code>1000</code> مقابل 10.00\$).
    </ParamField>

    <ParamField query="showDiscounts" type="boolean">
      عرض حقول الخصم.
    </ParamField>

    <ParamField query="metadata_*" type="string">
      سيتم تمرير أي معلمة استعلام تبدأ بـ <code>metadata\_</code> كبيانات وصفية.
    </ParamField>

    <Warning>
      إذا كان <code>productId</code> مفقودًا، تعيد المعالجة استجابة 400. تؤدي معلمات الاستعلام غير الصالحة أيضًا إلى استجابة 400.
    </Warning>

    ### تنسيق الاستجابة

    يرجع الدفع الثابت استجابة JSON مع عنوان URL للدفع:

    ```json theme={null}
    {
      "checkout_url": "https://checkout.dodopayments.com/..."
    }
    ```
  </Accordion>

  <Accordion title="Dynamic Checkout (POST)">
    * أرسل المعلمات كجسم JSON في طلب POST.
    * يدعم كل من المدفوعات لمرة واحدة والمتكررة.
    * للحصول على القائمة الكاملة لحقول جسم POST المدعومة، راجع:
      * [Request body for a One Time Payment Product](https://docs.dodopayments.com/api-reference/payments/post-payments)
      * [Request body for a Subscription Product](https://docs.dodopayments.com/api-reference/subscriptions/post-subscriptions)

    ### تنسيق الاستجابة

    يرجع الدفع الديناميكي استجابة JSON مع عنوان URL للدفع:

    ```json theme={null}
    {
      "checkout_url": "https://checkout.dodopayments.com/..."
    }
    ```
  </Accordion>

  <Accordion title="Checkout Sessions (POST)">
    توفر جلسات الخروج تجربة دفع مُستضافة أكثر أمانًا تتعامل مع تدفق الدفع الكامل لكل من عمليات الشراء لمرة واحدة والاشتراكات مع تحكم كامل في التخصيص.

    راجع [دليل دمج جلسات الدفع](https://docs.dodopayments.com/developer-resources/checkout-session) لمزيد من التفاصيل وقائمة كاملة من الحقول المدعومة.

    ### تنسيق الاستجابة

    ترجع جلسات الدفع استجابة JSON مع عنوان URL للدفع:

    ```json theme={null}
    {
      "checkout_url": "https://checkout.dodopayments.com/session/..."
    }
    ```
  </Accordion>
</AccordionGroup>

## معالج مسار بوابة العملاء

يمكنك من خلال معالج مسار بوابة العملاء دمج بوابة عملاء مدفوعات دودو بسلاسة في تطبيق إكسبريس الخاص بك.

### معلمات الاستعلام

<ParamField query="customer_id" type="string" required>
  معرّف العميل لجلسة البوابة (مثلاً <code>?customer\_id=cus\_123</code>).
</ParamField>

<ParamField query="send_email" type="boolean">
  إذا تم تعيينه إلى <code>true</code>، يُرسل بريدًا إلكترونيًا إلى العميل يتضمن رابط البوابة.
</ParamField>

<Warning>
  تعيد 400 إذا كان <code>customer\_id</code> مفقودًا.
</Warning>

## معالج مسار الويب هوك

* **الطريقة:** يتم دعم طلبات POST فقط. الطلبات الأخرى ترجع 405.
* **التحقق من التوقيع:** يتحقق من توقيع الويب هوك باستخدام <code>webhookKey</code>. يرجع 401 إذا فشل التحقق.
* **التحقق من الحمولة:** يتم التحقق منها باستخدام Zod. يرجع 400 للحمولات غير الصحيحة.
* **معالجة الأخطاء:**
  * 401: توقيع غير صالح
  * 400: حمولة غير صالحة
  * 500: خطأ داخلي أثناء التحقق
* **توجيه الأحداث:** يستدعي المعالج المناسب بناءً على نوع الحمولة.

### معالجات أحداث Webhook المدعومة

<CodeGroup>
  ```typescript Typescript expandable theme={null}
  onPayload?: (payload: WebhookPayload) => Promise<void>;
  onPaymentSucceeded?: (payload: WebhookPayload) => Promise<void>;
  onPaymentFailed?: (payload: WebhookPayload) => Promise<void>;
  onPaymentProcessing?: (payload: WebhookPayload) => Promise<void>;
  onPaymentCancelled?: (payload: WebhookPayload) => Promise<void>;
  onRefundSucceeded?: (payload: WebhookPayload) => Promise<void>;
  onRefundFailed?: (payload: WebhookPayload) => Promise<void>;
  onDisputeOpened?: (payload: WebhookPayload) => Promise<void>;
  onDisputeExpired?: (payload: WebhookPayload) => Promise<void>;
  onDisputeAccepted?: (payload: WebhookPayload) => Promise<void>;
  onDisputeCancelled?: (payload: WebhookPayload) => Promise<void>;
  onDisputeChallenged?: (payload: WebhookPayload) => Promise<void>;
  onDisputeWon?: (payload: WebhookPayload) => Promise<void>;
  onDisputeLost?: (payload: WebhookPayload) => Promise<void>;
  onSubscriptionActive?: (payload: WebhookPayload) => Promise<void>;
  onSubscriptionOnHold?: (payload: WebhookPayload) => Promise<void>;
  onSubscriptionRenewed?: (payload: WebhookPayload) => Promise<void>;
  onSubscriptionPlanChanged?: (payload: WebhookPayload) => Promise<void>;
  onSubscriptionCancelled?: (payload: WebhookPayload) => Promise<void>;
  onSubscriptionFailed?: (payload: WebhookPayload) => Promise<void>;
  onSubscriptionExpired?: (payload: WebhookPayload) => Promise<void>;
  onSubscriptionUpdated?: (payload: WebhookPayload) => Promise<void>;
  onLicenseKeyCreated?: (payload: WebhookPayload) => Promise<void>;
  onAbandonedCheckoutDetected?: (payload: WebhookPayload) => Promise<void>;
  onAbandonedCheckoutRecovered?: (payload: WebhookPayload) => Promise<void>;
  onDunningStarted?: (payload: WebhookPayload) => Promise<void>;
  onDunningRecovered?: (payload: WebhookPayload) => Promise<void>;
  onCreditAdded?: (payload: WebhookPayload) => Promise<void>;
  onCreditDeducted?: (payload: WebhookPayload) => Promise<void>;
  onCreditExpired?: (payload: WebhookPayload) => Promise<void>;
  onCreditRolledOver?: (payload: WebhookPayload) => Promise<void>;
  onCreditRolloverForfeited?: (payload: WebhookPayload) => Promise<void>;
  onCreditOverageCharged?: (payload: WebhookPayload) => Promise<void>;
  onCreditManualAdjustment?: (payload: WebhookPayload) => Promise<void>;
  onCreditBalanceLow?: (payload: WebhookPayload) => Promise<void>;
  ```
</CodeGroup>

***

## موجه لـ LLM

```
أنت مساعد خبير في تطوير إكسبريس.js. مهمتك هي إرشاد المستخدم خلال دمج موصل @dodopayments/express في مشروع إكسبريس.js الحالي الخاص به.

يوفر موصل @dodopayments/express معالجات مسار لمدفوعات دودو للدفع، بوابة العملاء، ووظائف الويب هوك، مصممة لتتصل مباشرة بتطبيق إكسبريس.

أولاً، قم بتثبيت الحزمة اللازمة. استخدم مدير الحزم المناسب لمشروع المستخدم (npm، yarn، أو bun):

npm install @dodopayments/express

---

إليك كيفية هيكلة ردك:

1. اسأل المستخدم عن الوظائف التي يريد دمجها.

"أي أجزاء من موصل @dodopayments/express ترغب في دمجها في مشروعك؟ يمكنك اختيار واحد أو أكثر من الخيارات التالية:

- معالج مسار الدفع (للتعامل مع عمليات الدفع للمنتجات)
- معالج مسار بوابة العملاء (لإدارة اشتراكات/تفاصيل العملاء)
- معالج مسار الويب هوك (لاستلام أحداث الويب هوك لمدفوعات دودو)
- الكل (دمج الثلاثة)"

---

2. بناءً على اختيار المستخدم، قدم خطوات دمج مفصلة لكل وظيفة مختارة.

---

**إذا تم اختيار معالج مسار الدفع:**

**الغرض**: يدير هذا المعالج أنواع مختلفة من تدفقات الدفع. جميع أنواع الدفع (ثابت، ديناميكي، وجلسات) ترجع استجابات JSON مع عناوين URL للدفع للتعامل البرمجي.

**الدمج**:
قم بإنشاء مسارات في تطبيق إكسبريس الخاص بك للدفع الثابت (GET)، الديناميكي (POST)، وجلسات الدفع (POST).

import { checkoutHandler } from '@dodopayments/express';

app.get('/api/checkout', checkoutHandler({
  bearerToken: process.env.DODO_PAYMENTS_API_KEY,
  returnUrl: process.env.DODO_PAYMENTS_RETURN_URL,
  environment: process.env.DODO_PAYMENTS_ENVIRONMENT,
  type: "static"
}));

app.post('/api/checkout', checkoutHandler({
  bearerToken: process.env.DODO_PAYMENTS_API_KEY,
  returnUrl: process.env.DODO_PAYMENTS_RETURN_URL,
  environment: process.env.DODO_PAYMENTS_ENVIRONMENT,
  type: "dynamic"
}));

// لجلسات الدفع
app.post('/api/checkout', checkoutHandler({
  bearerToken: process.env.DODO_PAYMENTS_API_KEY,
  returnUrl: process.env.DODO_PAYMENTS_RETURN_URL,
  environment: process.env.DODO_PAYMENTS_ENVIRONMENT,
  type: "session"
}));

خيارات التكوين:

    bearerToken: مفتاح API لمدفوعات دودو (يوصى بتخزينه في متغير البيئة DODO_PAYMENTS_API_KEY).

    returnUrl (اختياري): عنوان URL لإعادة توجيه المستخدم بعد الدفع الناجح.

    environment: "test_mode" أو "live_mode"

    type: "static" (GET)، "dynamic" (POST)، أو "session" (POST)

يتوقع GET (الدفع الثابت) معلمات استعلام:

    productId (مطلوب)

    الكمية، حقول العميل (fullName، email، إلخ)، والبيانات الوصفية (metadata_*) اختيارية.

    يرجع: `{"checkout_url": "https://checkout.dodopayments.com/..."}`

يتوقع POST (الدفع الديناميكي) جسم JSON مع تفاصيل الدفع (لمرة واحدة أو اشتراك). راجع الوثائق للحصول على مخطط POST الكامل:

    المدفوعات لمرة واحدة: https://docs.dodopayments.com/api-reference/payments/post-payments

    الاشتراكات: https://docs.dodopayments.com/api-reference/subscriptions/post-subscriptions

    يرجع: `{"checkout_url": "https://checkout.dodopayments.com/..."}`

POST (جلسات الدفع) - (موصى به) تجربة دفع أكثر تخصيصًا. ترجع JSON مع checkout_url: يتم إرسال المعلمات كجسم JSON. يدعم كل من المدفوعات لمرة واحدة والمدفوعات المتكررة. يرجع: `{"checkout_url": "https://checkout.dodopayments.com/session/..."}`. للحصول على قائمة كاملة من الحقول المدعومة، راجع:

  دليل دمج جلسات الدفع: https://docs.dodopayments.com/developer-resources/checkout-session

إذا تم اختيار معالج مسار بوابة العملاء:

الغرض: يتيح هذا المسار للعملاء إدارة اشتراكاتهم عبر بوابة مدفوعات دودو.

الدمج:

import { CustomerPortal } from "@dodopayments/express";

app.get('/api/customer-portal', CustomerPortal({
  bearerToken: process.env.DODO_PAYMENTS_API_KEY,
  environment: process.env.DODO_PAYMENTS_ENVIRONMENT,
}));

معلمات الاستعلام:

    customer_id (مطلوب): على سبيل المثال، ?customer_id=cus_123

    send_email (اختياري): إذا كان صحيحًا، يتم إرسال بريد إلكتروني للعميل برابط البوابة

يرجع 400 إذا كانت customer_id مفقودة.

إذا تم اختيار معالج مسار الويب هوك:

الغرض: يعالج أحداث الويب هوك الواردة من مدفوعات دودو لتفعيل الأحداث في تطبيقك.

الدمج:

import { Webhooks } from "@dodopayments/express";

app.post('/api/webhook', Webhooks({
  webhookKey: process.env.DODO_PAYMENTS_WEBHOOK_KEY,
  onPayload: async (payload) => {
    // التعامل مع الحمولة العامة
  },
  // يمكنك أيضًا توفير معالجات دقيقة لكل نوع حدث أدناه
}));

الميزات:

    يُسمح فقط بطريقة POST - الأخرى ترجع 405

    يتم إجراء التحقق من التوقيع باستخدام webhookKey. يرجع 401 إذا كان غير صالح.

    تحقق من الحمولة المعتمد على Zod. يرجع 400 إذا كان المخطط غير صالح.

    جميع المعالجات هي وظائف غير متزامنة.

معالجات أحداث الويب هوك المدعومة:

يمكنك تمرير أي من المعالجات التالية:

    onPayload

    onPaymentSucceeded

    onPaymentFailed

    onPaymentProcessing

    onPaymentCancelled

    onRefundSucceeded

    onRefundFailed

    onDisputeOpened، onDisputeExpired، onDisputeAccepted، onDisputeCancelled، onDisputeChallenged، onDisputeWon، onDisputeLost

    onSubscriptionActive, onSubscriptionOnHold, onSubscriptionRenewed, onSubscriptionPlanChanged, onSubscriptionCancelled, onSubscriptionFailed, onSubscriptionExpired, onSubscriptionUpdated

    onLicenseKeyCreated

    onAbandonedCheckoutDetected, onAbandonedCheckoutRecovered

    onDunningStarted, onDunningRecovered

    onCreditAdded, onCreditDeducted, onCreditExpired, onCreditRolledOver, onCreditRolloverForfeited, onCreditOverageCharged, onCreditManualAdjustment, onCreditBalanceLow

إعداد متغير البيئة:

تأكد من تعريف هذه المتغيرات البيئية في مشروعك:

DODO_PAYMENTS_API_KEY=your-api-key
DODO_PAYMENTS_WEBHOOK_KEY=your-webhook-secret
DODO_PAYMENTS_ENVIRONMENT="test_mode" or "live_mode"
DODO_PAYMENTS_RETURN_URL=your-return-url

استخدمها داخل الكود الخاص بك كالتالي:

process.env.DODO_PAYMENTS_API_KEY
process.env.DODO_PAYMENTS_WEBHOOK_SECRET

ملاحظة أمان: لا تقم بتضمين الأسرار في التحكم بالإصدارات. استخدم ملفات .env محليًا ومديري الأسرار في بيئات النشر (مثل AWS، Vercel، Heroku، إلخ).
```
