Shipper Open API

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

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

البداية

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

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

للبدء، أنشئ مفتاح API من لوحة تحكم Shipperفي التكاملات > 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
مرجع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,
      "status": "active",
      "available_qte": 42,
      "variants": [
        {
          "uuid": "a1b2c3d4-5678-9012-abcd-ef0123456789",
          "name": "Size L",
          "sku": "SKU-001-L",
          "price": 190,
          "available_qte": 15
        }
      ]
    }
  ],
  "pagination": { "total": 50, "current_page": 1, "per_page": 10, "last_page": 5 }
}

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,
  "status": "active",
  "available_qte": 42,
  "variants": [
    { "uuid": "a1b2c3d4-...", "name": "Size L", "sku": "SKU-001-L", "price": 190, "available_qte": 15 },
    { "uuid": "e5f6a7b8-...", "name": "Size M", "sku": "SKU-001-M", "price": 190, "available_qte": 27 }
  ]
}

الطلبات

GETGET /orders

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

معلمات الاستعلام
المعلمةالنوعمطلوبالوصف
pageinteger-رقم الصفحة (افتراضي: 1)
per_pageinteger-عناصر في الصفحة (افتراضي: 20، أقصى: 100)
statusstring-تصفية حسب حالة الشحنة (مثل delivered، awaitingpackaging، canceled)
start_datestring-تصفية الطلبات المنشأة في أو بعد هذا التاريخ (YYYY-MM-DD)
end_datestring-تصفية الطلبات المنشأة في أو قبل هذا التاريخ (YYYY-MM-DD)
searchstring-البحث برقم الطلب أو اسم العميل أو رقم الهاتف
مثال طلب
curl "https://server.shipper.network/api/v1/orders?status=delivered&start_date=2025-01-01&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": "2025-01-10T10:00:00.000000Z",
      "address": { "first_name": "Omar", "last_name": "Ben Ali", "phone1": "+21628177188" },
      "items_count": 2,
      "shipments_count": 1,
      "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 }
}

POSTPOST /orders

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

جسم الطلب
المعلمةالنوعمطلوبالوصف
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-معرف مرجع الطلب في نظامك - يظهر في لوحة تحكم Shipper
external_order_urlstring-رابط الطلب في نظامك - قابل للنقر من لوحة تحكم Shipper
مثال طلب
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"
}

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

عند حدوث حدث، يرسل Shipper طلب 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-Shipper-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طلبات كثيرة جداً - تم تجاوز حد المعدل. انتظر وأعد المحاولة