التوثيق
الدمجWebhooks

إعادة الإرسال والمحاولات

إزاي XPay بيعيد المحاولة تلقائيًا على التسليمات اللي فشلت، وإزاي تعيد إرسال حدث يدويًا من الـ Workbench.

تسليم الـ webhook ممكن يوصل لنقطتك أكتر من مرة لسببين مختلفين. XPay بيعيد المحاولة تلقائيًا لما المعالِج بتاعك يرجع رد غير 2xx أو يخلص وقته. وتقدر تعيد الإرسال يدويًا بنفسك من الـ Workbench لما تحتاج تصلّح خطأ في المعالِج وتغذّيه بالحدث تاني. الاتنين بيوصلوا كطلبات POST عادية المُتحقق بتاعك بيتعامل معاها أصلًا؛ الفرق هو مين اللي بدأها.

المحاولات التلقائية

التسليم بيتعدّ "فاشل" لو حصل أي واحدة من دي:

  • المعالِج بتاعك يرجع رد HTTP غير 2xx.
  • المعالِج بتاعك ما يردّش خلال 30 ثانية في المحاولة الواحدة.
  • اتصال الـ TCP يفشل (DNS، رفض، إعادة تعيين، خطأ TLS).

لما محاولة تفشل، XPay بيجدول اللي بعديها وبيكمّل لحد ما تنجح أو تخلص المحاولات. الجدول بيعتمد على الوضع اللي الحدث اتعمل فيه. الحساب الفعلي بيعيد المحاولة على مدى أطول بكتير من وضع الاختبار، علشان النقطة اللي بتواجه العملاء وبتقع لفترة قصيرة تستلم الحدث بمجرد ما ترجع تشتغل.

الحساب الفعلي بيعيد المحاولة 13 مرة على مدى حوالي 3 أيام. والفرق بين المحاولات بيكبر كل ما الفشل يستمر.

المحاولةبتتطلق بعد المحاولة اللي قبلها بـ
1على طول
2دقيقة
35 دقايق
430 دقيقة
5ساعة
6ساعتين
74 ساعات
88 ساعات
من 9 لـ 1312 ساعة لكل واحدة

وضع الاختبار بيعيد المحاولة 5 مرات على مدى حوالي ساعتين و35 دقيقة، علشان تشوف مسار الفشل كامل بسرعة وأنت بتختبر.

المحاولةبتتطلق بعد المحاولة اللي قبلها بـ
1على طول
2دقيقة
35 دقايق
430 دقيقة
5ساعتين

التسليم بينجح على أول رد 2xx. بمجرد ما محاولة واحدة ترجع 2xx، التسليم بيبقى succeeded وما بيحصلش محاولات إعادة بعدها، حتى لو رجّعت بعدين خطأ على نسخة مكررة.

إمتى XPay بيستسلم

بعد ما المحاولة الأخيرة تفشل (التلاتة عشر في الحساب الفعلي، أو الخامسة في وضع الاختبار)، حالة التسليم بتبقى failed.

لما تسليم يستنفد كل المحاولات على نقطة سليمة في باقي الأحوال، XPay بيبعت إيميل لملّاك حسابك والمسؤولين والمطوّرين في الحساب الفعلي علشان تصلّحه أو تعيد إرساله. الإيميل بيذكر رابط النقطة ونوع الحدث. (تسليمات وضع الاختبار عمرها ما بتطلق إيميلات.)

لو النقطة ما حصلش عليها أي تسليم ناجح خالص وقت ما الحدث ده كان بيفشل، XPay بيعتبرها واقعة: بيعطّل النقطة وبيبطّل يبعتلها أحداث جديدة. ده بينطبق في وضع الاختبار والحساب الفعلي. الحدث الواحد اللي بيفضل يفشل مش هيعطّل نقطة بتسلّم تمام في باقي الأحوال، بس النقطة اللي مش بتردّ خالص. ولما XPay يعطّل نقطة في الحساب الفعلي بيبعتلك إيميل دايمًا، حتى لو كنت كاتم تنبيه فشل التسليم. النقطة المعطّلة بتظهر بشارة معطل في لوحة التحكم؛ فعّلها تاني بعد ما تصلّح المعالِج بتاعك.

التسليم الفاشل مش بيضيع. تبويب الأحداث في الـ Workbench بيحتفظ بالتسليمات لمدة 90 يوم وتقدر تعيد إرسال أي واحد فيهم بعد ما تصلّح المعالِج بتاعك.

إعادة الإرسال اليدوي

تبويب Events في الـ Workbench بيعرض كل حدث حسابك أنتجه في آخر 90 يوم، مع كل تسليم لكل نقطة وكل محاولة جوّاه. على أي صف تسليم فيه زرّ Resend بيعمل POST لنفس حمولة الـ JSON لنفس النقطة من جديد.

اعمل إعادة إرسال لما:

  • تكون نشرت خطأ، والمعالِج بتاعك سقّط حدث حقيقي، ومحتاج تغذّيه بيه دلوقتي بعد ما الخطأ اتصلّح.
  • تكون بتنقّح معالِج جديد على بيانات قديمة.
  • تكون ضفت نوع حدث جديد لاشتراكك وعايز تملا الأحداث الأخيرة في المعالِج الجديد.

إعادة الإرسال مش بديل لإصلاح المعالِج نفسه. لو المعالِج لسه بيرجع 500، إعادة الإرسال هتنتج تسليم فاشل تاني وبس.

إيه الفرق عن المحاولة التلقائية

إعادة الإرسال اليدوي بتشتغل بمبدأ "أطلق وانسى": محاولة واحدة، من غير جدول إعادة. لو نقطتك رجّعت غير 2xx على إعادة الإرسال، XPay مش بيعيد المحاولة. اضغط Resend تاني من الـ Workbench لما تجهز لمحاولة جديدة.

كمان إعادة الإرسال مش بتحدّث حالة التسليم الأصلي. بتعمل تسليم شقيق جديد جنب الأصلي، وتبويب الأحداث بيجمّعهم مع بعض حسب الرابط علشان تشوف الخط الزمني الكامل لنقطة واحدة مرة واحدة.

علشان الشرح خطوة بخطوة لتبويب الأحداث (التصفية، والدخول بالتفصيل للمحاولات، وقراءة محتوى الطلب والرد)، شوف Workbench ← لوحة الأحداث.

شكل إعادة الإرسال من ناحيتك

المعالِج بتاعك مش هيقدر بسهولة يفرّق إعادة الإرسال عن الأصلي أو عن المحاولة التلقائية. كلهم بيوصلوا كطلبات POST لنفس الرابط بنفس محتوى الـ JSON.

اللي بيفضل ثابت في كل محاولة أو إعادة إرسال لنفس الحدث:

  • event.id، معرّف الحدث الفريد.
  • event.type، نوع الحدث.
  • event.data.object، حمولة المورد.
  • البايتات الخام لمحتوى الـ JSON.

اللي بيتغير في كل محاولة أو إعادة إرسال:

  • قيمة t في XPay-Signature هي طابع وقت محاولة التسليم دي بالذات، مش الحدث الأصلي.
  • توقيع v1 في XPay-Signature بيتحسب من جديد على قيمة t الجديدة دي.

نتيجتين للمُتحقق بتاعك:

  1. نافذة إعادة الإرسال لكل محاولة. إعادة إرسال بتوصل بعد الحدث الأصلي بـ 3 أيام لسه قيمة t بتاعتها في حدود ثواني من "دلوقتي"، فاختبار abs(now - t) > 300 بينجح. ما تقارنش t بطابع وقت created بتاع المورد؛ هما بيختلفوا عن بعض عن قصد.
  2. التحقق من التوقيع بيشتغل بنفس الطريقة. أعد الحساب على قيمة t الجديدة والمحتوى الخام باستخدام سر التوقيع بتاع نقطتك. شوف التحقق من التوقيعات.

ابنِ عدم التكرار على event.id

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

async function handleEvent(event: { id: string; type: string; data: unknown }) {
  // First-write-wins on event.id
  const inserted = await db.processedEvents.insertIfNew(event.id);
  if (!inserted) return; // already processed; no-op

  // Real work happens here
}

insertIfNew هو صف واحد في جدول معرّفات الأحداث المعالَجة (أو SET NX في Redis لو بتفضّل كده). الشغل اللي تحته بيشتغل مرة واحدة على الأكتر لكل حدث، مهما XPay أعاد المحاولة أو أنت أعدت الإرسال.

علشان النمط الكامل (تحقق، أزل التكرار، أقرّ بسرعة، اشتغل في طابور)، شوف التحقق من التوقيعات ← عدم التكرار.

رايح فين بعد كده

في الصفحة دي