شيبر Open API

ادمج نظامك مع شيبر لإنشاء وتتبع الطلبات برمجياً.

v1https://server.shipper.network/api/v1Postmanتحميل مجموعة Postman

البداية

شيبر Open API هي واجهة برمجة REST تتيح لك:

  • إنشاء الطلبات تلقائياً من نظامك
  • استرجاع تفاصيل الطلبات وتتبع الشحنات
  • عرض والبحث في منتجاتك وطلباتك
  • إلغاء الطلبات برمجياً
  • تلقي تحديثات الحالة الفورية عبر webhooks

للبدء، أنشئ مفتاح API من لوحة تحكم شيبرفي التكاملات > API.


المصادقة

جميع طلبات API تتطلب رمز Bearer في رأس Authorization.

Authorization: Bearer YOUR_API_KEY
Accept: application/json
Content-Type: application/json
حدود المعدل

الطلبات محدودة المعدل لكل مفتاح API. تجاوز الحد يعيد HTTP 429 (طلبات كثيرة جداً).

نوع النقطةالحدالنقاط
قراءة120طلب/دقيقةGET /products, /orders, /orders/:id, /webhooks
لوحة التحكم30طلب/دقيقةGET /dashboard/*
مرجع60طلب/دقيقةGET /countries, /countries/:code/divisions
كتابة30طلب/دقيقةPOST /orders, /webhooks
تدميري20طلب/دقيقةPOST /orders/:id/cancel, DELETE /webhooks/:id

رؤوس حد المعدل (X-RateLimit-Limit، X-RateLimit-Remaining) مضمنة في كل استجابة.


الجغرافيا

GETGET /countries

يعيد جميع البلدان المدعومة مع هيكلها الجغرافي. استخدمه لفهم مستويات التقسيم الإداري المطلوبة (ولاية، معتمدية، إلخ) لكل بلد.

مثال طلب
curl https://server.shipper.network/api/v1/countries \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
الاستجابة

200

[
  {
    "code": "TN",
    "name": "Tunisia",
    "geo_structure": {
      "fields": [
        { "id": "division_1_id", "label": "Governorate", "level": 1, "required": true, "depends_on": null },
        { "id": "division_2_id", "label": "Delegation", "level": 2, "required": true, "depends_on": "division_1_id" }
      ]
    }
  }
]

مصفوفة geo_structure.fields تخبرك بعدد مستويات التقسيم وتسمياتها والتبعيات. استخدم depends_on لبناء قوائم متتالية.

GETGET /countries/{code}/divisions

يعيد أسماء التقسيمات لبلد معين. استخدمه للحصول على القيم الصحيحة لـ address.division_1 و address.division_2 عند إنشاء الطلبات.

معلمات الاستعلام
المعلمةالنوعمطلوبالوصف
levelinteger-مستوى التقسيم (افتراضي: 1 = المستوى الأعلى)
parent_idinteger-تصفية حسب معرف التقسيم الأب للحصول على الأبناء
مثال: التقسيمات الرئيسية
curl https://server.shipper.network/api/v1/countries/TN/divisions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
{
  "country": "TN",
  "geo_structure": { ... },
  "divisions": [
    { "id": 1, "name": "Tunis", "level": 1, "parent_id": null },
    { "id": 2, "name": "Sfax", "level": 1, "parent_id": null },
    { "id": 3, "name": "Sousse", "level": 1, "parent_id": null }
  ]
}
مثال: التقسيمات الفرعية تحت تقسيم أب
curl "https://server.shipper.network/api/v1/countries/TN/divisions?level=2&parent_id=1" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
{
  "country": "TN",
  "geo_structure": { ... },
  "divisions": [
    { "id": 10, "name": "Bab El Bhar", "level": 2, "parent_id": 1 },
    { "id": 11, "name": "Bab Souika", "level": 2, "parent_id": 1 },
    { "id": 12, "name": "Carthage", "level": 2, "parent_id": 1 }
  ]
}

المنتجات

GETGET /products

يعيد كتالوج منتجاتك مع معرفات UUID. تحتاج UUID المنتج لإنشاء الطلبات عبر API.

معلمات الاستعلام
المعلمةالنوعمطلوبالوصف
pageinteger-رقم الصفحة (افتراضي: 1)
per_pageinteger-عناصر في الصفحة (افتراضي: 20، أقصى: 100)
searchstring-بحث باسم المنتج أو SKU
مثال طلب
curl "https://server.shipper.network/api/v1/products?per_page=10&search=shirt" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
الاستجابة

200

{
  "data": [
    {
      "uuid": "2e97b37a-3118-4905-842c-19706bcf1455",
      "name": "Blue T-Shirt",
      "sku": "SKU-001",
      "price": 190,
      "cost": 75,
      "status": "active",
      "link": "https://app.shipper.market/products/2e97b37a-3118-4905-842c-19706bcf1455",
      "supplier_identifier": "RU836",
      "available_qte": 42,
      "variants": [
        {
          "uuid": "a1b2c3d4-5678-9012-abcd-ef0123456789",
          "name": "Size L",
          "sku": "SKU-001-L",
          "price": 190,
          "cost": 75,
          "available_qte": 15
        }
      ]
    }
  ],
  "pagination": { "total": 50, "current_page": 1, "per_page": 10, "last_page": 5 }
}
ملاحظات حقول الاستجابة
  • price — سعر البيع الخاص بك (الذي يدفعه العميل)، بعملة منظمتك.
  • cost — تكلفة المورد (المبلغ الذي تدفعه للمورد لكل وحدة). متاح على المنتج وعلى كل متغير.
  • link — رابط Shipper Market قابل للمشاركة لهذا المنتج (مفيد لفريقك أو للتسويق).
  • supplier_identifier — اسم المستخدم في شيبر للمورد (مثل RU836). يحدد المورد الذي ينفذ المنتج.
  • available_qte — إجمالي وحدات المخزون المتاحة عبر المستودعات النشطة (مجموع public_stocks.qte).

GETGET /products/{uuid}

يعيد منتجاً واحداً بمعرف UUID، بما في ذلك المتغيرات والكميات المتوفرة.

مثال طلب
curl https://server.shipper.network/api/v1/products/2e97b37a-3118-4905-842c-19706bcf1455 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
الاستجابة

200

{
  "uuid": "2e97b37a-3118-4905-842c-19706bcf1455",
  "name": "Blue T-Shirt",
  "sku": "SKU-001",
  "price": 190,
  "cost": 75,
  "status": "active",
  "link": "https://app.shipper.market/products/2e97b37a-3118-4905-842c-19706bcf1455",
  "supplier_identifier": "RU836",
  "available_qte": 42,
  "variants": [
    { "uuid": "a1b2c3d4-...", "name": "Size L", "sku": "SKU-001-L", "price": 190, "cost": 75, "available_qte": 15 },
    { "uuid": "e5f6a7b8-...", "name": "Size M", "sku": "SKU-001-M", "price": 190, "cost": 75, "available_qte": 27 }
  ]
}

الطلبات

GETGET /orders

يعيد قائمة مرقمة من طلباتك. استخدم الفلاتر للتصفية حسب الحالة أو نطاق التاريخ أو مصطلحات البحث.

معلمات الاستعلام
المعلمةالنوعمطلوبالوصف
pageinteger-رقم الصفحة (افتراضي: 1)
per_pageinteger-عناصر في الصفحة (افتراضي: 20، أقصى: 100)
statusstring-تصفية حسب حالة الشحنة (مثل delivered، awaitingpackaging، canceled)
start_datestring-تصفية الطلبات المنشأة في أو بعد هذا التاريخ/الوقت. يقبل YYYY-MM-DD (يُفسَّر كـ 00:00:00) أو YYYY-MM-DD HH:MM[:SS] للدقة بالدقيقة.
end_datestring-تصفية الطلبات المنشأة في أو قبل هذا التاريخ/الوقت. مدخلات التاريخ فقط (YYYY-MM-DD) تشمل اليوم بأكمله؛ YYYY-MM-DD HH:MM[:SS] للدقة بالدقيقة.
searchstring-البحث برقم الطلب أو اسم العميل أو رقم الهاتف
مثال طلب
curl "https://server.shipper.network/api/v1/orders?status=delivered&start_date=2026-05-01%2009:00&per_page=10" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
الاستجابة

200

{
  "data": [
    {
      "id": 555,
      "status": "Paid",
      "store_name": "My Store",
      "is_cod": true,
      "is_paid": true,
      "created_at": "2026-05-10T10:00:00.000000Z",
      "address": { "first_name": "Omar", "last_name": "Ben Ali", "phone1": "+21628177188" },
      "items_count": 3,
      "shipments_count": 1,
      "products": [
        { "id": 442, "name": "Smart Sensor Light Toilet Lid" }
      ],
      "revenue": "59",
      "external_order_id": "ORD-123",
      "external_order_url": "https://mystore.com/orders/123"
    }
  ],
  "pagination": { "total": 150, "current_page": 1, "per_page": 10, "last_page": 15 }
}
ملاحظات حقول الاستجابة
  • status — محسوب من شحنات الطلب. القيم الممكنة: Pending، Fulfilled، In Transit، Delivered، Partial Delivery، Returned، Partial Return، Canceled، Paid. قد يكون أيضاً null للطلبات التي لا تحتوي على شحنات بعد.
  • items_count — إجمالي الوحدات المطلوبة (مجموع الكميات عبر عناصر السلة).
  • products — منتجات بائع متميزة مُشار إليها في الطلب. فارغ للطلبات التي لم يتم تنفيذها بعد.
  • revenue — مجموع معاملات إيرادات شحنات البائع بحالة Successful أو Under Review (أي المُحقَّقة + المُكتسَبة-قيد-التسوية). يُبلَّغ عنها بعملة منظمتك، كسلسلة عشرية بسيطة. صفر حتى يتم تسليم شحنة واحدة على الأقل.

POSTPOST /orders

ينشئ طلباً جديداً في شيبر. يعيد معرف الطلب الذي يمكنك استخدامه لتتبع الطلب.

جسم الطلب
المعلمةالنوعمطلوبالوصف
addressobject*كائن عنوان المستلم (انظر الحقول أدناه)
address.namestring*الاسم الكامل - يقسم تلقائياً إلى الاسم الأول واللقب
address.phone1string*رقم الهاتف الرئيسي
address.phone2string-رقم الهاتف الثانوي
address.address1string*العنوان السطر 1
address.address2string-العنوان السطر 2
address.division_1string-الولاية - استخدم الاسم الدقيق من GET /countries/{code}/divisions
address.division_2string-المعتمدية - استخدم الاسم الدقيق من GET /countries/{code}/divisions?level=2&parent_id=...
address.countrystring*رمز البلد من حرفين (مثل TN، DZ، MA)
itemsarray*مصفوفة عناصر الطلب
items[].idstring*UUID المنتج أو المتغير من GET /products
items[].quantityinteger-الكمية (افتراضي: 1)
items[].total_pricenumber-السعر الإجمالي لهذا العنصر. الافتراضي: سعر المنتج × الكمية
shipping_totalnumber-تكلفة الشحن المحملة على العميل (افتراضي: 0)
is_codboolean-)
auto_fulfillboolean-إرسال مباشرة للتجهيز دون إنشاء مسودة (افتراضي: false)
with_confirmationboolean-طلب مكالمة تأكيد هاتفية قبل الشحن (افتراضي: false)
store_namestring-اسم المتجر المصدر - يظهر في تتبع الطلب كمرجع لك
external_order_idstring-معرف مرجع الطلب في نظامك - يظهر في لوحة تحكم شيبر
external_order_urlstring-رابط الطلب في نظامك - قابل للنقر من لوحة تحكم شيبر
مثال طلب
curl -X POST https://server.shipper.network/api/v1/orders \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "address": {
      "name": "Omar Ben Ali",
      "division_1": "Tunis",
      "division_2": null,
      "phone1": "28177188",
      "address1": "Rue de la Liberte",
      "country": "TN"
    },
    "items": [
      { "quantity": 1, "id": "YOUR_PRODUCT_UUID", "total_price": 190 }
    ],
    "shipping_total": 9,
    "is_cod": true,
    "auto_fulfill": true,
    "with_confirmation": true,
    "store_name": "My Store",
    "external_order_id": "ORD-12345",
    "external_order_url": "https://mystore.com/orders/12345"
  }'
الاستجابة

201تم الإنشاء

{
  "id": 555
}

GETGET /orders/{id}

يعيد تفاصيل الطلب الكاملة بما في ذلك الحالة الحالية وأرقام تتبع الشحنات مع سجلات التسليم وعنوان المستلم.

معلمات المسار
المعلمةالنوعمطلوبالوصف
idinteger*معرف الطلب الذي أُعيد عند إنشاء الطلب
مثال طلب
curl https://server.shipper.network/api/v1/orders/555 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
الاستجابة

200

{
  "id": 555,
  "status": "Paid",
  "contact_task_status": "called",
  "shipments": [
    {
      "uuid": "11111111-2222-3333-4444-555555555555",
      "status": "delivered",
      "tracking_numbers": [
        {
          "number": "99999999999",
          "logs": [
            { "status": "at_carrier_origin_facility", "created_at": "2025-01-15T02:02:59.000000Z", "external_timestamp": "2025-01-14 22:48:00" },
            { "status": "in_transit", "created_at": "2025-01-15T02:02:59.000000Z", "external_timestamp": "2025-01-14 23:05:00" },
            { "status": "delivered", "created_at": "2025-01-18T02:09:19.000000Z", "external_timestamp": "2025-01-17 14:16:00" }
          ]
        }
      ]
    }
  ],
  "address": {
    "first_name": "Omar", "last_name": "Ben Ali",
    "phone1": "+21628177188", "phone2": "",
    "address1": "Rue de la Liberte", "address2": "",
    "division_1": "Tunis", "division_2": null, "country": "TN"
  }
}

POSTPOST /orders/{id}/cancel

يلغي طلباً وشحناته المرتبطة. يعمل للطلبات في مرحلة التأكيد (انتظار التأكيد الهاتفي) أو مرحلة التحضير (انتظار التغليف). الطلبات التي تم شحنها لا يمكن إلغاؤها عبر API.

معلمات المسار
المعلمةالنوعمطلوبالوصف
idinteger*معرف الطلب المراد إلغاؤه
مثال طلب
curl -X POST https://server.shipper.network/api/v1/orders/555/cancel \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
الاستجابة

200

{
  "success": true,
  "canceled_shipments": 1
}
استجابة الخطأ

422إذا لم يكن هناك شحنات قابلة للإلغاء:

{
  "error": "No shipments available to cancel"
}

لوحة التحكم

نقاط نهاية للإحصائيات المجمعة التي تدعم لوحة تحكم البائع. تتطلب جميع المسارات رمز API لمنظمة بائع؛ الرموز غير الخاصة بالبائع تتلقى استجابة HTTP 403.

GETGET /dashboard/overview

تقسيم الإيرادات / المصاريف / الربح للشحنات، مصنفة حسب الحالة (قيد الانتظار، مُسلَّمة-مدفوعة، مُسلَّمة-غير-مدفوعة، فشل التسليم). كل مجموعة تعرض تقسيمات المصاريف لكل بند وتجميعات فرعية حسب نوع الطلب.

مثال طلب
curl "https://server.shipper.network/api/v1/dashboard/overview?start_date=2026-04-01&end_date=2026-04-30" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
الاستجابة

200

{
  "shipments_pending":            { /* StatusGroup, see below */ },
  "shipments_delivered_paid":     { ... },
  "shipments_delivered_non_paid": { ... },
  "shipments_failed_delivery":    { ... },
  "stats_by_order_type": [
    {
      "order_type": "dropshipping",
      "shipments_pending":            { ... },
      "shipments_delivered_paid":     { ... },
      "shipments_delivered_non_paid": { ... },
      "shipments_failed_delivery":    { ... }
    }
  ]
}
بنية StatusGroup
{
  "status": "shipments_delivered_paid",
  "count": 133,
  "orders_with_revenue_count": 129,
  "revenue":              [{ "amount": "9750.00", "currency": { "id": "1", "ISO_4217": "TND", "symbol": "د.ت", "decimals": 3 } }],
  "revenue_expected":     [...],
  "revenue_transferred":  [...],
  "expenses":             [...],
  "expenses_transferred": [...],
  "expenses_expected":    [...],
  "net_profits":          [...],
  "expenses_breakdown": {
    "shipping":         [...],
    "packaging":        [...],
    "service":          [...],
    "qc":               [...],
    "payment_facility": [...],
    "confirmation":     [...],
    "call_forwarding":  [...],
    "follow_up":        [...],
    "upsell":           [...],
    "prepaid_cost":     [...],
    "product_cost":     [...],
    "dropshipping_fee": [...],
    "return_exchange_fee": [...]
  },
  "expenses_breakdown_transferred": { /* same 13 keys */ }
}

الحقول النقدية هي مصفوفات من {amount, currency} للتوافق المستقبلي مع البائعين متعددي العملات؛ حالياً يتم إرجاع إدخال واحد بعملة المنظمة الافتراضية. القيم هي سلاسل عشرية للحفاظ على الدقة (المعاملات تُخزَّن بـ decimal(65,30)).

GETGET /dashboard/delivery-stats

أعداد حسب حالة الشحنة، تقسيم أسباب فشل التوصيل، ومؤشرات أداء سرعة التوصيل بأيام العمل. محدد لطلبات الدروبشيبينغ.

مثال طلب
curl "https://server.shipper.network/api/v1/dashboard/delivery-stats?start_date=2026-04-01&end_date=2026-04-30" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
الاستجابة

200

{
  "total_by_status": [
    { "status": "delivered", "count": 4843, "on_hold_count": 0 },
    { "status": "canceled",  "count": 238,  "on_hold_count": 0 },
    { "status": "returnedtosender", "count": 28, "on_hold_count": 0 }
  ],
  "total_delivery_failures_by_reason": [
    { "reason": "Customer unavailable for delivery", "count": 993 },
    { "reason": "Trust or credibility issues at delivery", "count": 136 },
    { "reason": null, "count": 565 }
  ],
  "avg_delivery_speed_business_days": 1.6,
  "max_delivery_speed_business_days": 28,
  "delivered_within_1bd_pct": 66.3,
  "delivered_within_2bd_pct": 21,
  "delivered_over_2bd_pct":   12.7
}

GETGET /dashboard/confirmation-stats

إحصائيات قمع العملاء المحتملين وتحويل التوصيل للطلبات المؤكدة من خلال خدمة تأكيد خارجية لشيبر.

مثال طلب
curl "https://server.shipper.network/api/v1/dashboard/confirmation-stats?start_date=2026-04-01&end_date=2026-04-30" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
الاستجابة

200

{
  "has_stats": true,
  "stats": {
    "leads": {
      "total": 5484,
      "confirmed": 3371,
      "failed": 599,
      "closed_unreachable": 1068,
      "closed_unconfirmed": 445,
      "under_process": 1,
      "no_attempt": 0
    },
    "delivery_rates": {
      "delivered": 2240,
      "failed": 1072,
      "returning": 13,
      "in_transit": 8,
      "not_shipped": 12,
      "total_pipeline": 3345,
      "total_final": 3312,
      "overall_rate": 66.97,
      "absolute_rate": 67.63
    }
  }
}

has_stats تكون false عندما لا يكون لدى المنظمة أي طلبات مُمرَّرة عبر التأكيد الخارجي؛ سيكون stats هو null في تلك الحالة.

GETGET /dashboard/internal-confirmation-stats

نفس البنية كـ /dashboard/confirmation-stats، لكن محدد للطلبات التي أكدها البائع داخلياً (دون استخدام خدمة تأكيد شيبر). مفيد للبائعين الذين يديرون كلا التدفقين بالتوازي.

مثال طلب
curl "https://server.shipper.network/api/v1/dashboard/internal-confirmation-stats" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
الاستجابة

200 — بنية مطابقة لـ /dashboard/confirmation-stats. عندما لا يكون لدى البائع أي طلبات مؤكدة داخلياً، تكون has_stats قيمتها false وstats قيمتها null:

{
  "has_stats": false,
  "stats": null
}

GETGET /dashboard/product-performance

أداء كل منتج، مُقسَّم على صفحات وقابل للترتيب: أعداد الشحنات والوحدات عبر الحالات، بالإضافة إلى قمع التأكيد لكل منتج ونفس التجميعات حسب الحالة كما في /dashboard/overview.

معلمات الاستعلام
المعلمةالنوعمطلوبالوصف
pageinteger-رقم الصفحة (افتراضي: 1)
per_pageinteger-العناصر لكل صفحة (افتراضي: 20، الحد الأقصى: 50)
sort_bystring-إحدى القيم التالية: shipped_orders, delivered_orders, failed_orders, confirmed_return_orders, in_transit_orders, returning_orders, leads_total, leads_confirmed, overall_confirmation_rate, absolute_confirmation_rate, conversion_rate. الافتراضي: shipped_orders. القيم غير الصحيحة تُرجِع 422.
start_datestring-مرشح تاريخ اختياري (انظر مقدمة لوحة التحكم).
end_datestring-مرشح تاريخ اختياري (انظر مقدمة لوحة التحكم).
retailer_product_idinteger-تحديد منتج واحد للبائع.
مثال طلب
curl "https://server.shipper.network/api/v1/dashboard/product-performance?per_page=10&sort_by=delivered_orders" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
الاستجابة

200

{
  "products": [
    {
      "retailer_product_id": "550",
      "name": "SMOKURE STOP TABAC 40 CAPSULES",
      "shipped_orders": 2351,   "shipped_units": 2418,
      "delivered_orders": 1442, "delivered_units": 1487,
      "failed_orders": 898,     "failed_units": 921,
      "in_transit_orders": 12,  "in_transit_units": 13,
      "returning_orders": 4,    "returning_units": 4,
      "confirmed_return_orders": 320, "confirmed_return_units": 327,
      "leads_total": 3531,
      "leads_confirmed": 2374,
      "leads_failed": 121,
      "leads_unreachable": 715,
      "leads_duplicate_wrong": 18,
      "leads_closed_other": 303,
      "overall_confirmation_rate": 67.2,
      "absolute_confirmation_rate": 70.5,
      "conversion_rate": 40.8,
      "shipments_pending":            { /* StatusGroup */ },
      "shipments_delivered_paid":     { ... },
      "shipments_delivered_non_paid": { ... },
      "shipments_failed_delivery":    { ... }
    }
  ],
  "total": 127
}

يعتمد التقسيم إلى صفحات على page/per_page؛ تحمل الاستجابة فقط العدد الإجمالي. احسب last_page كـ Math.ceil(total / per_page).


Webhooks

تتيح لك Webhooks تلقي إشعارات HTTP فورية عند تغيير حالة الطلب أو الشحنة، بدلاً من الاستعلام المتكرر عن API.

POSTPOST /webhooks

سجل رابطاً لتلقي أحداث webhook. يمكنك تسجيل حتى 5 webhooks لكل مفتاح API. يجب أن يستخدم الرابط HTTPS.

جسم الطلب
المعلمةالنوعمطلوبالوصف
urlstring*رابط HTTPS الذي سيستقبل طلبات POST مع بيانات الحدث
eventsarray*الأحداث للاشتراك: "order.status_changed" و/أو "shipment.status_changed"
secretstring-مفتاح سري (16 حرف كحد أدنى) يُستخدم لتوقيع البيانات بـ HMAC-SHA256 للتحقق
مثال طلب
curl -X POST https://server.shipper.network/api/v1/webhooks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://mystore.com/webhooks/shipper",
    "events": ["order.status_changed", "shipment.status_changed"],
    "secret": "my-webhook-secret-key"
  }'
الاستجابة

201

{
  "id": 1,
  "url": "https://mystore.com/webhooks/shipper",
  "events": ["order.status_changed", "shipment.status_changed"],
  "status": "active",
  "created_at": "2025-03-29T10:00:00.000000Z"
}

GETGET /webhooks

يعيد جميع webhooks المسجلة لمفتاح API الحالي، بما في ذلك حالتها وعدد الإخفاقات.

مثال طلب
curl https://server.shipper.network/api/v1/webhooks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
الاستجابة

200

[
  {
    "id": 1,
    "url": "https://mystore.com/webhooks/shipper",
    "events": ["order.status_changed", "shipment.status_changed"],
    "status": "active",
    "last_triggered_at": "2025-03-29T15:30:00.000000Z",
    "failure_count": 0,
    "created_at": "2025-03-29T10:00:00.000000Z"
  }
]

DELETEDELETE /webhooks/{id}

يحذف تسجيل webhook. سيتوقف webhook عن تلقي الأحداث فوراً.

مثال طلب
curl -X DELETE https://server.shipper.network/api/v1/webhooks/1 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
الاستجابة

200

{ "success": true }

شكل بيانات Webhook

عند حدوث حدث، يرسل شيبر طلب POST إلى رابطك المسجل مع جسم JSON:

order.status_changed
{
  "event": "order.status_changed",
  "timestamp": "2025-01-15T10:30:00.000000Z",
  "data": {
    "order_id": 555,
    "status": "Paid",
    "previous_status": "Pending"
  }
}
shipment.status_changed
{
  "event": "shipment.status_changed",
  "timestamp": "2025-01-15T10:30:00.000000Z",
  "data": {
    "order_id": 555,
    "shipment_uuid": "11111111-2222-3333-4444-555555555555",
    "status": "delivered",
    "previous_status": "onitsway"
  }
}
التحقق من التوقيع

إذا قدمت مفتاحاً سرياً عند تسجيل webhook، يتضمن كل طلب رأس X-شيبر-Signature. تحقق منه بحساب HMAC-SHA256 لجسم الطلب باستخدام مفتاحك السري:

// Node.js example
const crypto = require('crypto');
const signature = crypto.createHmac('sha256', 'my-webhook-secret-key')
  .update(rawBody)
  .digest('hex');
const isValid = signature === req.headers['x-shipper-signature'];

رموز الأخطاء

تستخدم API رموز حالة HTTP القياسية. جميع استجابات الخطأ تتضمن جسم JSON مع التفاصيل.

الرمزالمعنى
200نجاح
201تم إنشاء المورد بنجاح
401غير مصرح - مفتاح API مفقود أو غير صالح
403ممنوع - مفتاح API معطل أو ملغى
404غير موجود - المورد المطلوب غير موجود
422خطأ تحقق - تحقق من كائن الأخطاء في جسم الاستجابة للتفاصيل
429طلبات كثيرة جداً - تم تجاوز حد المعدل. انتظر وأعد المحاولة