Haulerz
القائمة

توثيق الربط مع Haulerz

هذا الدليل يشرح كيفية ربط نظامك بـ Haulerz لإرسال طلبات التوصيل واستقبال تحديثات حالتها. جميع الطلبات عبر HTTPS وبصيغة JSON.

نظرة عامة

يرسل نظامك طلبات التوصيل إلى Haulerz عبر واجهة برمجية (REST). ينفّذ سائقو Haulerz التوصيل، بينما يرسل Haulerz تحديثات الحالة إلى نظامك عبر Webhook.

  • Base URL: https://partners.staging.haulerz.net
  • جميع الطلبات تتطلب ترويسة Authorization.
  • البيئة (تجريبية/إنتاج) تُحدَّد تلقائيًا من نوع المفتاح المستخدم.

المصادقة

يُرسل مفتاح API في ترويسة Authorization بصيغة Bearer. لكل شريك مفتاحان:

  • مفتاح تجريبي (Sandbox): hlz_sk_test_... — لا يؤثر على الطلبات الحقيقية.
  • مفتاح إنتاج (Production): hlz_sk_live_... — طلبات حقيقية تصل للسائقين.
Authorization: Bearer hlz_sk_test_...

⚠️ احفظ مفاتيحك بأمان ولا تشاركها في الواجهات الأمامية أو المستودعات العامة.

إنشاء طلب — POST /api/v1/partners/orders

ينشئ طلب توصيل جديدًا. الحقول متوافقة مع مسميات نظامكم (LogesTechs) لتسهيل الربط.

الترويسات (Headers)

المفتاحالقيمةإلزامي
AuthorizationBearer <API_KEY>✅
Content-Typeapplication/json✅
Idempotency-Keyمعرّف فريد لمنع التكراراختياري (موصى به)

جسم الطلب (Request Body)

{
  "invoiceNumber": "TARD-2026-99817",   // رقم طلبكم (مطلوب) — يُعاد في كل تحديث
  "shipmentType": "REGULAR",            // REGULAR (الافتراضي) | COD — اختياري
  "cod": 0,                             // مطلوب (> 0) فقط عندما shipmentType = COD
  "currency": "SAR",
  "notes": "طرد إلكترونيات — الدور الثالث",

  "package": {
    "description": "إلكترونيات",        // اختياري — الافتراضي: "شحنة طرد #<رقم الطلب>"
    "quantity": 1,
    "weight": 2.5,                      // كجم
    "declaredValue": 350.00
  },

  "originAddress": {                    // عنوان الاستلام
    "contactName": "مستودع طرد",         // مطلوب
    "contactPhone": "+966511111111",    // مطلوب
    "addressLine1": "الرياض، حي العليا", // مطلوب
    "addressLine2": "البوابة الخلفية",
    "shortAddress": "RCTB4359",         // العنوان الوطني المختصر — أو أرسل latitude+longitude
    "latitude": 24.7136,                // اختياري إن أرسلت shortAddress
    "longitude": 46.6753,               // اختياري إن أرسلت shortAddress
    "cityId": 1                         // اختياري (وصفي فقط)
  },

  "destinationAddress": {              // عنوان التسليم
    "contactName": "محمد أحمد",         // مطلوب
    "contactPhone": "+966500000000",   // مطلوب
    "addressLine1": "الرياض، حي النخيل", // مطلوب
    "shortAddress": "RRRA2929"          // العنوان الوطني المختصر — أو أرسل latitude+longitude
  },

  "scheduledAt": null                  // اختياري (ISO 8601) للجدولة المسبقة
}
📍 تحديد الموقع (لكل من الاستلام والتسليم):
  • يجب أن يحتوي كل عنوان على أحد الخيارين: إمّا الإحداثيات latitude + longitude، أو العنوان الوطني السعودي المختصر shortAddress.
  • صيغة العنوان المختصر: 4 أحرف إنجليزية + 4 أرقام (مثال: RCTB4359). نقوم باستخراج الإحداثيات منه تلقائيًا.
  • إذا أرسلت الإحداثيات والعنوان المختصر معًا، فإن الإحداثيات الصريحة لها الأولوية.
  • cityId حقل اختياري ووصفي فقط — لا يُستخدم لتحديد الموقع ولا يُغني عن الإحداثيات أو العنوان المختصر.
💳 الدفع ونوع الشحنة (shipmentType):

كل طلب يتضمّن مبلغين منفصلين تمامًا:

  • أجرة التوصيل (رسوم Haulerz): تُخصم دائمًا من محفظتكم المدفوعة مسبقًا (Prepaid Wallet) في جميع الحالات — بغضّ النظر عن نوع الشحنة. لا يُرفض الطلب عند نقص الرصيد.
  • مبلغ الـ COD (قيمة البضاعة): يُحصّله السائق نقدًا من المستلم عند التسليم، ويُرسله فقط عندما تكون الشحنة COD.
shipmentTypeأجرة التوصيلتحصيل من المستلمحقل cod
REGULARمن المحفظةلا يوجديُتجاهل / 0
CODمن المحفظةقيمة البضاعة نقدًامطلوب (> 0)

الافتراضي: shipmentType اختياري — إذا لم تُرسله يُعتبر REGULAR تلقائيًا (الدفع بالكامل من المحفظة، ولا تحصيل من المستلم). استخدم COD فقط عندما يجب على السائق تحصيل قيمة البضاعة نقدًا.

الاستجابة (201 Created)

{
  "success": true,
  "environment": "sandbox",
  "data": {
    "barcode": "HLZ-SBX-000123",
    "haulerz_order_id": 123,
    "invoiceNumber": "TARD-2026-99817",
    "status": "PENDING_CUSTOMER_CARE_APPROVAL",
    "status_label": "Submitted",
    "tracking_url": "https://track.haulerz.com/HLZ-SBX-000123",
    "created_at": "2026-07-08T18:00:00Z"
  }
}

مثال cURL

curl -X POST https://partners.staging.haulerz.net/api/v1/partners/orders \
  -H "Authorization: Bearer hlz_sk_test_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 4f9c-8821-a1" \
  -d '{ "invoiceNumber": "TARD-2026-99817", "shipmentType": "REGULAR",
        "package": {"description":"إلكترونيات"},
        "originAddress": {"contactName":"مستودع طرد","contactPhone":"+966511111111","addressLine1":"الرياض","shortAddress":"RCTB4359"},
        "destinationAddress": {"contactName":"محمد","contactPhone":"+966500000000","addressLine1":"الرياض","shortAddress":"RRRA2929"} }'

استعلام الحالة — GET /api/v1/partners/orders/{ref}

يرجع الحالة الحالية وسجل الحالات. {ref} يمكن أن يكون barcode الصادر منّا أو invoiceNumber الخاص بكم.

curl https://partners.staging.haulerz.net/api/v1/partners/orders/TARD-2026-99817 \
  -H "Authorization: Bearer hlz_sk_test_..."
{
  "success": true,
  "environment": "sandbox",
  "data": {
    "barcode": "HLZ-SBX-000123",
    "invoiceNumber": "TARD-2026-99817",
    "status": "OUT_FOR_DELIVERY",
    "status_label": "Out for delivery",
    "history": [
      { "status": "PENDING_CUSTOMER_CARE_APPROVAL", "label": "Submitted", "at": "..." },
      { "status": "OUT_FOR_DELIVERY", "label": "Out for delivery", "at": "..." }
    ]
  }
}

فحص الاتصال — GET /api/v1/ping

للتحقق من صحة المفتاح والاتصال قبل البدء.

curl https://partners.staging.haulerz.net/api/v1/ping \
  -H "Authorization: Bearer hlz_sk_test_..."

{ "success": true, "environment": "sandbox",
  "data": { "message": "pong", "partner": "طرد (Tard)" } }

حالات الطلب

يمر الطلب بالحالات التالية. نرسل تحديثًا (Webhook) عند كل حالة مُعلَّمة بـ ✅:

حالة HaulerznewStatus (نظامكم)الوصفWebhook
Confirmed APPROVED_BY_CUSTOMER_CARE_AND_WAITING_FOR_DISPATCHER تم قبول الطلب وهو بانتظار إسناد سائق ✅
Picked Up SCANNED_BY_DRIVER_AND_IN_CAR استلم السائق الشحنة ✅
Out for Delivery OUT_FOR_DELIVERY الشحنة في الطريق للعميل ✅
Delivered DELIVERED_TO_RECIPIENT تم التسليم بنجاح ✅
Cancelled CANCELLED تم إلغاء الطلب ✅

حالات مثل FAILED و POSTPONED_DELIVERY و RETURNED_BY_RECIPIENT مخطط لها في مرحلة لاحقة.

تحديثات الحالة (Webhooks)

عند تغيّر حالة الطلب، يرسل Haulerz طلب POST إلى الرابط الذي تزوّدونا به (webhookUrl) بالصيغة التالية المتوافقة مع نظامكم:

POST <your-webhook-url>
X-Haulerz-Signature: <hmac-sha256>
X-Haulerz-Event: order.status_updated

{
  "packageId": 123,
  "newStatus": "DELIVERED_TO_RECIPIENT",
  "barcode": "HLZ-2026-000123",
  "invoiceNumber": "TARD-2026-99817",
  "cod": 0,
  "time": 1762347300095,
  "notes": null,
  "driverName": "اسم السائق",
  "driverPhone": "05xxxxxxxx"
}
  • invoiceNumber هو مفتاح المطابقة مع طلبكم الأصلي.
  • نوقّع كل طلب بترويسة X-Haulerz-Signature (HMAC-SHA256) للتحقق.
  • يُتوقّع أن يردّ نظامكم بـ 2xx خلال ثوانٍ لتأكيد الاستلام.

الأخطاء

جميع الأخطاء تتبع الصيغة الموحّدة:

{
  "success": false,
  "error": {
    "code": "validation_failed",
    "message": "One or more fields are invalid.",
    "details": [{ "field": "destinationAddress.contactPhone", "issue": "required" }]
  }
}
HTTPcodeالمعنى
400 invalid_request جسم الطلب غير صالح / JSON تالف
401 unauthorized مفتاح API مفقود
403 invalid_api_key مفتاح API غير صالح
405 method_not_allowed طريقة HTTP غير مدعومة
409 duplicate_order طلب مكرر (نفس invoiceNumber)
422 validation_failed فشل التحقق من الحقول
500 server_error خطأ داخلي