إنتقل إلى المحتوى الرئيسي

إعداد الـ webhooks

تعرّف على كيفية إعداد الـ webhooks لمفاتيح API في OrcaRail لتلقي إشعارات الدفع لحظيًا.

نظرة عامة​

تُضبط الـ webhooks في OrcaRail على مستوى مفتاح API. يمكن أن يكون لكل مفتاح API رابط webhook خاص به، ما يتيح لك:

  • إرسال أحداث مختلفة إلى نقاط نهاية مختلفة
  • استخدام webhooks منفصلة لكل بيئة (التطوير، والاختبار المرحلي، والإنتاج)
  • اختبار الـ webhooks لكل مفتاح API بشكل مستقل

إعداد الـ webhooks​

الخطوة 1: أنشئ مفتاح API أو حدّثه​

تُضبط الـ webhooks عند إنشاء مفتاح API أو تحديثه. يمكنك تعيين المعامل webhookUrl:

إنشاء مفتاح API برابط webhook​

POST /api/v1/organizations/:organizationId/api-keys
Authorization: Bearer YOUR_JWT_TOKEN
Content-Type: application/json

استبدل :organizationId بالمؤسسة التي تريد إدارتها. تجدها في لوحة التحكم ← إعدادات المؤسسة، أو باستدعاء نقطة نهاية قائمة المؤسسات ونسخ id المؤسسة المطلوبة. يجب أن ينتمي رمز bearer إلى مستخدم/جلسة يمكنها إدارة المؤسسة نفسها.

جسم الطلب:

{
"name": "Production API Key",
"webhookUrl": "https://api.example.com/webhooks/orcarail"
}

الاستجابة:

{
"apiKey": {
"id": 1,
"name": "Production API Key",
"keyPrefix": "ak_live_",
"status": "active",
"webhookUrl": "https://api.example.com/webhooks/orcarail",
"createdAt": "2024-01-01T00:00:00.000Z"
},
"key": "ak_live_abc123def456",
"secret": "sk_live_xyz789uvw012"
}

تحديث رابط webhook لمفتاح API​

يمكنك تحديث رابط الـ webhook لمفتاح API موجود:

PATCH /api/v1/api-keys/:id
Authorization: Bearer YOUR_JWT_TOKEN
Content-Type: application/json

جسم الطلب:

{
"webhookUrl": "https://api.example.com/webhooks/orcarail"
}

الاستجابة:

{
"id": 1,
"name": "Production API Key",
"keyPrefix": "ak_live_",
"status": "active",
"webhookUrl": "https://api.example.com/webhooks/orcarail",
"updatedAt": "2024-01-01T12:00:00.000Z"
}

الخطوة 2: متطلبات رابط الـ webhook​

يجب أن يستوفي رابط الـ webhook هذه المتطلبات:

  • HTTPS — إلزامي في الإنتاج (يُسمح بـ HTTP للتطوير المحلي)
  • متاح للعموم — يجب أن تتمكن OrcaRail من الوصول إليه من الإنترنت
  • نقطة نهاية HTTP صالحة — يجب أن تقبل طلبات POST
  • استجابة سريعة — يجب أن تعيد 200 OK خلال 10 ثوانٍ (مهلة الانتظار 10 ثوانٍ)

الخطوة 3: إزالة رابط الـ webhook​

لإيقاف تلقي الـ webhooks لمفتاح API، اضبط webhookUrl على null:

PATCH /api/v1/api-keys/:id
Authorization: Bearer YOUR_JWT_TOKEN
Content-Type: application/json

جسم الطلب:

{
"webhookUrl": null
}

أمثلة على الكود​

JavaScript/TypeScript​

// Create API key with webhook URL
const response = await fetch(
'https://api.orcarail.com/api/v1/organizations/org_123/api-keys',
{
method: 'POST',
headers: {
Authorization: `Bearer ${jwtToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Production API Key',
webhookUrl: 'https://api.example.com/webhooks/orcarail',
}),
}
)

const { apiKey, key, secret } = await response.json()
console.log('API Key created:', key)
console.log('Webhook URL:', apiKey.webhookUrl)

// Update webhook URL
const updateResponse = await fetch(
`https://api.orcarail.com/api/v1/api-keys/${apiKey.id}`,
{
method: 'PATCH',
headers: {
Authorization: `Bearer ${jwtToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
webhookUrl: 'https://api.example.com/webhooks/orcarail-v2',
}),
}
)

Python​

import requests

# Create API key with webhook URL
response = requests.post(
'https://api.orcarail.com/api/v1/organizations/org_123/api-keys',
headers={
'Authorization': f'Bearer {jwt_token}',
'Content-Type': 'application/json',
},
json={
'name': 'Production API Key',
'webhookUrl': 'https://api.example.com/webhooks/orcarail',
},
)

data = response.json()
api_key = data['apiKey']
print(f"API Key created: {data['key']}")
print(f"Webhook URL: {api_key['webhookUrl']}")

# Update webhook URL
update_response = requests.patch(
f"https://api.orcarail.com/api/v1/api-keys/{api_key['id']}",
headers={
'Authorization': f'Bearer {jwt_token}',
'Content-Type': 'application/json',
},
json={
'webhookUrl': 'https://api.example.com/webhooks/orcarail-v2',
},
)

cURL​

# Create API key with webhook URL
curl -X POST https://api.orcarail.com/api/v1/organizations/org_123/api-keys \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Production API Key",
"webhookUrl": "https://api.example.com/webhooks/orcarail"
}'

# Update webhook URL
curl -X PATCH https://api.orcarail.com/api/v1/api-keys/1 \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"webhookUrl": "https://api.example.com/webhooks/orcarail-v2"
}'

اختبار إعداد الـ webhook​

باستخدام نقطة نهاية اختبار الـ webhook​

توفر OrcaRail نقاط نهاية لاختبار إعداد الـ webhook:

إرسال webhook تجريبي​

يرسل حدثًا تجريبيًا payment_intent.completed إلى رابط الـ webhook المضبوط:

POST /api/v1/webhooks/test/:apiKeyId
Authorization: Bearer YOUR_JWT_TOKEN

الاستجابة:

{
"success": true
}

مثال:

const response = await fetch(
'https://api.orcarail.com/api/v1/webhooks/test/1',
{
method: 'POST',
headers: {
Authorization: `Bearer ${jwtToken}`,
},
}
)

const result = await response.json()
console.log('Test webhook sent:', result.success)

إرسال webhook مخصص​

أرسل حمولة مخصصة لاختبار معالج الـ webhook:

POST /api/v1/webhooks/test/:apiKeyId/custom
Authorization: Bearer YOUR_JWT_TOKEN
Content-Type: application/json

جسم الطلب:

{
"payload": {
"type": "payment_intent.completed",
"data": {
"object": {
"id": "550e8400-e29b-41d4-a716-446655440001",
"amount": "100.00",
"currency": "usd",
"status": "succeeded"
}
}
}
}

الاستجابة:

{
"success": true
}

عرض سجلات الـ webhooks​

تحقق من حالة تسليم الـ webhooks:

GET /api/v1/webhooks/logs?limit=50&offset=0
Authorization: Bearer YOUR_JWT_TOKEN

معاملات الاستعلام:

المعاملالنوعالافتراضيالوصف
limitnumber50عدد السجلات المُعادة
offsetnumber0عدد السجلات المتخطّاة

الاستجابة:

{
"logs": [
{
"id": 1,
"apiKeyId": 1,
"event": "payment_intent.completed",
"url": "https://api.example.com/webhooks/orcarail",
"statusCode": 200,
"success": true,
"attemptNumber": 1,
"createdAt": "2024-01-01T00:00:00.000Z"
}
],
"total": 1
}

مثال:

const response = await fetch(
'https://api.orcarail.com/api/v1/webhooks/logs?limit=10&offset=0',
{
headers: {
Authorization: `Bearer ${jwtToken}`,
},
}
)

const { logs, total } = await response.json()
console.log(`Found ${total} webhook logs`)
logs.forEach((log) => {
console.log(`${log.event}: ${log.success ? 'Success' : 'Failed'}`)
})

أفضل الممارسات​

1. استخدم webhooks مختلفة لكل بيئة​

أنشئ مفاتيح API منفصلة بروابط webhook مختلفة لكل بيئة:

// Development
{
name: "Development API Key",
webhookUrl: "https://dev.example.com/webhooks/orcarail"
}

// Staging
{
name: "Staging API Key",
webhookUrl: "https://staging.example.com/webhooks/orcarail"
}

// Production
{
name: "Production API Key",
webhookUrl: "https://api.example.com/webhooks/orcarail"
}

2. اختبر قبل الإنتاج​

اختبر دائمًا نقطة نهاية الـ webhook قبل استخدامها في الإنتاج:

  1. استخدم نقطة نهاية اختبار الـ webhook للتأكد من عمل المعالج
  2. راجع سجلات الـ webhooks للتأكد من نجاح التسليم
  3. تأكد من أن التحقق من التوقيع يعمل بشكل صحيح

3. راقب تسليم الـ webhooks​

راجع سجلات الـ webhooks بانتظام للتأكد من:

  • تسليم الـ webhooks بنجاح
  • أن أزمنة الاستجابة مقبولة
  • عدم حدوث أخطاء

4. تعامل مع فشل الـ webhooks​

تعيد OrcaRail إرسال الـ webhooks الفاشلة تلقائيًا:

  • الحد الأقصى للمحاولات: 3 محاولات (1 أولية + 2 إعادة)
  • استراتيجية التأخير: تأخير أُسّي يبدأ من ثانيتين
  • مهلة الانتظار: 10 ثوانٍ لكل طلب

تأكد من أن نقطة نهاية الـ webhook تتعامل مع إعادة المحاولات بسلاسة (اجعل المعالجات idempotent).

5. استخدم ngrok للتطوير المحلي​

للتطوير المحلي، استخدم ngrok لإتاحة خادمك المحلي:

# Install ngrok
npm install -g ngrok

# Expose local server
ngrok http 3000

ثم اضبط رابط الـ webhook على رابط ngrok:

https://abc123.ngrok.io/webhooks/orcarail

استكشاف الأخطاء وإصلاحها​

الـ webhook لا يتلقى الأحداث​

  1. تحقق من حالة مفتاح API — تأكد من أن المفتاح نشط
  2. تحقق من رابط الـ webhook — تأكد من ضبط الرابط بشكل صحيح
  3. راجع سجلات الـ webhooks — ابحث عن أخطاء التسليم في السجلات
  4. اختبر الـ webhook — استخدم نقطة نهاية الاختبار للتحقق من الاتصال

الـ webhook يعيد 404​

  • تأكد من وجود نقطة نهاية الـ webhook وقبولها لطلبات POST
  • تحقق من صحة مسار الرابط
  • تأكد من أن خادمك يعمل ويمكن الوصول إليه

الـ webhook يعيد 500​

  • راجع سجلات خادمك بحثًا عن أخطاء
  • تأكد من أن معالج الـ webhook لا يرمي استثناءات
  • تأكد من إعادة 200 OK حتى لو فشلت المعالجة

فشل التحقق من التوقيع​

  • تأكد من استخدام السر الصحيح (سر مفتاح API)
  • تأكد من حساب التوقيع بشكل صحيح
  • تأكد من استخدام جسم الطلب الخام (لا JSON المحلَّل)

الخطوات التالية​