Haulerz

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

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

نظرة عامة

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

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

المصادقة

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

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

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

إنشاء طلب — 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.haulerz.com/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.haulerz.com/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.haulerz.com/api/v1/ping \
  -H "Authorization: Bearer hlz_sk_test_..."

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

حالات الطلب

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

حالة HaulerznewStatus (نظامكم)الوصفWebhook
ConfirmedAPPROVED_BY_CUSTOMER_CARE_AND_WAITING_FOR_DISPATCHERتم قبول الطلب وهو بانتظار إسناد سائق
Picked UpSCANNED_BY_DRIVER_AND_IN_CARاستلم السائق الشحنة
Out for DeliveryOUT_FOR_DELIVERYالشحنة في الطريق للعميل
DeliveredDELIVERED_TO_RECIPIENTتم التسليم بنجاح
CancelledCANCELLEDتم إلغاء الطلب

حالات مثل 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المعنى
400invalid_requestجسم الطلب غير صالح / JSON تالف
401unauthorizedمفتاح API مفقود
403invalid_api_keyمفتاح API غير صالح
405method_not_allowedطريقة HTTP غير مدعومة
409duplicate_orderطلب مكرر (نفس invoiceNumber)
422validation_failedفشل التحقق من الحقول
500server_errorخطأ داخلي