لاختبار webhook بشكل صحيح، وفّر للمزوّد عنوان URL عام يمكنه الوصول إليه، شغّل حدثًا حقيقيًا أو اختباريًا، ثم تحقق من أن المعالج لديك يستقبل الحمولة، يتحقق من التوقيع، يعيد الاستجابة الصحيحة، وينفذ الأثر الجانبي المتوقع. لأن تطبيقك هنا هو المستقبل وليس العميل، تحتاج إلى أدوات التقاط، نفق محلي، ومشغلات أحداث من المزوّد بدل الاعتماد على زر "Send" فقط.
لماذا اختبار Webhooks أصعب من اختبار APIs العادية؟
في استدعاء API عادي، أنت تتحكم في كل شيء: الطريقة، الرؤوس، الجسم، وتوقيت الطلب. أما في Webhooks، فالمزوّد هو من يرسل الطلب إلى تطبيقك عند حدوث حدث معيّن.
هذا يخلق تحديات عملية:
لا تتحكم دائمًا في توقيت الحدث
مثلًا، حدثpayment_intent.succeededفي Stripe لا يحدث إلا عندما يطلقه Stripe أو أدواته.التسليم غير متزامن
لا تنتظر قيمة إرجاع مباشرة، بل تلتقط طلبًا واردًا.شكل الحمولة يحدده المزوّد
يجب أن يتعامل المعالج مع JSON الفعلي الذي يرسله GitHub أو Stripe أو Slack.معظم الطلبات موقّعة
يجب التحقق من رأس التوقيع قبل الوثوق بالجسم. تجاهل التوقيع أثناء الاختبار قد يخفي أخطاء إنتاجية حقيقية. راجع أيضًا: التحقق من توقيع الـ webhook.
إذا كنت ما زلت تقارن بين الأنماط، راجع مقارنة الـ webhooks بالاستقصاء polling ومقارنة الـ webhook بالـ WebSocket.
أدوات تحتاجها لاختبار Webhook
ستحتاج غالبًا إلى أربع فئات من الأدوات:
- خدمة التقاط لرؤية الطلبات الخام.
- نفق محلي لكشف
localhost. - أدوات المزوّد لتشغيل أحداث اختبار.
- أداة API لحفظ الطلبات، تشغيلها، وإضافة تأكيدات.
1. التقط الحمولة الحقيقية أولًا
قبل كتابة منطق المعالجة، وجّه المزوّد إلى عنوان URL مؤقت وشاهد ما يرسله فعليًا.
webhook.site
يعطيك webhook.site عنوان URL عشوائيًا فريدًا بمجرد فتح الصفحة. أي طلب يُرسل إليه يظهر مباشرة مع:
- الجسم الكامل.
- الرؤوس.
- طريقة HTTP.
- الاستعلامات إن وجدت.
النسخة المجانية تنتهي بعد 7 أيام وتدعم حتى 100 طلب، مع حد أقصى 10MB لكل طلب. الخطط المدفوعة تضيف عناوين دائمة، طلبات غير محدودة، وسجلًا محفوظًا.
Beeceptor
يوفر Beeceptor نقطة نهاية HTTPS مجانية يمكن استخدامها كمستقبل webhook، مع إمكانية فحص الحمولات الواردة في الوقت الفعلي. كما يدعم mock server، لذلك يمكنك الالتقاط والمحاكاة من نفس الأداة.
Pipedream RequestBin
Pipedream RequestBin خيار شائع آخر لالتقاط الطلبات. تحقق من حدود الخطة الحالية في وثائق الخدمة، لأن حدود الخدمات المجانية تتغير كثيرًا.
الهدف من هذه الخطوة بسيط: احصل على عينة حقيقية من الحمولة والرؤوس لاستخدامها لاحقًا في اختبارات قابلة للتكرار.
2. اختبر محليًا باستخدام نفق إلى localhost
المزوّد لا يستطيع الوصول إلى:
http://localhost:3000
لذلك تحتاج إلى نفق يعطيك عنوان HTTPS عام يوجّه الطلبات إلى جهازك.
باستخدام ngrok
brew install ngrok
ngrok config add-authtoken $YOUR_TOKEN
ngrok http 3000
سيطبع ngrok عنوانًا عامًا مثل:
https://abc123.ngrok-free.app
إذا كان المعالج لديك على:
http://localhost:3000/webhooks
فاستخدم في إعدادات المزوّد:
https://abc123.ngrok-free.app/webhooks
حسابات ngrok المجانية تحصل على نطاق تطوير تلقائي. النطاقات المخصصة تتطلب خطة مدفوعة.
باستخدام cloudflared
cloudflared tunnel --url http://localhost:3000
انسخ عنوان HTTPS الذي يظهر في الطرفية وضعه في إعدادات webhook لدى المزوّد.
لشرح أوسع لهذا النمط، راجع: كيفية اختبار واجهات برمجة تطبيقات localhost باستخدام خدمات الـ webhook.
3. شغّل أحداث اختبار من المزوّد
بعد توفير URL عام، تحتاج إلى إطلاق حدث فعلي أو اختباري.
Stripe
استخدم Stripe CLI لإعادة توجيه أحداث sandbox إلى المعالج المحلي:
stripe listen --forward-to localhost:3000/webhooks
لتصفية أحداث محددة:
stripe listen --events payment_intent.succeeded,checkout.session.completed \
--forward-to localhost:3000/webhooks
سيطبع الأمر سر توقيع webhook. ضعه في إعدادات تطبيقك حتى يتمكن المعالج من التحقق من التوقيع.
بعد تشغيل المستمع، أطلق حدثًا:
stripe trigger payment_intent.succeeded
stripe trigger checkout.session.completed
stripe trigger --help
انتبه: بعض الأحداث تنشئ كائنات API مدعومة ولها آثار جانبية. مثلًا، payment_intent.succeeded قد يؤدي أيضًا إلى payment_intent.created.
GitHub
لاختبار Webhook في GitHub:
- افتح المستودع.
- اذهب إلى Settings.
- من Code and automation اختر Webhooks.
- افتح عنوان الـ webhook.
- انتقل إلى Recent deliveries.
- افتح تسليمًا سابقًا.
- اضغط Redeliver.
قيود مهمة:
- يمكنك إعادة تسليم أحداث آخر 3 أيام فقط.
- تحتاج إلى صلاحيات admin على المستودع.
- GitHub لا يعيد التسليمات الفاشلة تلقائيًا؛ إعادة التشغيل يدوية.
Slack
Webhooks الواردة في Slack سهلة الاختبار. أرسل POST إلى عنوان webhook:
curl -X POST https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX \
-H 'Content-type: application/json' \
-d '{"text":"Hello, world."}'
عنوان Slack webhook سرّي. لا تضعه في كود الواجهة أو مستودع عام؛ Slack قد يلغي الروابط المسرّبة.
4. اختبر المعالج نفسه
التقاط الطلبات وتشغيل الأحداث يثبت أن الاتصال يعمل، لكنه لا يثبت أن المعالج صحيح.
ابدأ باختبار مباشر باستخدام curl:
curl -X POST http://localhost:3000/webhooks \
-H 'Content-Type: application/json' \
-H 'Stripe-Signature: t=...,v1=...' \
-d '{"id":"evt_test","type":"payment_intent.succeeded","data":{"object":{"id":"pi_123","status":"succeeded"}}}'
لكن curl وحده لا يكفي عادةً، خصوصًا إذا أردت:
- حفظ عدة حمولات.
- اختبار توقيع صالح وآخر غير صالح.
- تشغيل الاختبارات في CI.
- إضافة assertions على الاستجابة.
هنا تصبح أداة API مفيدة.
اختبار Webhooks باستخدام Apidog
Apidog منصة API لتصميم الواجهات، تصحيحها، اختبارها، محاكاتها، وتوثيقها.
لا يحتوي Apidog على "صندوق وارد webhook" مخصص، لذلك استخدمه لما يجيده فعليًا:
- بناء طلبات webhook محفوظة.
- إرسال حمولات حقيقية أو معدلة.
- إضافة assertions على الاستجابة.
- تشغيل سيناريوهات في CI.
- استخدام mock server بدل مزوّد خارجي عند الحاجة.
5. احفظ حمولة Webhook كطلب قابل لإعادة الاستخدام
بعد التقاط حمولة حقيقية من webhook.site أو من وثائق المزوّد:
- أنشئ طلبًا جديدًا في Apidog.
- اضبط الطريقة على
POST. - ضع عنوان المعالج، مثل:
http://localhost:3000/webhooks
- الصق جسم JSON الحقيقي.
- أضف الرؤوس التي يرسلها المزوّد، مثل:
Content-Type: application/json
Stripe-Signature: t=...,v1=...
- احفظ الطلب باسم واضح، مثل:
Stripe - payment_intent.succeeded
الآن أصبح لديك اختبار قابل لإعادة التشغيل بدل إعادة كتابة أمر curl في كل مرة.
6. أضف تأكيدات على الاستجابة
إرجاع 200 لا يعني أن المعالج صحيح. اختبر محتوى الاستجابة أيضًا.
في Apidog:
- افتح الطلب أو السيناريو.
- افتح Post Processors.
- اضغط + Add.
- اختر Assertion.
- أضف شرطًا على جسم الاستجابة.
مثال: إذا كانت الاستجابة:
{
"data": {
"status": "succeeded"
}
}
استخدم المسار:
$.data.status
واجعل الشرط:
Equals succeeded
يمكنك إضافة عدة assertions، مثل:
- حالة HTTP تساوي
200. -
$.data.statusتساويsucceeded. - وجود
$.data.id. - رفض الطلب عند توقيع خاطئ.
ملاحظة: التأكيدات المرئية تقارن القيم كسلاسل نصية. إذا احتجت فحص أنواع دقيقة مثل رقم أو boolean، استخدم سكربت مخصص بصيغة pm.test المتوافقة مع Postman.
مثال لفحص مخصص:
pm.test("status is succeeded", function () {
const json = pm.response.json();
pm.expect(json.data.status).to.eql("succeeded");
});
7. اختبر حالات الفشل عمدًا
لا تختبر مسار النجاح فقط. أضف طلبات أو بيانات اختبار تغطي:
- توقيع غير صالح.
- توقيع مفقود.
- حقل مطلوب مفقود.
- نوع حدث غير مدعوم.
- تكرار نفس الحدث لاختبار idempotency.
- جسم JSON غير صالح.
مثال حمولة مكررة لاختبار التعامل مع نفس الحدث:
{
"id": "evt_test_duplicate",
"type": "payment_intent.succeeded",
"data": {
"object": {
"id": "pi_123",
"status": "succeeded"
}
}
}
المعالج الجيد يجب ألا ينفذ الأثر الجانبي مرتين عند وصول نفس event.id.
8. استخدم Mock Server عند اختبار الخدمات التابعة
أحيانًا يكون الاتجاه معكوسًا: خدمة داخل نظامك تستدعي مزوّدًا خارجيًا، ولا تريد استدعاء المزوّد الحقيقي أثناء الاختبار.
يمكنك استخدام Apidog Mock Server لمحاكاة هذا المزوّد.
يدعم Apidog ثلاثة أنواع من mock:
- Local Mock: يعمل مع عميل سطح المكتب، ويعمل فقط أثناء فتح العميل.
- Cloud Mock: مستضاف على خوادم Apidog، يعمل 24/7، ويمكن تشغيله أو إيقافه، وهو متوقف افتراضيًا.
- Runner Mock: يعمل على بنية runner مستضافة ذاتيًا ومشتركة بين الفريق.
لكل نقطة نهاية HTTP وحدة Mock. انسخ عنوان URL للمحاكاة من:
- تبويب API في وضع Design.
- أو تبويب Mock في وضع Debug.
ملاحظة: المسارات التي تبدأ بـ / فقط يتم توجيهها إلى بيئة المحاكاة.
استخدم عنوان mock أثناء الاختبارات لتجنب استدعاءات API حقيقية وآثار جانبية غير مرغوبة.
9. شغّل اختبارات Webhook في CI باستخدام Apidog CLI
بعد نجاح السيناريو محليًا، شغّله مع كل push باستخدام Apidog CLI.
يتطلب Node.js 16 أو أحدث.
npm install -g apidog-cli
node -v
apidog -v
which node
which npm
which apidog
لتشغيل سيناريو محفوظ:
apidog run --access-token $APIDOG_ACCESS_TOKEN -t 637132 -e 358171 -d 3497013 -r html,cli
المعاملات:
-
--access-token: رمز الوصول. -
-t: معرف سيناريو الاختبار. -
-e: معرف البيئة، وهو مطلوب. -
-d: بيانات الاختبار، ويمكن أن تكون ملف CSV/JSON أو معرف dataset محفوظة. -
-r: نوع التقارير، ويدعمcliوhtmlوjsonوjunit.
للتفاصيل، راجع: برنامج Apidog CLI التعليمي.
إذا أردت بناء واختبار Webhooks بصريًا، يمكنك تجربة Apidog مجانًا بدون بطاقة ائتمان.
سير عمل عملي لاختبار Webhook
استخدم هذا التسلسل في كل تكامل جديد:
التقط حمولة حقيقية
وجّه المزوّد إلى webhook.site أو أداة مشابهة، ثم احفظ الجسم والرؤوس والتوقيع.شغّل المعالج محليًا
ابدأ تطبيقك على منفذ مثل3000.افتح نفقًا عامًا
استخدم:
ngrok http 3000
أو:
cloudflared tunnel --url http://localhost:3000
- ضع عنوان HTTPS في إعدادات المزوّد مثال:
https://abc123.ngrok-free.app/webhooks
شغّل حدثًا حقيقيًا أو اختباريًا
استخدمstripe trigger، أو GitHub Redeliver، أو طلب Slack.تحقق من التوقيع
أرسل نفس الحمولة مرة بتوقيع صالح ومرة بتوقيع مزور. يجب قبول الأولى ورفض الثانية.احفظ الطلب في Apidog
استخدم الحمولة الحقيقية والرؤوس الفعلية.أضف assertions
تحقق من status code، الجسم، والأثر الجانبي.أتمت الاختبار في CI
شغّل السيناريو عبر Apidog CLI عند كل تغيير.
إذا كنت تصمم نظام Webhook وليس فقط تستهلكه، راجع كيفية تصميم webhooks موثوقة وأفضل ممارسات الـ webhooks للدفع. وللصورة الأكبر، اقرأ دليل API للـ webhooks والـ webhooks والبنية المعتمدة على الأحداث.
الأسئلة المتكررة
كيف تختبر الـ webhook؟
وفّر للمزوّد عنوان URL عامًا، شغّل حدثًا حقيقيًا أو اختباريًا، ثم تحقق من أن المعالج يستقبل الحمولة، يتحقق من التوقيع، يعيد الحالة الصحيحة، وينفذ الأثر الجانبي المتوقع. الأفضل أن تلتقط حمولة حقيقية أولًا، ثم تحفظها كطلب قابل لإعادة التشغيل مع assertions.
كيف تختبر الـ webhooks محليًا؟
شغّل المعالج على منفذ محلي، ثم اكشفه باستخدام نفق:
ngrok http 3000
أو:
cloudflared tunnel --url http://localhost:3000
انسخ عنوان HTTPS الناتج إلى إعدادات webhook لدى المزوّد، ثم شغّل حدثًا. ستصل الطلبات إلى خادمك المحلي ويمكنك تصحيحها مباشرة.
كيف تختبر الـ webhook باستخدام Postman؟
يمكن لـ Postman إرسال POST بحمولة مخصصة إلى نقطة النهاية وإضافة اختبارات على الاستجابة، لكنه لا يستقبل webhook واردًا حقيقيًا وحده. الأمر نفسه ينطبق على Apidog: استخدمه لبناء طلبات محفوظة بحمولة ورؤوس المزوّد وإضافة assertions. لالتقاط حدث حقيقي، استخدم خدمة التقاط أو نفقًا محليًا.
كيف تختبر Webhooks الخاصة بـ Stripe؟
استخدم Stripe CLI:
stripe listen --forward-to localhost:3000/webhooks
ثم شغّل حدثًا:
stripe trigger payment_intent.succeeded
لرؤية الأحداث المدعومة:
stripe trigger --help
يعطيك stripe listen سر توقيع webhook، ويجب استخدامه في إعدادات التطبيق للتحقق من التوقيع.
كيف تختبر Webhook الخاصة بـ Slack؟
أرسل JSON إلى عنوان Slack incoming webhook:
curl -X POST https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX \
-H 'Content-type: application/json' \
-d '{"text":"Hello, world."}'
إذا نجح الطلب، ستظهر الرسالة في القناة المكوّنة. حافظ على سرية عنوان URL.
كيف تختبر عنوان URL لـ webhook؟
أرسل طلب POST نموذجيًا وتحقق من الاستجابة والسلوك. أبسط فحص:
curl -X POST https://example.com/webhooks \
-H 'Content-Type: application/json' \
-d '{"type":"test.event"}'
للاختبار الحقيقي، استخدم حمولة فعلية، جرّب توقيعًا صالحًا وآخر غير صالح، وتحقق من الاستجابة والآثار الجانبية بدل الاكتفاء برقم 200.
Top comments (0)