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

# Inngest

> قم بتشغيل الوظائف بدون خادم والمهام الخلفية في Inngest بناءً على أحداث مدفوعات Dodo.

## المقدمة

قم بتنفيذ الوظائف بدون خادم والمهام الخلفية تلقائيًا عند حدوث أحداث الدفع. قم بمعالجة المدفوعات، إرسال الإشعارات، تحديث قواعد البيانات، وتشغيل سير العمل المعقد باستخدام منصة تنفيذ الوظائف الموثوقة من Inngest.

<Info>
  يتطلب هذا التكامل عنوان ويب هوك الخاص بـ Inngest من تكوين الدالة الخاصة بك.
</Info>

## البدء

<Steps>
  <Step title="Open the Webhook Section">
    في لوحة تحكم Dodo Payments الخاصة بك، انتقل إلى <b>Webhooks → + Add Endpoint</b> وافتح قائمة الدمج المنسدلة.

    <Frame>
      <img src="https://mintcdn.com/dodopayments/slbAEdrLLwKHfaRf/images/integrations/inngest.png?fit=max&auto=format&n=slbAEdrLLwKHfaRf&q=85&s=b160678c00ceed38439160b4b253c8f3" alt="إضافة نقطة النهاية وقائمة الدمج المنسدلة" style={{ maxHeight: '500px', width: 'auto' }} width="1646" height="944" data-path="images/integrations/inngest.png" />
    </Frame>
  </Step>

  <Step title="Select Inngest">
    اختر بطاقة التكامل <b>Inngest</b>.
  </Step>

  <Step title="Create Inngest Function">
    في Inngest، أنشئ دالة جديدة وانسخ عنوان ويب هوك من تكوين الدالة.
  </Step>

  <Step title="Paste Webhook URL">
    ألصق عنوان ويب هوك Inngest في تكوين نقطة النهاية.
  </Step>

  <Step title="Configure Transformation">
    حرر شفرة التحويل لتنسيق الأحداث الخاصة بدالتك في Inngest.
  </Step>

  <Step title="Test & Create">
    اختبر باستخدام أحمال بيانات نموذجية ثم انقر على <b>إنشاء</b> لتفعيل التكامل.
  </Step>

  <Step title="Done!">
    🎉 ستؤدي الآن أحداث الدفع إلى تشغيل وظائف Inngest الخاصة بك تلقائيًا.
  </Step>
</Steps>

## أمثلة على كود التحويل

### حمولة حدث أساسية

```javascript basic_event.js icon="js" expandable theme={null}
function handler(webhook) {
  if (webhook.eventType === "payment.succeeded") {
    const p = webhook.payload.data;
    webhook.payload = {
      name: "payment.succeeded",
      data: {
        payment_id: p.payment_id,
        amount: (p.total_amount / 100).toFixed(2),
        currency: p.currency || "USD",
        customer_email: p.customer.email,
        customer_name: p.customer.name,
        payment_method: p.payment_method || "unknown"
      },
      user: {
        email: p.customer.email
      },
      ts: Math.floor(new Date(webhook.payload.timestamp).getTime() / 1000)
    };
  }
  return webhook;
}
```

### معالج حدث الاشتراك

```javascript subscription_event.js icon="js" expandable theme={null}
function handler(webhook) {
  const s = webhook.payload.data;
  switch (webhook.eventType) {
    case "subscription.active":
      webhook.payload = {
        name: "subscription.started",
        data: {
          subscription_id: s.subscription_id,
          customer_email: s.customer.email,
          customer_name: s.customer.name,
          product_id: s.product_id,
          amount: (s.recurring_pre_tax_amount / 100).toFixed(2),
          frequency: s.payment_frequency_interval,
          next_billing: s.next_billing_date
        },
        user: {
          email: s.customer.email
        },
        ts: Math.floor(new Date(webhook.payload.timestamp).getTime() / 1000)
      };
      break;
    case "subscription.cancelled":
      webhook.payload = {
        name: "subscription.cancelled",
        data: {
          subscription_id: s.subscription_id,
          customer_email: s.customer.email,
          cancelled_at: s.cancelled_at,
          cancel_at_next_billing: s.cancel_at_next_billing_date
        },
        user: {
          email: s.customer.email
        },
        ts: Math.floor(new Date(webhook.payload.timestamp).getTime() / 1000)
      };
      break;
  }
  return webhook;
}
```

### معالج حدث النزاع

```javascript dispute_event.js icon="js" expandable theme={null}
function handler(webhook) {
  if (webhook.eventType.startsWith("dispute.")) {
    const d = webhook.payload.data;
    webhook.payload = {
      name: webhook.eventType,
      data: {
        dispute_id: d.dispute_id,
        payment_id: d.payment_id,
        amount: (d.amount / 100).toFixed(2),
        status: d.dispute_status,
        stage: d.dispute_stage,
        remarks: d.remarks || "",
        urgent: webhook.eventType === "dispute.opened"
      },
      user: {
        email: d.customer?.email || "unknown"
      },
      ts: Math.floor(new Date(webhook.payload.timestamp).getTime() / 1000)
    };
  }
  return webhook;
}
```

## حالات استخدام Inngest الشائعة

<AccordionGroup>
  <Accordion title="Payment Processing">
    * إرسال رسائل تأكيد عبر البريد الإلكتروني
    * تحديث سجلات العملاء
    * معالجة عمليات الاسترداد
    * إنشاء فواتير
    * تحديث المخزون
  </Accordion>

  <Accordion title="Subscription Management">
    * ترحيب بالمشتركين الجدد
    * معالجة الإلغاءات
    * إرسال تذكيرات التجديد
    * تحديث دورات الفوترة
    * التعامل مع المدفوعات الفاشلة
  </Accordion>

  <Accordion title="Analytics & Reporting">
    * تحديث مؤشرات الإيرادات
    * تتبع سلوك العملاء
    * توليد التقارير
    * مزامنة البيانات مع منصات التحليلات
    * حساب معدلات التسرب
  </Accordion>
</AccordionGroup>

## نصائح

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

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

<AccordionGroup>
  <Accordion title="Functions not triggering">
    * تحقق من أن عنوان ويب هوك صحيح ونشط
    * تحقق من أن دالة Inngest منشورة ونشطة
    * تأكد من أن أسماء الأحداث تتطابق مع محفزات الدالة
    * راجع سجلات دالة Inngest بحثًا عن أخطاء
  </Accordion>

  <Accordion title="Data not received correctly">
    * تحقق من أن بنية الحمولة تتوافق مع توقعات Inngest
    * تحقق من أن أسماء الأحداث منسقة بشكل صحيح
    * تأكد من تضمين جميع الحقول المطلوبة
    * اختبر باستخدام أداة اختبار ويب هوك الخاصة بـ Inngest
  </Accordion>
</AccordionGroup>
