# مرجع الأحداث (/ar/integrate/webhooks/event-reference)

كل حدث webhook ممكن XPay يبعتهولك، إمتى بيتطلق، والكائن اللي بيحمله.

الأحداث هي الطريقة اللي بيها XPay بيقولّك إن حاجة حصلت على السيرفر بتاعك: دفعة نجحت، أو مبلغ اترد، أو عميل اتعمل. كل حدث بيوصل لنقطتك بيشترك في نفس غلاف الـ JSON؛ اللي بيتغير هو قيمة `type` والمورد اللي جوّه `data.object`.

الصفحة دي هي القائمة الرسمية للأحداث اللي تقدر تشترك فيها. علشان تعرف خطوات الاشتراك بالضغط، شوف [إعداد نقطة نهاية](/integrate/webhooks/setting-up-an-endpoint). وعلشان كود التحقق، شوف [التحقق من التوقيعات](/integrate/webhooks/verifying-signatures).

## غلاف الحدث [#غلاف-الحدث]

كل تسليم webhook ليه نفس الشكل العام:

```json
{
  "id": "evt_test_AbC123...",
  "object": "event",
  "api_version": "3.1.0",
  "created": "2026-05-01T12:00:00.000Z",
  "type": "checkout.session.completed",
  "livemode": false,
  "data": {
    "object": { "id": "cs_test_...", "object": "checkout.session" }
  }
}
```

| الحقل         | النوع           | المعنى                                                                                                                                                                                                            |
| ------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`          | string          | معرّف الحدث، ببادئة `evt_test_*` أو `evt_live_*`. ثابت عبر كل محاولات الإعادة. استخدمه كمفتاح عدم التكرار (idempotency).                                                                                          |
| `object`      | string          | دايمًا `"event"`.                                                                                                                                                                                                 |
| `api_version` | string          | نسخة الـ API المستخدمة في تكوين `data.object`.                                                                                                                                                                    |
| `created`     | ISO 8601 string | وقت تسجيل الحدث لأول مرة.                                                                                                                                                                                         |
| `type`        | string          | نوع الحدث (شوف الجداول تحت).                                                                                                                                                                                      |
| `livemode`    | boolean         | `true` لأحداث الحساب الفعلي، و`false` لأحداث وضع الاختبار.                                                                                                                                                        |
| `data.object` | object          | المورد اللي الحدث بيخصّه. نفس شكل `GET /<resource>/:id` بالظبط.                                                                                                                                                   |
| `request`     | object \| null  | طلب الـ API اللي أنشأ الحدث: `{ id, idempotency_key }`. القيمة `request.idempotency_key` هي الـ `Idempotency-Key` اللي بعتّه في الطلب ده (شوف [عدم التكرار](/integrate/idempotency))، أو `null` لو ما بعتّش واحد. |

الـ `data.object` مطابق تمامًا للي بيرجعهولك الـ GET endpoint المقابل. لو تقدر تقرا Checkout Session من `GET /checkout/sessions/:id`، يبقى معالِج `checkout.session.completed` بتاعك يقدر يقرا نفس الحقول بنفس الأسماء من `data.object`.

## أحداث جلسة الدفع (Checkout Session) [#أحداث-جلسة-الدفع-checkout-session]

بتتطلق على مراحل حياة <ApiLink href="/api-reference/objects/checkout-session">جلسة الدفع</ApiLink>. دي الأحداث اللي معظم عمليات الدمج بتعتمد عليها.

| الحدث                        | بيتطلق لما                                                          | `data.object`                                                                |
| ---------------------------- | ------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| `checkout.session.completed` | دفعة العميل على الجلسة تنجح. حالة الجلسة `status` بتبقى `complete`. | <ApiLink href="/api-reference/objects/checkout-session">جلسة الدفع</ApiLink> |

اشترك في `checkout.session.completed` علشان تنفّذ الطلب. الحمولة بتحمل الـ `paymentIntent` والـ `customer` والـ `lineItems` بعد ما اتحلّوا، فحدث واحد بيكفي معظم منطق تنفيذ الطلبات. والـ `lineItems` بيسرد بس اللي العميل اشتراه؛ والإضافات الاختيارية اللي ماضافهاش مش متضمّنة.

## أحداث الـ Charge [#أحداث-الـ-charge]

بتتطلق على مراحل حياة الـ <ApiLink href="/api-reference/objects/charge">Charge</ApiLink>. الـ Charge هو محاولة واحدة لتحريك فلوس على وسيلة دفع العميل. الدفعة الناجحة بتنتج Charge واحد؛ والعميل اللي أعاد المحاولة بعد رفض بينتج كذا واحد.

| الحدث              | بيتطلق لما                                                                                                                                                              | `data.object`                                                  |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
| `charge.succeeded` | الـ Charge يتحصّل بنجاح. بيتطلق قبل `checkout.session.completed` في دفعات الدفع المستضاف.                                                                               | <ApiLink href="/api-reference/objects/charge">Charge</ApiLink> |
| `charge.failed`    | محاولة الـ Charge تفشل. بيحمل `failureCode` و`failureMessage` بيوصّفوا السبب.                                                                                           | <ApiLink href="/api-reference/objects/charge">Charge</ApiLink> |
| `charge.refunded`  | استرداد ناجح (كامل أو جزئي) يتطبّق على الـ Charge. المبلغ المسترد بيبقى في `amountRefunded`. ومصفوفة `refunds.data` بتاعت الـ Charge بتحمل كل استرداد اتعمل لحد دلوقتي. | <ApiLink href="/api-reference/objects/charge">Charge</ApiLink> |

استخدم أحداث `charge.*` لو نموذج البيانات بتاعك بيتتبّع الفلوس على مستوى الـ charge (زي الحالات اللي فيها أكتر من تحصيل، أو دفعات معادة). لمعظم عمليات الدمج، الاستماع لـ `checkout.session.completed` و`refund.*` بيكفي.

## أحداث الاسترداد (Refund) [#أحداث-الاسترداد-refund]

بتتطلق على مراحل حياة الـ <ApiLink href="/api-reference/objects/refund">Refund</ApiLink>.

| الحدث            | بيتطلق لما                                           | `data.object`                                                  |
| ---------------- | ---------------------------------------------------- | -------------------------------------------------------------- |
| `refund.created` | سجل Refund جديد يتعمل.                               | <ApiLink href="/api-reference/objects/refund">Refund</ApiLink> |
| `refund.failed`  | محاولة استرداد تفشل. حالة الـ Refund بتبقى `failed`. | <ApiLink href="/api-reference/objects/refund">Refund</ApiLink> |

الأحداث دي بتتطلق على المبالغ المستردة سواء اتعملت عن طريق الـ API أو من لوحة التحكم. شوف [المبالغ المستردة](/integrate/refunds) لمسار الـ API.

الحدث `charge.refunded` (فوق) بيحمل الـ Charge الأب والـ Refund الجديد متضمَّن جوّه `refunds.data`، فتقدر تبني تنفيذ الطلب على أي جنب على حسب الكيان اللي نموذج بياناتك بيتتبّعه.

## أحداث العميل (Customer) [#أحداث-العميل-customer]

بتتطلق على مراحل حياة الـ <ApiLink href="/api-reference/objects/customer">Customer</ApiLink>.

| الحدث              | بيتطلق لما                                       | `data.object`                                                      |
| ------------------ | ------------------------------------------------ | ------------------------------------------------------------------ |
| `customer.created` | سجل عميل يتعمل (عن طريق الـ API أو لوحة التحكم). | <ApiLink href="/api-reference/objects/customer">Customer</ApiLink> |
| `customer.updated` | خصائص سجل عميل تتغير.                            | <ApiLink href="/api-reference/objects/customer">Customer</ApiLink> |
| `customer.deleted` | سجل عميل يتحذف.                                  | <ApiLink href="/api-reference/objects/customer">Customer</ApiLink> |

علشان تعرف الفرق بين العميل المسجَّل والعميل الضيف، وإزاي مطابقة الضيوف بتشتغل، شوف [دورة حياة العميل](/integrate/checkout-session/customer-lifecycle).

## مراقبة الـ Webhook [#مراقبة-الـ-webhook]

لما تسليم معيّن يستنفد كل محاولات الإعادة، XPay بيبعت إيميل لملّاك الحساب والمسؤولين والمطوّرين. الإيميل بيذكر رابط النقطة ونوع الحدث اللي ما اتسلّمش، علشان تعرف أنهي عملية دمج تبصّ عليها. التنبيهات دي بتغطّي تسليمات الحساب الفعلي بس. الفشل بيوصلك بإيميل مش بـ webhook عن قصد، لأن webhook لنقطة معطّلة هيفشل هو كمان.

علشان تعرف جدول الإعادة اللي ورا التنبيه ده، وإزاي تعيد إرسال تسليم بعد ما تصلّح المعالِج، شوف [إعادة الإرسال والمحاولات](/integrate/webhooks/replaying-and-retries).

## الترتيب على دفعة ناجحة [#الترتيب-على-دفعة-ناجحة]

الدفعة الواحدة بتطلق أكتر من حدث. بيوصلوا قريبين من بعض، بس مش بالضرورة بالترتيب؛ تعامل مع كل حدث على إنه مستقل، واعمل إزالة تكرار على `event.id`.

| الترتيب | الحدث                        | ليه                                          |
| ------- | ---------------------------- | -------------------------------------------- |
| 1       | `charge.succeeded`           | الفلوس اتحركت.                               |
| 2       | `checkout.session.completed` | الجلسة بقت `complete`. ده ميعاد تنفيذ الطلب. |

وفي حالة الاسترداد:

| الترتيب | الحدث             | ليه                                                  |
| ------- | ----------------- | ---------------------------------------------------- |
| 1       | `refund.created`  | سجل Refund اتعمل.                                    |
| 2       | `charge.refunded` | قيمة `amountRefunded` بتاعت الـ Charge الأب اتحدّثت. |

مش لازم تستمع لكلهم. اختار الأحداث اللي نموذج بياناتك محتاجها وتجاهل الباقي.

## قراءة `data.object` [#قراءة-dataobject]

حقل `data.object` بنفس الشكل اللي كنت هتاخده من الـ GET endpoint المطابق. ما تروحش تستدعي الـ API علشان تجيب المورد تاني بعد ما توصلك حدثه؛ الحمولة فيها كل حاجة النقطة دي كانت هترجّعها أصلًا.

علشان الشكل الرسمي لكل مورد، شوف صفحات الكائنات في مرجع الـ API:

* <ApiLink href="/api-reference/objects/checkout-session">
    Checkout Session
  </ApiLink>
* <ApiLink href="/api-reference/objects/payment-intent">
    Payment Intent
  </ApiLink>
* <ApiLink href="/api-reference/objects/charge">
    Charge
  </ApiLink>
* <ApiLink href="/api-reference/objects/refund">
    Refund
  </ApiLink>
* <ApiLink href="/api-reference/objects/customer">
    Customer
  </ApiLink>

علشان تعرف إزاي الموارد دي بتتركّب مع بعض (وأنهي معرّفات تحتفظ بيها في سجل الطلب بتاعك)، شوف [نموذج الكائنات](/integrate/object-model).

## تذكير بعدم التكرار [#تذكير-بعدم-التكرار]

كل حدث ممكن يتسلّم أكتر من مرة: XPay بيعيد المحاولة لما يرجع رد غير 2xx، وممكن تعيد الإرسال يدويًا من الـ Workbench، والرد الناجح اللي ما وصلش لـ XPay بينتج نسخة مكررة. استخدم `event.id` كمفتاح إزالة التكرار في المعالِج بتاعك.

علشان النمط الكامل، شوف [التحقق من التوقيعات ← عدم التكرار](/integrate/webhooks/verifying-signatures#عدم-التكرار).

## رايح فين بعد كده [#رايح-فين-بعد-كده]

<Cards>
  <Card icon="<Cable />" title="إعداد نقطة نهاية" href="/integrate/webhooks/setting-up-an-endpoint">
    ضيف نقطة، اختار الأحداث، وانسخ سر التوقيع.
  </Card>

  <Card icon="<ShieldCheck />" title="التحقق من التوقيعات" href="/integrate/webhooks/verifying-signatures">
    كود التحقق بـ HMAC-SHA256 ونمط عدم التكرار.
  </Card>

  <Card icon="<RefreshCw />" title="إعادة الإرسال والمحاولات" href="/integrate/webhooks/replaying-and-retries">
    جدول إعادة المحاولة التلقائي، إعادة الإرسال اليدوي، ودورة حياة التسليم.
  </Card>

  <Card icon="<Terminal />" title="التطوير المحلي" href="/integrate/webhooks/local-development">
    حوّل التسليمات لجهازك وأنت بتبني المعالِج.
  </Card>

  <Card icon="<Network />" title="نموذج الكائنات" href="/integrate/object-model">
    إزاي جلسة الدفع، وPayment Intent، وCharge، وRefund، والعميل بيرتبطوا.
  </Card>
</Cards>