تخطَّ إلى المحتوى
للمطورين

واجهة شركات التوصيل (Shipping API)

تستقبل شركتكم طلبات متاجر متاجرة آلياً، وتحدّث حالة كل طرد لتظهر للتاجر والعميل.

الدولةفلسطين (PS)
العملةILSشيكل، رقمان عشريان. مبلغ التحصيل يكون عدداً صحيحاً (المتجر يقرّب الإجمالي).
صيغة الجوال+970 أو +972 ثم 9 أرقام تبدأ بـ 5
مناطق التوصيلwb الضفة الغربية · jer القدس · in48 الداخل (مناطق 48) · gaza قطاع غزة

شركات مربوطة بهذه الواجهة في فلسطين: سندر Snder

1) كيف يعمل الربط

  1. يعطيكم فريق متاجرة مفتاحين: مفتاح اختبار (mtj_test_…) ومفتاح تشغيل (mtj_…). كلٌّ يُعرض مرة واحدة.
  2. عندما يضع التاجر طلباً على «جاري التوصيل» أو «تم الشحن» والعميل اختار شركتكم، يصلكم الطلب: إشعاراً فورياً (Webhook) أو بالسحب من GET /orders.
  3. تحدّثون حالته بـ POST /orders/{id}/status فتظهر فوراً للتاجر والعميل. «سُلّم» تُكمل الطلب في المتجر.
  4. ليس عندكم مبرمج؟ كل ما سبق متاح بالأزرار في بوابة الشركاء ← «طلبات التوصيل».

2) العنوان والتوثيق

Base URL:  https://motajrh.com/api/carrier/v1
Header:    Authorization: Bearer YOUR_KEY
           Accept: application/json

كل الردود JSON. المفتاح الخاطئ يعيد 401. الحد: 240 طلباً في الدقيقة.

3) بيئة الاختبار

بمفتاح الاختبار ترون وتغيّرون طلبات تجريبية فقط، ولا يتأثر أي متجر. أنشئوا طلباً تجريبياً (يُرسل لرابط إشعاراتكم أيضاً)، ثم جرّبوا كل الخطوات عليه:

POST https://motajrh.com/api/carrier/v1/test/orders          → 201 { "order": { "id": 7, "order_number": "TEST-AB12CD", "test": true, … } }
GET  https://motajrh.com/api/carrier/v1/me                   → { "company": "…", "mode": "test", "open_orders": 1, "zones": { … } }

بمفتاح التشغيل تعيد هذه النقطة 403. تحديث الأسعار والتحصيل بمفتاح الاختبار يُفحص ولا يُحفظ.

4) قائمة الطلبات

GET https://motajrh.com/api/carrier/v1/orders?status=new&limit=50&after_id=0
المعاملالوصف
statusnew, accepted, picked, out, delivered, returned, failed, cancelled
sinceالطلبات التي تغيّرت منذ هذا الوقت (ISO 8601)
after_idللصفحة التالية: قيمة next_after_id من الرد السابق
limitمن 1 إلى 100 (الافتراضي 50)
{
  "orders": [{
    "id": 1024,
    "order_number": "MA-10501",
    "status": "new",
    "tracking_number": null,
    "cod_amount": 122,          // المبلغ المطلوب تحصيله (0 = مدفوع)
    "currency": "ILS",
    "test": false, "settled": false, "settlement_ref": null,
    "created_at": "2026-10-08T12:10:00+03:00",
    "store":     { "id": 551, "name": "Magic Veil", "phone": "+970568823256", "url": "https://magicveil.motajrh.com",
                   "lat": 32.2211, "lng": 35.2544 },
    "pickup":    { "city": "نابلس", "district": "", "address": "…",
                   "lat": 32.2211, "lng": 35.2544 },
    "recipient": { "name": "…", "phone": "+970568823256", "country": "فلسطين",
                   "zone": "wb", "zone_name": "الضفة الغربية", "region": "", "city": "نابلس",
                   "district": "", "address": "رفيديا، شارع الجامعة", "note": "",
                   "lat": 32.227, "lng": 35.242 },
    "items":     [{ "name": "…", "sku": "PRF1", "quantity": 1 }],
    "order_total": 122, "delivery_fee": 20, "paid": false,
    "quote_id": null, "distance_km": null,     // إن كنتم تسعّرون لحظياً: رقم عرض السعر الذي رآه العميل
    "account": "store"                        // من يدفع لكم الأجرة: store حساب المتجر عندكم، platform حساب المنصة الواحد
  }],
  "has_more": false,
  "next_after_id": null
}

حقول الطلب: أين تجدون كل معلومة

المعلومةالحقلملاحظة
رقم الطلب عندناid, order_numberid رقم ثابت تستعملونه في الروابط؛ order_number ما يراه التاجر والعميل
رقم الطلب عندكمtracking_numberترسلونه أنتم مع أول تحديث للحالة، ونحفظه ونعرضه للتاجر والعميل
معرّف المتجرstore.idرقم ثابت لكل متجر عندنا: احفظوا به موقع المتجر مرة واحدة
اسم المتجرstore.name
جوال المتجرstore.phoneجوال فرع الاستلام
إحداثيات المتجرstore.lat, store.lng = pickup.lat, pickup.lngموقع فرع الاستلام كما حدّده التاجر على الخريطة: أرقام عشرية (WGS84)، خط العرض lat ثم خط الطول lng. null إن لم يحدّده بعد
عنوان المتجرpickup.city, pickup.district, pickup.address
اسم العميلrecipient.name
جوال العميلrecipient.phoneبالصيغة الدولية: +970 أو +972 ثم 9 أرقام تبدأ بـ 5
إحداثيات العميلrecipient.lat, recipient.lngالموقع الذي حدّده العميل على الخريطة عند إتمام الطلب. إن طلبتم منا «موقع العميل إلزامي» فلن يصلكم طلب بدونه؛ وإلا قد يكون null
وصف عنوان العميلrecipient.city, district, address, notenote: ملاحظة العميل للمندوب
مبلغ التحصيلcod_amount, currency0 = الطلب مدفوع، لا تحصّلوا شيئاً
أجرة التوصيلdelivery_fee, quote_id, distance_kmما دفعه العميل للتوصيل. مع السعر اللحظي: delivery_fee = price من عرضكم، و quote_id رقمه
المحتوياتitems[].name, sku, quantity

مناطق فلسطين في recipient.zone: wb الضفة الغربية، jer القدس، in48 الداخل (مناطق 48)، gaza قطاع غزة

5) طلب واحد

GET https://motajrh.com/api/carrier/v1/orders/1024      → { "order": { …, "history": [ { "status": "new", "at": "…", "by": "store" } ] } }

6) تحديث حالة الطلب

POST https://motajrh.com/api/carrier/v1/orders/1024/status
Content-Type: application/json

{ "status": "picked", "tracking_number": "SN-778812", "note": "" }
statusمعناهاما يحدث في المتجر
acceptedقبلتم الطلبيُسجَّل في سجل الطلب
pickedاستُلم الطرد من المتجريُسجَّل، ويظهر رقم التتبع للعميل
outمع المندوب للتسليميُسجَّل
deliveredسُلّم للعميليصير الطلب «تم التوصيل» ويُبلَّغ العميل
failedتعذّر التسليم (يمكن إعادة المحاولة)تنبيه للتاجر
returnedمرتجع للمتجر (نهائي)تنبيه للتاجر

الطلب المغلق (delivered / returned / cancelled) يعيد 409. الحالة غير المعروفة تعيد 422.

7) أسعاركم ومناطق تغطيتكم

أرسلوا أسعاركم فيراها كل تاجر عند إعداد شركتكم، ويعتمدها بضغطة. المنطقة التي لا ترسلونها تعني أنكم لا توصّلون إليها.

PUT https://motajrh.com/api/carrier/v1/rates
{ "country": "PS", "rates": [  { "zone": "wb", "price": 20, "days": "1-3" },  { "zone": "jer", "price": 30, "days": "1-3" }
] }

GET https://motajrh.com/api/carrier/v1/rates             → { "rates": { "PS": { … } }, "zones": { "PS": { … } } }

8) التحصيل عند الاستلام

ما حصّلتموه من العملاء ولم تحوّلوه للمتاجر بعد، ثم إبلاغنا بالتحويل. يصل التاجر تنبيه ويؤكد الاستلام من لوحته.

GET  https://motajrh.com/api/carrier/v1/settlements
     → { "pending": [ { "id": 1024, "order_number": "MA-10501", "store": "Magic Veil", "cod_amount": 122, "currency": "ILS" } ],
         "totals": { "ILS": 122 } }

POST https://motajrh.com/api/carrier/v1/settlements
     { "order_ids": [1024, 1031], "reference": "TRX-2026-0091" }   → { "settled": 2 }

للشركات التي تعمل بالخريطة: الموقع، السعر اللحظي، والطلبات المدفوعة

ثلاثة خيارات يفعّلها فريقنا لشركتكم عند الطلب، كلٌّ منها مستقل عن الآخر:

الخيارماذا يفعل
موقع العميل إلزاميالعميل الذي يختار شركتكم عند الدفع لا يكمل الطلب قبل تحديد موقعه على الخريطة (زر «موقعي الحالي» أو دبوس). فلا يصلكم طلب بلا recipient.lat و recipient.lng.
السعر اللحظينستدعي نقطة تسعير عندكم بعد أن يحدد العميل موقعه، ونعرض له السعر الذي تُرجعونه كما هو. يمكن أن يكون «إلزامياً» (لا سعر ثابت: إن لم تردّوا لا تُعرض شركتكم لهذا الطلب) أو «اختيارياً» (إن لم تردّوا يُعرض سعر التاجر الثابت).
الطلبات المدفوعة فقطلا تُعرض شركتكم مع «الدفع عند الاستلام»، ولا يُرسل لكم طلب قبل أن يُدفع. فيكون cod_amount صفراً في كل طلب يصلكم.

نقطة التسعير عندكم (أنتم تبنونها ونحن نستدعيها)

POST https://your-domain/…/shipping/quote
Authorization: Bearer <مفتاح تعطوننا إياه>
Content-Type: application/json

{ "store_id": 551,
  "pickup":  { "lat": 32.2211, "lng": 35.2544 },
  "dropoff": { "lat": 32.227, "lng": 35.242 } }

← 200 { "available": true, "quote_id": "q_8f2a1c", "price": 12, "currency": "ILS",
        "distance_km": 3.4, "eta_minutes": 45, "expires_at": "2026-10-08T18:30:00+03:00" }
← 200 { "available": false }        // خارج التغطية: لا تُعرض شركتكم لهذا الطلب
  • price بعملة المتجر (ILS في فلسطين)، ويُعرض للعميل كما هو. إن أرسلتم currency مختلفة نتجاهل الرد.
  • quote_id و distance_km و eta_minutes و expires_at اختيارية. إن أرسلتم quote_id حفظناه وأعدناه لكم في حقل quote_id من الطلب، و delivery_fee يساوي price.
  • نحتفظ بالعرض 10 دقائق على الأكثر، ولا نتجاوز expires_at ناقص دقيقتين؛ بعدها نطلب سعراً جديداً. فالطلب يُنشأ دائماً بسعر ما زال صالحاً عندكم.
  • ننتظر ردّكم 6 ثوانٍ. الرد غير 200، أو بلا حقل available، يُعدّ «لا ردّ».
  • لا تسعير بلا موقع المتجر: إن لم يحدد التاجر موقع فرعه على الخريطة لا نستدعيكم.

من يدفع أجرة التوصيل؟

طريقتان، نتفق معكم على إحداهما (وحقل account في كل طلب وكل طلب تسعير يقول أيهما):

accountالمعنى
platformحساب واحد للمنصة عندكم: تخصمون أجرة كل طلب من رصيد المنصة. نحن نأخذها من رصيد المتجر عندنا قبل إرسال الطلب، فلا يصلكم طلب لم تُغطَّ أجرته. إن أُلغي الطلب قبل الاستلام (order.cancelled) لا تُخصم الأجرة.
storeلكل متجر حسابه ورصيده عندكم يشحنه بنفسه. store.id هو ما تربطون به حساب المتجر، والتاجر يراه في لوحته ليعطيكم إياه. المنصة خارج المال.

9) الإشعار الفوري (Webhook) — اختياري

أعطوا الفريق رابطاً يبدأ بـ https://، فنرسل إليه POST عند كل طلب جديد وعند إلغاء التاجر طلباً:

X-Motajrh-Event: order.created            (or order.cancelled)
X-Motajrh-Delivery: 5521                  (unique per delivery: use it to ignore a repeat)
X-Motajrh-Signature: hex( HMAC-SHA256( raw body, your webhook secret ) )

{ "event": "order.created", "order": { … the same object as in the list … } }

تحققوا من التوقيع وردّوا بـ 200 خلال 8 ثوانٍ. إن لم يردّ خادمكم نعيد المحاولة بعد دقيقة، 5 دقائق، 30 دقيقة، ساعتين، 6 ساعات، ثم 12 ساعة. والطلب يبقى دائماً في GET /orders?status=new.

10) مثال سريع

curl -H "Authorization: Bearer YOUR_KEY" -H "Accept: application/json" \
     "https://motajrh.com/api/carrier/v1/orders?status=new"

curl -X POST -H "Authorization: Bearer YOUR_KEY" -H "Content-Type: application/json" \
     -d '{"status":"delivered"}' "https://motajrh.com/api/carrier/v1/orders/1024/status"

11) رموز الأخطاء

401 unauthorizedالمفتاح خاطئ أو موقوف
403 test_key_onlyالنقطة لمفتاح الاختبار فقط
404 not_foundالطلب ليس لشركتكم أو غير موجود
409 closedالطلب مغلق
422قيمة غير صحيحة (التفاصيل في errors أو message)
429تجاوزتم 240 طلباً في الدقيقة

شركة توصيل وتريد الانضمام؟

انضم كشريك

اربطوا شركة التوصيل مع متاجرة

عبّئوا بيانات الشركة ويتواصل معكم فريقنا ويرسل لكم مفتاح الاختبار.