تسجيل webhook
يمكنك تسجيل حتى 10 روابط webhook لكل متجر. كل واحد يمكن أن يشترك بقائمة مختلفة من الأحداث؛ اختر النموذج المناسب لك:
- نقطة واحدة، كل الأحداث — أسهل للتطبيقات الصغيرة. تفرّع على
eventفي معالجك. - عدة نقاط، حدث واحد لكل — أنظف في إعدادات microservices، لكن روابط أكثر للإدارة.
POST /v1/webhooks — تسجيل
المصادقة: مفتاح منصة بصلاحية webhooks:write. يتطلب Idempotency-Key.
الجسم
| الحقل | النوع | إلزامي | ملاحظات |
|---|---|---|---|
url | string (https URL) | ✅ | يجب أن يكون http:// أو https://. للإنتاج: دائمًا https://. أقصى طول 500. |
events | string[] | ✅ | قائمة أسماء أحداث. انظر كتالوج الأحداث للقيم المسموح بها. مصفوفة فارغة = خطأ. |
الطلب
curl -X POST 'https://api.dzbuild.app/v1/webhooks' \
-H "Authorization: Bearer $DZ_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"url": "https://yourapp.example/webhooks/dzbuild",
"events": ["order.created", "order.confirmed", "order.shipped",
"order.cancelled", "signup.counted"]
}'
الاستجابة 201
{
"data": {
"id": 17,
"secret": "fc9b5f0b51b4a93c1d6f8e29b6a2e30c7c2c44a4f2a6c8d8e0e1b9d4f6c1a8b3",
"note": "Save the secret now — it is not retrievable after this response."
}
}
secret يظهر مرة واحدة. احفظه بجانب معرّف الـ webhook في مدير الأسرار. إنه القيمة التي تستخدمها للتحقق من كل POST وارد. إن فقدته، احذف الـ webhook وأنشئ غيره.
الأخطاء
| الكود | السبب |
|---|---|
bad_request "url must be a valid http(s) URL" | شكل رابط خاطئ |
bad_request "events must be a non-empty list" | مصفوفة فارغة |
bad_request "unknown event: foo. Allowed: …" | اسم حدث غير موجود في الكتالوج |
GET /v1/webhooks — قائمة
المصادقة: مفتاح منصة بصلاحية webhooks:read.
curl https://api.dzbuild.app/v1/webhooks \
-H "Authorization: Bearer $DZ_KEY"
{
"data": {
"items": [
{
"id": 17,
"url": "https://yourapp.example/webhooks/dzbuild",
"events": ["order.created", "order.confirmed"],
"status": "active",
"last_success_at": "2026-04-30 21:18:23",
"last_failure_at": null,
"failure_count": 0,
"created_at": "2026-04-30 19:00:00"
}
],
"allowed_events": [
"order.created", "order.confirmed", "order.shipped", "order.delivered",
"order.cancelled", "order.returned", "payment.received",
"signup.counted", "event.recorded", "product.stock_low"
]
}
}
allowed_events هي القائمة الرسمية — استخدمها لتعبئة لوحات في أدواتك الإدارية.
| الحالة | المعنى |
|---|---|
active | يستلم التسليمات |
paused | لا يستلم (يمكنك إيقافه من اللوحة) |
dead | عُطّل تلقائيًا بعد 5 رسائل ميتة متتالية. راسل الدعم لإعادته. |
POST /v1/webhooks/{id}/test
أطلق تسليم webhook.test للتحقق أن نقطتك تستلم وتتحقق من التواقيع بشكل صحيح.
المصادقة: مفتاح منصة بصلاحية webhooks:write. يتطلب Idempotency-Key.
curl -X POST 'https://api.dzbuild.app/v1/webhooks/17/test' \
-H "Authorization: Bearer $DZ_KEY" \
-H "Idempotency-Key: test-17-$(date +%s)"
{ "data": { "tested": true, "note": "a webhook.test delivery was enqueued; check your endpoint" } }
تسليم الاختبار يبدو هكذا:
{
"event": "webhook.test",
"store_id": 13,
"occurred_at": "2026-04-30T21:24:17+00:00",
"data": { "ts": 1717112657 },
"delivery_id": "..."
}
يحمل توقيعًا حقيقيًا — يمكن اختبار شيفرة التحقق لديك من البداية للنهاية.
DELETE /v1/webhooks/{id}
المصادقة: مفتاح منصة بصلاحية webhooks:write. يتطلب Idempotency-Key.
curl -X DELETE 'https://api.dzbuild.app/v1/webhooks/17' \
-H "Authorization: Bearer $DZ_KEY" \
-H "Idempotency-Key: del-17"
{ "data": { "deleted": true, "id": 17 } }
بعد الحذف:
- لا تُجدوَل تسليمات جديدة.
- التسليمات قيد الطيران (في الطابور) تُحاوَل مرة أخرى.
- سر الـ webhook صار عديم الفائدة — لا أحد يستطيع التوقيع به.
متطلبات النقطة
رابط webhook يجب أن:
- يردّ بـ 2xx عند النجاح — أي شيء آخر يُعتبر خطأ (4xx ack، 5xx يُعاد).
- يردّ خلال 10 ثوانٍ. الأبطأ → timeout → إعادة محاولة.
- يقبل
POSTمعContent-Type: application/json. - يقرأ الجسم الخام للتحقق من التوقيع (لا تُعد التسلسل).
- يكون idempotent — نفس
delivery_idقد يصل أكثر من مرة.
فخ شائع في بعض الأطر: middleware يُعيد ترميز جسم JSON قبل أن يراه معالجك، فيُخفق sha256(body) بالمطابقة. الحلول:
- Express: استعمل
express.raw({ type: 'application/json' })لمسار webhook ثمJSON.parse(req.body)في المعالج. - Django:
request.bodyهي البايتات الخام — هذا ما تريده. - Laravel:
$request->getContent()يُعيد الجسم الخام. - PHP خام:
file_get_contents('php://input').
انظر التحقق من التواقيع لشيفرة كاملة بأربع لغات.