المطوّرون
Webhooks
في هذه الصفحة
إعداد نقطة نهاية
- أضف مسار https إلى خادمك يقرأ النص الخام ويرد بـ
2xxخلال 10 ثوانٍ. نفّذ العمل بعد الرد. - أنشئ نقطة النهاية عبر الـ API، أو اطلب من فريقنا. احفظ سرّ
whsec_الذي يُرجعه: فهو يظهر مرة واحدة فقط. - تحقّق من كل طلب (أدناه)، ثم أزل التكرار بالاعتماد على
idالحدث. - أرسل لنفسك حدثًا تجريبيًا من كل نوع تتعامل معه.
الحدث
لكل حدث الغلاف نفسه. ويحمل data حقول النوع الخاصة به.
idstring- يبدأ بـ evt_. يبقى نفسه في كل إعادة محاولة، وفي ترويسة webhook-id.
typestring- أحد الأحداث أدناه.
api_versionstring- الإصدار الذي كُتب به data: إصدار نقطة النهاية لديك.
created_atstring- متى حدث، وقد يكون ذلك قبل أن يصلك.
testboolean- true للأحداث التجريبية.
dataobject- معرّفات لجلب الكائن كاملًا، وما الذي تغيّر.
POST /hooks/ninjabuy HTTP/1.1
Host: acme-goods.com
Content-Type: application/json
User-Agent: NinjaBuy-Webhooks/1.0
webhook-id: evt_4m2x
webhook-timestamp: 1793685600
webhook-signature: v1,K5oZfzN95Z9UVu1EsfQmfVNQhnkZ2pj9o9NDN/H/pI4=
{
"id": "evt_4m2x",
"type": "order.shipped",
"api_version": "2026-11",
"created_at": "2026-11-03T06:00:00Z",
"test": false,
"data": {
"order": "ord_3n7q",
"external_id": "1012",
"shipment": "shp_5r8w",
"carrier": "YunExpress",
"tracking_number": "YT2630812345678",
"tracking_url": "https://t.17track.net/en#nums=YT2630812345678",
"shipping_charged": { "amount": "134.52", "currency": "CNY" },
"pushed_to_channel": true
}
}الأحداث
order.created
وصلنا طلب، من متجرك على Shopify أو من الـ API. مدفوع، أو awaiting_payment.
{
"id": "evt_1a7c",
"type": "order.created",
"api_version": "2026-11",
"created_at": "2026-11-01T09:14:02Z",
"test": false,
"data": {
"order": "ord_3n7q",
"external_id": "1012",
"source": "shopify",
"status": "buying",
"payment_status": "paid",
"lines": [
{
"line": "lin_9a2c",
"variant": "var_41hz",
"sku": "5187209554",
"quantity": 1
}
]
}
}order.paid
دُفع طلب من رصيدك. يُطلق أيضًا للطلبات التي انتظرت شحن الرصيد.
{
"id": "evt_1a9f",
"type": "order.paid",
"api_version": "2026-11",
"created_at": "2026-11-01T11:02:40Z",
"test": false,
"data": {
"order": "ord_3n8a",
"external_id": "1013",
"amount": { "amount": "57.00", "currency": "CNY" },
"paid_from": "balance",
"was_awaiting_payment": true
}
}order.bought
دفعنا للبائع. البنود بحالة with_seller حتى تصل إلى مستودعنا.
{
"id": "evt_2c4e",
"type": "order.bought",
"api_version": "2026-11",
"created_at": "2026-11-01T13:30:05Z",
"test": false,
"data": {
"order": "ord_3n7q",
"external_id": "1012",
"lines": [
{
"line": "lin_9a2c",
"sku": "5187209554",
"quantity": 1,
"status": "with_seller"
}
]
}
}order.checked
القطع في مستودعنا، مفحوصة، مع صورها. التغليف هو الخطوة التالية.
{
"id": "evt_9w1c",
"type": "order.checked",
"api_version": "2026-11",
"created_at": "2026-11-02T03:20:11Z",
"test": false,
"data": {
"order": "ord_3n7q",
"external_id": "1012",
"fulfillment_order": "fo_7k2m",
"lines": [
{
"line": "lin_9a2c",
"qc": "passed",
"photos": [
"https://media.ninjabuy.com/qc/ord_3n7q/1.webp",
"https://media.ninjabuy.com/qc/ord_3n7q/2.webp"
]
}
]
}
}order.shipped
خرج الطرد برقم تتبّع، وتكلفة الشحن نهائية. المتجر الذي جاء منه الطلب لديه رقم التتبّع أيضًا.
{
"id": "evt_4m2x",
"type": "order.shipped",
"api_version": "2026-11",
"created_at": "2026-11-03T06:00:00Z",
"test": false,
"data": {
"order": "ord_3n7q",
"external_id": "1012",
"shipment": "shp_5r8w",
"carrier": "YunExpress",
"tracking_number": "YT2630812345678",
"tracking_url": "https://t.17track.net/en#nums=YT2630812345678",
"shipping_charged": { "amount": "134.52", "currency": "CNY" },
"pushed_to_channel": true
}
}product.cost_changed
بائع غيّر سعرًا، وما فعلته قاعدة المزامنة: أعادت التسعير أو أوقفت مؤقتًا أو أرسلت تنبيهًا.
{
"id": "evt_8q0d",
"type": "product.cost_changed",
"api_version": "2026-11",
"created_at": "2026-11-04T02:10:00Z",
"test": false,
"data": {
"product": "prd_1x0a",
"variant": "var_2b7k",
"sku": "4410923871",
"cost": {
"from": { "amount": "42.00", "currency": "CNY" },
"to": { "amount": "48.00", "currency": "CNY" }
},
"action": "repriced",
"price": {
"from": { "amount": "18.99", "currency": "USD" },
"to": { "amount": "20.99", "currency": "USD" }
},
"rule": "rule_default"
}
}product.out_of_stock
نفد متغيّر لدى البائع ولا يوجد منه على رفّك: ضبطناه على 0 في قنواتك.
{
"id": "evt_2b9n",
"type": "product.out_of_stock",
"api_version": "2026-11",
"created_at": "2026-11-04T02:11:30Z",
"test": false,
"data": {
"product": "prd_8f2k",
"variant": "var_41j0",
"sku": "5187209555",
"warehouse_on_hand": 0,
"channels_updated": [
{
"channel": "shopify",
"shop": "acme-goods.myshopify.com",
"available": 0
}
]
}
}qc.issue
وجد فحصنا مشكلة في قطعة: لون أو مقاس خاطئ، أو ضرر، أو جزء ناقص. اختر قبل respond_by، ودون رد نعلّقها ونراسلك.
{
"id": "evt_6c3h",
"type": "qc.issue",
"api_version": "2026-11",
"created_at": "2026-11-02T03:20:11Z",
"test": false,
"data": {
"order": "ord_3n7q",
"external_id": "1012",
"fulfillment_order": "fo_7k2m",
"line": "lin_9a2c",
"sku": "5187209554",
"issue": "wrong_color",
"note": "Received grey, ordered black.",
"photos": ["https://media.ninjabuy.com/qc/ord_3n7q/3.webp"],
"choices": ["ship_anyway", "exchange", "refund"],
"respond_by": "2026-11-05T03:20:11Z"
}
}التوقيعات
عمليات التسليم موقّعة بطريقة Standard Webhooks، فتتحقق منها مكتبة قد تستخدمها أصلًا. ثلاث ترويسات ترافق كل عملية تسليم:
| الترويسة | ما يحتويه |
|---|---|
| webhook-id | معرّف الحدث. |
| webhook-timestamp | وقت إرسال هذه المحاولة، بثواني Unix. |
| webhook-signature | v1، ثم فاصلة وقيمة HMAC-SHA256 بترميز base64 لـ id.timestamp.body بسرّك. أثناء التدوير، توقيعان يفصل بينهما مسافة. |
المفتاح هو سرّك بعد whsec_، بعد فك ترميز base64. وقّع النص الخام تمامًا كما وصل؛ وارفض أي طابع زمني يبتعد أكثر من خمس دقائق، فلا يمكن إعادة تشغيل طلب ملتقط.
التحقق من عملية تسليم
بمكتبة standardwebhooks، أو ببضعة أسطر من كتابتك:
إعادة المحاولات والترتيب
أي رد غير 2xx خلال 10 ثوانٍ يُعدّ فشلًا، فنعيد المحاولة، كل مرة بـ webhook-id نفسه وطابع زمني وتوقيع جديدين:
| المحاولة | بعد السابقة |
|---|---|
| 1 | فورًا |
| 2 | 5 ثوانٍ |
| 3 | 5 دقائق |
| 4 | 30 دقيقة |
| 5 | ساعتان |
| 6 | 5 ساعات |
| 7 | 10 ساعات |
| 8 | 10 ساعات، الأخيرة |
- بعد المحاولة الأخيرة تُعدّ عملية التسليم فاشلة. أرسلها مجددًا من قائمة عمليات التسليم.
- نقطة النهاية التي فشلت كل عمليات التسليم إليها لخمسة أيام تُعطَّل، بعد إرسال بريد إليك. إعادة تفعيلها ترسل ما فاتها في آخر ثلاثة أيام.
- قد تصل الأحداث مرتين وبغير ترتيب. أزل التكرار بالاعتماد على id، وحين يهمّ الترتيب، اجلب الكائن واعتمد حالته بدل حالة الحدث.