الأحداث
الـWebhook هو عنوان على خادمك نرسل إليه حدثًا فور وقوعه. وهناك ستة أحداث:
form.response.created Eine neue Antwort auf eines deiner Formulare
form.response.updated Jemand hat seine Antwort über den Bearbeitungslink geändert
order.paid Eine Bestellung ist bezahlt
order.fulfilled Eine Bestellung ist versendet oder übergeben
order.canceled Eine bestätigte Bestellung wurde storniert
order.refunded Eine Bestellung wurde erstattetيصل order.refunded عند أول استرداد جزئي وعند الاسترداد الكامل. أما صندوق الدفع الذي لم يُدفع قط وانتهت صلاحيته فلا يُعد إلغاءً — ولا يُرسَل له أي حدث.
إعداد خطاف ويب
يمكن للبرامج أيضًا تسجيل خطافات الويب بنفسها: POST /v1/webhooks بمفتاح يحمل webhooks:manage — بالإضافة إلى صلاحية قراءة البيانات التي يرسلها خطاف الويب (forms:read لأحداث النماذج، وorders:read للطلبات).
- افتح قسم المطوّر في لوحة التحكم.
- أدخل تحت „خطافات الويب“ عنوان المستقبِل الخاص بك — وهو يبدأ بـ https.
- اختر تحت „ما الأحداث؟“ ما تريد تلقّيه، ثم انقر على „إنشاء خطاف ويب“.
- انسخ السر الذي يظهر بعد ذلك إلى المستقبِل الخاص بك.
- انقر على „إرسال اختبار“ — تظهر النتيجة فورًا أسفله.
ما يصل
كل حدث هو طلب POST يحمل JSON. يحتوي data.object على الكائن بالشكل نفسه الموجود في الواجهة البرمجية — الطلب كما في GET /v1/orders/{id}، والإجابة كما في قائمة الإجابات. وفي أحداث النماذج، يبيّن data.form أيضًا النموذج الذي تنتمي إليه الإجابة.
{
"id": "evt_Q2x9kLmP4vT7aB1cD3eF5gH7",
"object": "event",
"type": "order.paid",
"api_version": "2026-09-23",
"created_at": "2026-09-23T14:05:12Z",
"data": {
"object": {
"id": 5531,
"object": "order",
"number": 42,
"status": "confirmed",
"payment_status": "paid",
"currency": "EUR",
"total": 3890,
"customer": { "email": "mara@example.com", "name": "Mara Sol" },
"items": [
{ "name": "Kaffeebohnen, 500 g", "sku": "KAF-500", "quantity": 2, "unit_price": 1690 }
]
}
}
}التحقق من التوقيع
يحمل كل استدعاء الترويسة KENJTEC-Signature: t=<الوقت>,v1=<التوقيع>. التوقيع هو HMAC-SHA256 محسوب على الوقت ونقطة وجسم الطلب دون أي تعديل — باستخدام سر خطاف الويب الخاص بك مفتاحًا. تجاهل كل ما مضى على وقته أكثر من خمس دقائق.
تحقّق مقابل الجسم الخام قبل تحليل JSON: فاختلاف مسافة واحدة فقط يكفي لينتج توقيعًا مختلفًا. يمكنك العثور على السر في أي وقت تحت „عرض السر“؛ أما „تجديد السر“ فيُبطل السر القديم فورًا.
import crypto from "node:crypto";
// raw: the unparsed request body (Buffer), header: the KENJTEC-Signature header
export function verify(raw, header, secret) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) return false;
const expected = crypto.createHmac("sha256", secret)
.update(`${parts.t}.`).update(raw).digest("hex");
const given = String(parts.v1 ?? "");
return given.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(given));
}import hashlib, hmac, time
def verify(raw: bytes, header: str, secret: str) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
if abs(time.time() - int(parts["t"])) > 300:
return False
expected = hmac.new(secret.encode(), f"{parts['t']}.".encode() + raw, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, parts.get("v1", ""))قد يصل الحدث نفسه مرتين — مثلًا عندما يرد خادمك لكن الرد لا يصلنا. ويبقى المعرّف في id (وكذلك في الترويسة KENJTEC-Event-Id) كما هو: احفظه وعالج كل حدث مرة واحدة فقط.
عندما لا يصل شيء ما
يُعدّ مُسلَّمًا كل رد يحمل حالة من 200 إلى 299 خلال عشر ثوانٍ. ولا نتبع عمليات إعادة التوجيه.
إذا لم يصل حدث ما، نعيد المحاولة: بعد 1 و5 و30 دقيقة، وبعد 2 و6 و12 ساعة، ومرتين بعد 24 ساعة — لمدة تزيد قليلًا على ثلاثة أيام. وإذا أخفق تسليم خمسة أحداث متتالية نهائيًا، نوقف خطاف الويب؛ وتوضّح لوحة التحكم حينها السبب، ويعيد „إعادة التشغيل“ ضبطه.
تحت „السجل“ ترى كل عملية تسليم خلال آخر 30 يومًا مع حالتها ومحتواها. ومن هناك يمكن إرسال أي حدث مجددًا عبر „إرسال مرة أخرى“.

لا تُرسَل خطافات الويب إلا إلى عناوين https عامة. ولا نقبل العناوين الموجودة في الشبكات الداخلية ولا عناوين KENJTEC نفسها.