Skip to content
المميزاتالأسعارالشراكةالمدونةالمساعدةمن نحنتواصل معنا
ابدأ الآنتسجيل الدخول
العودة إلى المدونة
guides2026-08-295 دقيقة قراءة

تكافؤ الويب هوك: عندما يرسل Stripe نفس حدث العمولة ثلاث مرات

ضمان at-least-once من Stripe يعني نحو 0.3% أحداث مكررة في الإنتاج. كيف يتعامل نمط claim لجدول stripe_webhook_events في thMenu مع التكرارات — وحالة السباق.

th

thMenu Team

thmenu.com

على مدى 14 شهراً سجلنا كل webhook من Stripe على thMenu: 312 من 100,000 حدث وصلت بنفس event_id مرتين أو ثلاث مرات. هذا وعد "at-least-once delivery" من Stripe بأرقام ملموسة — بدون تكافؤ، ثلاث نسخ مكررة في دفتر العمولات.

لماذا يصل نفس الحدث ثلاث مرات

إذا لم يستلم Stripe استجابة 2xx خلال ~10 ثوانٍ، يعيد المحاولة. مهلات TCP، بدايات lambda الباردة، أعطال DNS العابرة، حتى المعالجة الناجحة متبوعة بانقطاع الاتصال — كلها تثير إعادة المحاولات.

ثلاث سيناريوهات شائعة: cold start لـ Cloudflare Workers يتجاوز 10 ثوانٍ، معاملة D1 batch تم commit ولكن انقطع الاتصال، أو نقرة "resend" يدوية في dashboard Stripe.

نمط INSERT-Claim

دفاع thMenu هو جدول stripe_webhook_events مع event_id PRIMARY KEY. أول إجراء: INSERT. خطأ unique constraint 23505 = تكرار — 200 OK no-op.

أمر حاسم: يجب أن يسبق claim منطق العمل لتجنب race condition.

Race Condition: أحداث خارج الترتيب

حادث حقيقي: customer.subscription.updated وصل قبل 800ms من checkout.session.completed. UPDATE أثر على 0 صفوف. الإصلاح: rollback للـ claim، إرجاع 503، Stripe يعيد المحاولة.

FAQ

تحقق التوقيع قبل أو بعد claim؟ قبل. Verify رخيص، كتابة DB مكلفة.

كم تحفظ صفوف التكافؤ؟ Stripe يضمن 30 يوماً؛ نحفظ 90 يوماً.

هل يعيد Stripe المحاولة إلى الأبد؟ لا، 3 أيام كحد أقصى.

هل وجدت هذا مفيداً؟ شاركه.