تخط وانتقل إلى المحتوى الرئيسي

الشحن

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

بقلم: Support

تغطي هذه النقاط ما تحفظه لوحة التحكم في صفحات الشحن: سعر التوصيل للمنزل وللمكتب في كل ولاية، وقواعد الشحن المجاني، وشركات التوصيل المرتبطة بالمتجر. وتقدّم أيضاً قوائم الولايات والبلديات التي يحتاجها نموذج الطلب، والبلديات ومكاتب الاستلام التي تخدمها شركة توصيل المتجر.

الأسعار بالدينار الجزائري (DZD). يحسب POST /v1/orders سعر التوصيل من هذه الأسعار ويتجاهل أي تكلفة شحن تُرسل في الجسم، لذلك تقرأ واجهة المتجر الخاصة هذه الأسعار لتعرض تقديراً وتترك الطلب يحسب المبلغ. انظر الثيمات والواجهات المخصصة.

قبل أن تبدأ

  • يحتاج المفتاح صلاحيات الشحن. المفاتيح المُنشأة من لوحة التحكم (الإعدادات ← واجهة API، /dashboard/api) تملك الاثنتين. الصلاحيات تُجمَّد لحظة إنشاء المفتاح، فالمفتاح القديم الذي تنقصه يُرجع 403 forbidden: أنشئ مفتاحاً جديداً من لوحة التحكم.

  • المتجر الذي يبيع منتجات رقمية ليس له إعداد شحن: كل كتابة في هذه الصفحة تُرجع فيه 422 shipping_not_available.

  • كل كتابة تحتاج الترويسة Idempotency-Key. انظر Idempotency.

  • اختبار شركة توصيل وربطها يتصلان بخوادم الشركة أثناء النداء، ومزامنة الأسعار تتصل بها في الخلفية. هذه النداءات الثلاثة وPOST /v1/orders/{id}/send-to-delivery تتقاسم ميزانية خاصة بشركات التوصيل لكل متجر، فوق حدود المعدل.

  • يمكن التراجع عن كتابة الأسعار والإعدادات. أما ربط شركة توصيل وفصلها وتغيير الشركة الافتراضية فلا. قسم التراجع في آخر هذه الصفحة يشرح الطريقة.

  • قراءات الشحن لا تُخزَّن مؤقتاً على الحافة: نداء GET يُرسل مباشرة بعد كتابة يُرجع القيم الجديدة.

النطاق

الوصف

shipping:read

قراءة أسعار الشحن وإعداداته، وشركات التوصيل المرتبطة، وتغطية شركات التوصيل، وقوائم الولايات والبلديات.

shipping:write

تعديل أسعار الشحن وإعداداته، وربط شركات التوصيل واختبارها وفصلها ومزامنة أسعارها.

GET /v1/wilayas

الولايات التي يوصل إليها المتجر حسب نظام الولايات فيه: من 1 إلى 58 في النظام المتوافق مع شركات التوصيل، ومن 1 إلى 69 في نظام 69 ولاية. الأسماء بالعربية والفرنسية والإنجليزية. القائمة كلها تأتي في استجابة واحدة، دون ترقيم صفحات.

المصادقة: مفتاح منصة بصلاحية shipping:read.

الطلب

curl 'https://api.dzbuild.app/v1/wilayas' \
  -H "Authorization: Bearer $DZ_KEY"

الاستجابة 200

تظهر هنا ولايتان من 58 ولاية. الحقل mode_note جملة واحدة بالإنجليزية تشرح النظام.

{
  "data": {
    "wilaya_mode": "58",
    "mode_note": "Courier-compatible mode: wilayas 1-58 only.",
    "count": 58,
    "wilayas": [
      { "id": 1, "name_ar": "أدرار", "name_fr": "Adrar", "name_en": "Adrar" },
      { "id": 16, "name_ar": "الجزائر", "name_fr": "Alger", "name_en": "Algiers" }
    ]
  }
}

GET /v1/wilayas/{id}/communes

بلديات ولاية واحدة، مرتبة حسب الاسم الفرنسي. يُجاب عن أي ولاية من 1 إلى 69 مهما كان نظام الولايات في المتجر. القائمة كلها تأتي في استجابة واحدة.

المصادقة: مفتاح منصة بصلاحية shipping:read.

هذه قائمة البلديات الخاصة بالمنصة. لا تقول أي البلديات تخدمها شركة التوصيل: هذا دور GET /v1/shipping/coverage.

الطلب

curl 'https://api.dzbuild.app/v1/wilayas/16/communes' \
  -H "Authorization: Bearer $DZ_KEY"

الاستجابة 200

تظهر هنا بلديتان من 57 بلدية في الولاية 16.

{
  "data": {
    "wilaya_id": 16,
    "count": 57,
    "communes": [
      { "id": 564, "wilaya_id": 16, "name_ar": "عين بنيان", "name_fr": "Ain Benian" },
      { "id": 558, "wilaya_id": 16, "name_ar": "عين طاية", "name_fr": "Ain Taya" }
    ]
  }
}

المعرّف الذي ليس أرقاماً فقط يُرجع 400 bad_request. والولاية غير الموجودة تُرجع 404 not_found.

GET /v1/shipping/rates

سعر التوصيل لكل ولاية لها سعر في المتجر، مفهرساً برقم الولاية. الولاية التي ليس لها سعر لا تظهر في rates.

المصادقة: مفتاح منصة بصلاحية shipping:read.

الطلب

curl 'https://api.dzbuild.app/v1/shipping/rates' \
  -H "Authorization: Bearer $DZ_KEY"

الاستجابة 200

تظهر هنا ولاية واحدة.

{
  "data": {
    "wilaya_mode": "58",
    "currency": "DZD",
    "limits": {
      "max_price": 100000,
      "max_delivery_days": 60
    },
    "count": 58,
    "rates": {
      "16": {
        "home_price": 400,
        "home_enabled": true,
        "desk_price": 300,
        "desk_enabled": true,
        "days": 1,
        "is_active": true,
        "synced_provider": null,
        "synced_at": null
      }
    }
  }
}

الحقل

المعنى

wilaya_mode

58 أو 69، وهي القيمة نفسها التي في GET /v1/shipping/settings.

limits

أعلى سعر وأعلى قيمة days يقبلهما POST /v1/shipping/rates.

count

عدد الولايات في rates.

home_price، desk_price

سعر التوصيل للمنزل وسعر التوصيل للمكتب، بالدينار الجزائري.

home_enabled، desk_enabled

هل يقدّم المتجر نوع التوصيل هذا في هذه الولاية.

days

مدة التوصيل بالأيام.

synced_provider، synced_at

شركة التوصيل التي كتبت قائمة أسعارها هذا السعر آخر مرة، ومتى (YYYY-MM-DD HH:MM:SS). القيمة null إن لم تكتبه أي مزامنة.

POST /v1/shipping/rates

ينشئ أسعار الولايات التي ترسلها أو يعدّلها. الولايات الأخرى لا تُمَس.

المصادقة: مفتاح منصة بصلاحية shipping:write. يتطلب Idempotency-Key.

الجسم

rates كائن مفهرس برقم الولاية مكتوباً بأرقام فقط ("16" وليس "016")، ويضم من 1 إلى 69 ولاية. كل قيمة تحمل الحقول المراد ضبطها، وكل حقل اختياري.

الحقل

النوع

ملاحظات

home_price

number

بالدينار، يُقرَّب إلى رقمين بعد الفاصلة، من 0 إلى 100000. يُقبل النص الرقمي أيضاً.

home_enabled

bool

true أو false. وتُقبل أيضاً 0 و1 و"0" و"1".

desk_price

number

القواعد نفسها التي لـ home_price.

desk_enabled

bool

القواعد نفسها التي لـ home_enabled.

days

int

عدد صحيح من الأيام، من 0 إلى 60.

الحقل الذي تتركه أو ترسله null يحتفظ بقيمته المحفوظة. والولاية التي لم يكن لها سعر تبدأ بسعر 0 وبنوعَي التوصيل مفعّلين وبمدة 3 أيام.

الطلب

curl -X POST 'https://api.dzbuild.app/v1/shipping/rates' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: rates-2026-10-06-1" \
  -d '{"rates": {"16": {"home_price": 450, "desk_price": 350}, "31": {"desk_enabled": false}}}'

الاستجابة 200

الحقل rates يضم الولايات المكتوبة فقط، كما حُفظت بعد الكتابة.

{
  "data": {
    "updated": 2,
    "wilaya_ids": [16, 31],
    "rates": {
      "16": { "home_price": 450, "home_enabled": true, "desk_price": 350, "desk_enabled": true, "days": 1 },
      "31": { "home_price": 500, "home_enabled": true, "desk_price": 350, "desk_enabled": false, "days": 2 }
    }
  }
}

القيم السابقة تُحفظ، فيمكن التراجع عن الكتابة. الاستجابة لا تحمل change_id: انظر قسم التراجع.

GET /v1/shipping/settings

قواعد الشحن المجاني ونظام الولايات.

المصادقة: مفتاح منصة بصلاحية shipping:read.

الطلب

curl 'https://api.dzbuild.app/v1/shipping/settings' \
  -H "Authorization: Bearer $DZ_KEY"

الاستجابة 200

تحمل الاستجابة أيضاً كائن notes فيه جملتان بالإنجليزية تعيدان شرح قاعدة الحد الأدنى وقاعدة نظام الولايات. المثال لا يعرضه.

{
  "data": {
    "free_shipping": false,
    "free_shipping_threshold": 8000,
    "free_shipping_threshold_active": true,
    "wilaya_mode": "58"
  }
}

الحقل

المعنى

free_shipping

true عندما يكون التوصيل مجانياً لكل الطلبات.

free_shipping_threshold

المجموع الفرعي للطلب بالدينار الذي يصبح التوصيل مجانياً ابتداءً منه. القيمة 0 أو null تعني أنه لا يوجد حد.

free_shipping_threshold_active

true فقط عندما يكون الحد أكبر من 0.

wilaya_mode

"58": الولايات الـ 58 التي تعمل بها شركات التوصيل. "69": كل الولايات الـ 69، وهو نظام يُضبط من لوحة التحكم.

PATCH /v1/shipping/settings

يغيّر إعداداً أو أكثر من الإعدادات الثلاثة. أرسل واحداً على الأقل، والحقول الأخرى تُتجاهل.

المصادقة: مفتاح منصة بصلاحية shipping:write. يتطلب Idempotency-Key.

الجسم

الحقل

النوع

ملاحظات

free_shipping

bool

true أو false. وتُقبل أيضاً 0 و1 و"0" و"1".

free_shipping_threshold

number أو null

بالدينار، يُقرَّب إلى رقمين بعد الفاصلة، من 0 إلى 99999999.99. القيمة 0 أو null تُلغي الحد.

wilaya_mode

string

"58" فقط، وهي تُرجع متجراً في نظام 69 ولاية إلى 58 ولاية. التحويل إلى 69 ولاية يتم من صفحة أسعار الشحن في لوحة التحكم (/dashboard/shipping)، ويُرجع هنا 422 wilaya_mode_69_unsupported.

الطلب

curl -X PATCH 'https://api.dzbuild.app/v1/shipping/settings' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: settings-2026-10-06-1" \
  -d '{"free_shipping_threshold": 8000}'

الاستجابة 200

الإعدادات بعد الكتابة، دون notes. القيم السابقة تُحفظ، فيمكن التراجع عن التغيير.

GET /v1/shipping/providers

كل شركات التوصيل التي تدعمها المنصة، مرتبطة بالمتجر أو لا، مع ما تطلبه كل واحدة عند ربطها. قيم بيانات الدخول لا تُرجع أبداً: الحقلان has_id وhas_token يقولان فقط هل توجد قيمة محفوظة. القائمة كلها تأتي في استجابة واحدة.

المصادقة: مفتاح منصة بصلاحية shipping:read.

الطلب

curl 'https://api.dzbuild.app/v1/shipping/providers' \
  -H "Authorization: Bearer $DZ_KEY"

الاستجابة 200

تظهر هنا شركة واحدة. وتحمل الاستجابة أيضاً جملة note لا يعرضها المثال.

{
  "data": {
    "count": 103,
    "providers": [
      {
        "provider": "yalidine",
        "family": "yalidine",
        "credentials": {
          "api_id": { "label": "API ID", "required": true },
          "api_token": { "label": "API Token", "required": true },
          "_note": "Send an empty string to keep the currently stored value. Credentials are never returned by this API."
        },
        "extra_fields": {
          "delivery_tier": {
            "label": "Service tier",
            "required": false,
            "values": ["express"],
            "note": "Only \"express\" is valid here: this courier rejects the economic parameter outright and every order push would fail."
          }
        },
        "supports_rate_sync": true,
        "linked": true,
        "source": "store_delivery_providers",
        "is_enabled": true,
        "is_default": true,
        "is_send_default": true,
        "has_id": true,
        "has_token": true,
        "delivery_tier": "express",
        "economic_available": null,
        "credentials_failed_at": null,
        "synced_tier": "express",
        "stock_account": null,
        "auto_validate": null,
        "custom_name": null,
        "linked_at": "2026-09-14 10:12:00",
        "updated_at": "2026-09-14 10:12:00"
      }
    ]
  }
}

الحقل

المعنى

family

yalidine أو procolis أو ecotrack أو standalone.

credentials

ما يعنيه api_id وapi_token عند هذه الشركة، بتسمياتها هي. api_token غائب عند الشركة التي تأخذ قيمة واحدة.

extra_fields

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

supports_rate_sync

هل يعمل POST /v1/shipping/rates/sync مع هذه الشركة.

linked

هل هذه الشركة مربوطة بالمتجر.

source

store_delivery_providers لشركة رُبطت من قائمة شركات التوصيل (عبر هذه الواجهة أو لوحة التحكم)، وstore_row لشركة ضُبطت بالطريقة القديمة مباشرة في إعدادات المتجر، وnull إن لم تكن مربوطة.

is_enabled

هل الربط مفعّل.

is_default

هل هذه هي شركة التوصيل الافتراضية للمتجر.

is_send_default

الشركة التي يستعملها POST /v1/orders/{id}/send-to-delivery عندما لا يحدد النداء شركة.

delivery_tier، synced_tier، economic_available

مستوى الخدمة عند شركات عائلة Yalidine: المستوى المختار، والمستوى الذي استعملته آخر مزامنة للأسعار، وهل كان الحساب يقدّم المستوى الاقتصادي عند تلك المزامنة.

stock_account، auto_validate، custom_name

الحقول الإضافية المحفوظة لهذه الشركة، وnull إن لم تُضبط.

credentials_failed_at

وقت بصيغة ISO 8601، يُضبط عندما تظل الشركة ترفض بيانات الدخول المحفوظة. الإرسال لهذه الشركة يُرفض ما دام مضبوطاً. وربط الشركة من جديد يمحوه.

linked_at، updated_at

YYYY-MM-DD HH:MM:SS. القيمة null لشركة مضبوطة في إعدادات المتجر.

ما يحمله api_id وapi_token

provider

api_id

api_token

yalidine، yalitec، guepex، easyandspeed، economiqua، wecan

API ID

API Token

zrexpress، abexexpress، leopardexpress، colilog، flashdelivery

Token

Key

zrexpressnew

API Key (secret key)

Tenant ID

noest

API Token

User GUID

colivraison

Public Key

Bearer Token

ecomdelivery

API Key

API Token

neardelivery

ApiKey

ApiSecret

maystro

API Token

لا شيء

zimou

Bearer Token

لا شيء

elogistia

API Key

لا شيء

mdm

x-api-key

لا شيء

customecotrack وكل شركات عائلة ecotrack

Bearer Token

لا شيء

الحقول الإضافية، وكلها اختيارية ما لم يُذكر غير ذلك:

  • delivery_tier، عائلة Yalidine: القيمة express. وتقبل guepex أيضاً economic.

  • stock_account، عائلة ecotrack: تجهيز الطلبات من مخزون شركة التوصيل.

  • auto_validate، noest: اعتماد الطلبات تلقائياً لدى شركة التوصيل.

  • api_url وcustom_name، customecotrack، وكلاهما إلزامي للربط: عنوان Ecotrack الخاص بالشركة بصيغة https (نطاق ينتهي بـ .ecotrack.dz، أو platform.dhd-dz.com أو app.conexlog-dz.com)، والاسم الذي يظهر لها، حتى 100 حرف.

POST /v1/shipping/providers/test

يرسل بيانات الدخول إلى شركة التوصيل ويخبرك هل قبلتها. لا يُحفظ شيء. إذا كان api_id أو api_token فارغاً أو غائباً تُستعمل القيمة المحفوظة لهذه الشركة، فيمكنك إعادة اختبار شركة مربوطة دون أن تملك بيانات دخولها.

المصادقة: مفتاح منصة بصلاحية shipping:write. يتطلب Idempotency-Key. يُحسب من ميزانية شركات التوصيل.

الجسم

الحقل

النوع

إلزامي

ملاحظات

provider

string

نعم

معرّف من GET /v1/shipping/providers.

api_id

string

ما لم يكن محفوظاً

القيمة الأولى من بيانات الدخول.

api_token

string

ما لم يكن محفوظاً

القيمة الثانية، للشركات التي تأخذ قيمتين.

api_url

string

لـ customecotrack فقط

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

delivery_tier

string

لا

express أو economic. لا تُقبل economic إلا لـ guepex.

الطلب

curl -X POST 'https://api.dzbuild.app/v1/shipping/providers/test' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: test-yalidine-1" \
  -d '{"provider": "yalidine", "api_id": "YOUR_API_ID", "api_token": "YOUR_API_TOKEN"}'

الاستجابة 200

الشركة التي ترفض بيانات الدخول تُرجع أيضاً 200، مع ok: false وmessage نتيجة الفحص لدى الشركة. الحقل resolved_provider يُضبط لـ zrexpressnew فقط: منصة ZR Express التي قبلت الزوج.

{
  "data": {
    "provider": "yalidine",
    "ok": true,
    "message": "تم الاتصال بنجاح",
    "resolved_provider": null,
    "saved": false
  }
}

POST /v1/shipping/providers

يربط شركة توصيل، أو يعيد حفظ شركة مربوطة. تختبر المنصة بيانات الدخول مع الشركة أولاً، ولا تحفظ شيئاً إن رفضتها الشركة.

المصادقة: مفتاح منصة بصلاحية shipping:write. يتطلب Idempotency-Key. يُحسب من ميزانية شركات التوصيل.

الجسم

حقول نداء الاختبار، مع:

الحقل

النوع

الافتراضي

ملاحظات

enabled

bool

true

تفعيل الربط أو تعطيله.

set_default

bool

false

جعل هذه الشركة الشركةَ الافتراضية للمتجر.

custom_name

string

لا شيء

لـ customecotrack فقط، وهو إلزامي هناك. تُزال وسوم HTML ويُقص الاسم إلى 100 حرف.

stock_account

bool

القيمة المحفوظة

عائلة ecotrack.

auto_validate

bool

القيمة المحفوظة

noest.

  • الحقل api_id أو api_token الفارغ يحتفظ بالقيمة المحفوظة، فيمكن إعادة حفظ شركة مربوطة دون إرسال بيانات دخولها من جديد.

  • أول شركة يربطها المتجر تصبح شركته الافتراضية. في الاستجابة يكون is_default مساوياً لـ true فقط عندما يجعل هذا النداء الشركة افتراضية، فالشركة الافتراضية التي يُعاد حفظها دون set_default تبقى افتراضية بينما تقول الاستجابة false. ويُظهر GET /v1/shipping/providers الحالة الحقيقية.

  • zrexpress وzrexpressnew شركة واحدة: ربط إحداهما يحل محل الأخرى. والزوج zrexpressnew الذي تقبله منصة ZR Express القديمة يُحفظ باسم zrexpress، ويظهر ذلك في الحقل provider في الاستجابة.

الطلب

curl -X POST 'https://api.dzbuild.app/v1/shipping/providers' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: link-yalidine-1" \
  -d '{"provider": "yalidine", "api_id": "YOUR_API_ID", "api_token": "YOUR_API_TOKEN", "set_default": true}'

الاستجابة 200

{
  "data": {
    "provider": "yalidine",
    "is_enabled": true,
    "is_default": true,
    "has_id": true,
    "has_token": true,
    "undoable": false,
    "note": "Courier credentials are never recorded, so linking cannot be undone. To revert, link the previous courier again or unlink this one."
  }
}

بيانات الدخول المرفوضة تُرجع 422 credentials_rejected مع رسالة الشركة، ولا يُحفظ شيء.

POST /v1/shipping/providers/default

يجعل شركة مربوطة الشركةَ الافتراضية للمتجر. الإرسالات الجديدة إلى التوصيل تذهب إليها.

المصادقة: مفتاح منصة بصلاحية shipping:write. يتطلب Idempotency-Key.

الحقل provider في الجسم يسمّي الشركة. لا تصبح شركة افتراضية إلا إذا رُبطت من قائمة شركات التوصيل، والشركة المضبوطة في إعدادات المتجر تُرجع 404 provider_not_linked. وعندما تكون الشركة المختارة معطّلة، يقول warning إن الإرسال يبقى متوقفاً إلى أن تُفعَّل من جديد.

الطلب

curl -X POST 'https://api.dzbuild.app/v1/shipping/providers/default' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: default-noest-1" \
  -d '{"provider": "noest"}'

الاستجابة 200

{
  "data": {
    "provider": "noest",
    "is_default": true,
    "previous_default": "yalidine",
    "undoable": false,
    "warning": "New send-to-delivery pushes now go to \"noest\". "
  }
}

التأكيد قبل مزامنة الأسعار أو فصل شركة

مزامنة الأسعار تكتب فوق أسعار التاجر نفسه، وفصل الشركة يزيل بيانات دخول محفوظة، لذلك يطلب النداءان تأكيداً قبل التنفيذ.

  1. نادِ دون تأكيد. الرد يكون 422 confirmation_required، ويضيف الكائن error الحقول confirm_token (يُستعمل مرة واحدة) وconfirm_token_expires_in (600 ثانية) وaction وwill_change، وهو الملخص الذي تعرضه على التاجر.

  2. بعد موافقة التاجر، أعد النداء ومعه confirm_token في الجسم وبمفتاح Idempotency-Key جديد. المفتاح الأول مرتبط بالجسم الذي لا يحوي الرمز، فإعادة استعماله تُرجع 422 idempotency_key_reuse.

الرمز يعمل مرة واحدة، وللمفتاح الذي تلقّاه فقط، وما دام ما يصفه لم يتغير: جدول الأسعار في حالة المزامنة، وفي حالة الفصل عدد الشركات المربوطة وهل هذه الشركة هي الافتراضية. الرمز المستعمل أو المنتهي أو الذي لم يعد يطابق يُرجع 422 confirmation_stale مع رمز وملخص جديدين.

المفتاح الذي لا يستعمله المساعد المدمج في لوحة التحكم يمكنه إرسال "confirm": true بدل الرمز وتخطي الخطوة 1. أما المفاتيح التي يستعملها المساعد فيجب أن ترسل الرمز.

هكذا يبدو الرد الأول للمزامنة.

{
  "error": {
    "code": "confirmation_required",
    "message": "Syncing overwrites your own prices for every wilaya \"yalidine\" serves. Show the merchant the summary below; when they approve, re-send with the confirm_token.",
    "confirm_token": "cft_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "confirm_token_expires_in": 600,
    "action": "shipping.rates_sync:yalidine",
    "will_change": {
      "action": "Overwrite shipping rates from yalidine",
      "wilayas_at_risk": 58,
      "reversible": true,
      "note": "The prior prices are saved to the change log first, so this can be undone."
    }
  }
}

في حالة الفصل يضم will_change الحقول action وwas_store_default وremaining_providers وconsequence وreversible (false) وnote.

POST /v1/shipping/rates/sync

يستبدل أسعار المتجر بقائمة أسعار شركة التوصيل نفسها، لكل ولاية من 1 إلى 58 تسعّرها الشركة. تجري المزامنة في الخلفية. قبل وضع أي شيء في الطابور يُحفظ جدول الأسعار كله، وchange_id في الاستجابة يتراجع عن المزامنة.

المصادقة: مفتاح منصة بصلاحية shipping:write. يتطلب Idempotency-Key وتأكيداً. يُحسب من ميزانية شركات التوصيل.

الجسم

الحقل

النوع

إلزامي

ملاحظات

provider

string

نعم

شركة رُبطت من قائمة شركات التوصيل ومفعّلة. mdm وneardelivery ليس لهما قائمة أسعار.

confirm_token

string

انظر أعلاه

من الرد confirmation_required.

confirm

bool

انظر أعلاه

true، للمفاتيح التي لا يستعملها المساعد.

ما تغيّره المزامنة

  • تكتب home_price وdesk_price وتضبط synced_provider وsynced_at. مفاتيح التفعيل وdays في الولاية التي كان لها سعر تبقى كما هي. والولاية التي لم يكن لها سعر تأخذ 3 أيام.

  • شركات عائلة Yalidine تحتاج ولاية المتجر، وتُضبط بالحقل wilaya_id في PATCH /v1/store (انظر المتجر). دونها يُرجع النداء 422 store_wilaya_required.

  • تابع النتيجة بـ GET /v1/shipping/rates: الأسعار التي كتبتها المزامنة تحمل اسم الشركة في synced_provider وقيمة جديدة في synced_at. وإذا لم ترسل الشركة أي أسعار تبقى الأسعار كما كانت.

  • ما دامت مزامنة للشركة نفسها جارية، يُرجع النداء 202 مع status: already_running وsync_id تلك المزامنة وchange_id: null، دون طلب تأكيد.

  • بعد نجاح مزامنة، يمكن مزامنة الشركة نفسها من جديد بعد 5 دقائق. والنداء قبل ذلك يُرجع 429 sync_cooldown.

الطلب

curl -X POST 'https://api.dzbuild.app/v1/shipping/rates/sync' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: sync-yalidine-2" \
  -d '{"provider": "yalidine", "confirm_token": "cft_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}'

الاستجابة 202

{
  "data": {
    "status": "queued",
    "sync_id": "a1b2c3d4e5f6a7b8c9d0e1f2",
    "change_id": 500,
    "note": "The sync runs in the background and overwrites your prices for every wilaya this courier serves. Poll GET /v1/shipping/rates for the result; undo change_id to restore the prior prices."
  }
}

DELETE /v1/shipping/providers/{provider}

يفصل شركة توصيل ويزيل بيانات دخولها من المتجر. لا يمكن التراجع عن ذلك: لتُرسل مع هذه الشركة من جديد، اربطها من جديد. والطرود الموجودة أصلاً عند الشركة يبقى تتبعها مستمراً.

المصادقة: مفتاح منصة بصلاحية shipping:write. يتطلب Idempotency-Key وتأكيداً.

  • provider في المسار هو معرّف الشركة. لا يمكن فصل شركة هنا إلا إذا رُبطت من قائمة شركات التوصيل، وأي شركة أخرى تُرجع 404 provider_not_linked.

  • الجسم يحمل التأكيد فقط: confirm_token، أو confirm: true للمفاتيح التي لا يستعملها المساعد.

  • عندما تكون الشركة المفصولة هي الافتراضية، تصبح الشركة الافتراضية هي الشركة المفعّلة الأخرى التي رُبطت قبل غيرها.

  • وإن لم توجد، لا تبقى شركة افتراضية ويتوقف الإرسال إلى التوصيل في المتجر كله. وتحمل الاستجابة حينها new_default: null وsend_to_delivery_active: false.

الطلب

curl -X DELETE 'https://api.dzbuild.app/v1/shipping/providers/yalidine' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: unlink-yalidine-2" \
  -d '{"confirm_token": "cft_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}'

الاستجابة 200

{
  "data": {
    "provider": "yalidine",
    "unlinked": true,
    "undoable": false,
    "remaining_providers": 1,
    "new_default": "noest",
    "send_to_delivery_active": true,
    "warning": "The store default is now \"noest\"; new send-to-delivery pushes go there."
  }
}

GET /v1/shipping/coverage

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

المصادقة: مفتاح منصة بصلاحية shipping:read.

معاملات الاستعلام

المعامل

النوع

الافتراضي

ملاحظات

provider

string

لا شيء

معرّف شركة مربوطة. دونه تُستعمل الشركة المعلَّمة بـ is_send_default، وإلا فأول شركة مربوطة.

wilaya_id

int

0

القيمة 0 تعطي عدداً لكل ولاية. من 1 إلى 69 تضيف بلديات تلك الولاية ومكاتب الاستلام فيها وdesk_send_allowed. القيمة خارج المجال من 0 إلى 69 تُرجع 400 bad_request.

الطلب

curl 'https://api.dzbuild.app/v1/shipping/coverage?wilaya_id=16' \
  -H "Authorization: Bearer $DZ_KEY"

الاستجابة 200

تظهر هنا بلدية واحدة ومكتب واحد.

{
  "data": {
    "provider": "yalidine",
    "is_send_default": true,
    "knowledge_synced_at": "2026-10-05 03:12:44",
    "wilayas": [
      { "wilaya_id": 16, "name": "Alger", "communes": 57, "communes_home": 57, "communes_desk": 12, "desks": 9 }
    ],
    "wilaya_id": 16,
    "desk_send_allowed": true,
    "communes": [
      { "commune_id": 521, "name": "Alger Centre", "name_ar": "الجزائر الوسطى", "home": true, "desk": true }
    ],
    "desks": [
      { "desk_id": "160101", "name": "Agence Alger Centre", "address": "Alger Centre", "phone": null, "commune_id": 521 }
    ]
  }
}

الحقل

المعنى

knowledge_synced_at

آخر مرة حدّثت فيها المنصة بلديات هذه الشركة ومكاتبها. القيمة null إن لم تحدّثها أبداً.

wilayas

لكل ولاية: عدد البلديات communes، وكم منها فيه توصيل للمنزل (communes_home) وتوصيل للمكتب (communes_desk)، وعدد المكاتب desks. ومع wilaya_id تظهر تلك الولاية وحدها.

desk_send_allowed

هل يقبل POST /v1/orders/{id}/send-to-delivery طلب توصيل للمكتب إلى هذه الولاية مع هذه الشركة. إنه الفحص نفسه.

communes

commune_id هو المعرّف الذي في GET /v1/wilayas/{id}/communes، أو null عندما لا تطابق بلديةُ الشركة أي بلدية في تلك القائمة، ويكون name حينها الاسم الذي تعطيه الشركة للبلدية. home وdesk يقولان أي نوعَي التوصيل تقدّمه الشركة هناك.

desks

مكاتب الاستلام لدى الشركة في الولاية. يشرح دليل الثيمات والواجهات المخصصة كيف تعرضها عند إتمام الطلب.

المتجر الذي ليس له شركة توصيل يُرجع 422 no_courier_linked. والقيمة provider لشركة لم يربطها المتجر تُرجع 404 provider_not_linked.

التراجع عن تغييرات الأسعار والإعدادات

POST /v1/shipping/rates وPATCH /v1/shipping/settings ومزامنة الأسعار تحفظ القيم التي تستبدلها، فيمكن التراجع عن كل منها بـ POST /v1/changes/{id}/undo.

  • مزامنة الأسعار تُرجع change_id الخاص بها. أما الكتابتان الأخريان فلا: ابحث عن التغيير بـ GET /v1/changes?entity=shipping.rates أو GET /v1/changes?entity=shipping.settings، الأحدث أولاً. عرض التغييرات يحتاج store:read.

  • التراجع يحتاج shipping:write وIdempotency-Key. والتراجع نفسه تغيير مستقل، undo_change_id، يمكنك التراجع عنه بدوره، إلا التراجع عن مزامنة فإنه يُرجع 422 nothing_to_restore. انظر التغييرات والتراجع عنها.

  • التراجع عن كتابة أسعار يحذف أسعار الولايات التي أنشأتها تلك الكتابة. والتراجع عن مزامنة يُرجع الولايات التي كان لها سعر قبلها، أما الولاية التي أضافتها المزامنة فتحتفظ بسعرها الجديد.

  • التراجع يعيد كتابة القيم المحفوظة حتى لو تغيّرت الأسعار أو الإعدادات بعد ذلك، من لوحة التحكم أو عبر الواجهة البرمجية.

  • التغيير الذي يُتراجع عنه مرة ثانية يُرجع 409 already_undone.

  • رمز التطبيق المثبّت لا يستطيع عرض التغييرات ولا التراجع عنها: كلاهما يُرجع 403 forbidden.

curl -X POST 'https://api.dzbuild.app/v1/changes/500/undo' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Idempotency-Key: undo-500"

{
  "data": {
    "undone": true,
    "change_id": 500,
    "entity": "shipping.rates",
    "undo_change_id": 510
  }
}

الأخطاء

HTTP

الرمز

السبب

400

bad_request

الجسم ليس كائن JSON، أو rates غائب أو ليس كائناً، أو معرّف في المسار غير صالح، أو wilaya_id خارج المجال من 0 إلى 69، أو Idempotency-Key غائب أو غير صالح.

400

invalid_rates

rates فارغ أو فيه أكثر من 69 ولاية، أو سعر ليس كائناً، أو مفتاح تفعيل ليس قيمة منطقية.

400، 422

invalid_wilaya

400: مفتاح في rates ليس أرقاماً فقط. 422: لا توجد ولاية بهذا الرقم.

400، 422

invalid_price

400: ليس رقماً. 422: سالب أو أكبر من 100000.

400، 422

invalid_days

400: ليس عدداً صحيحاً. 422: خارج المجال من 0 إلى 60.

400

nothing_to_update

PATCH /v1/shipping/settings دون أي حقل من حقوله الثلاثة.

400

invalid_free_shipping

free_shipping ليس قيمة منطقية.

400، 422

invalid_threshold

400: ليس رقماً ولا null. 422: سالب أو أكبر من 99999999.99.

400

invalid_wilaya_mode

wilaya_mode ليس "58" ولا "69".

422

wilaya_mode_69_unsupported

wilaya_mode هو "69"، وهذا يُضبط من لوحة التحكم.

400

provider_required

provider غائب.

400

credentials_required

لم يُرسل api_id ولم يُحفظ، أو لا يوجد api_token لشركة تأخذ قيمتين.

400

invalid_credentials_format

قيم zrexpressnew تحوي أقواس JSON أو مسافات أو أسطراً جديدة، أو تبدأ بـ http، أو تتجاوز 128 حرفاً.

400

api_url_required، custom_name_required

customecotrack دون عنوانها، أو ربط دون اسمها.

400، 422

invalid_delivery_tier

400: ليس express ولا economic. 422: economic لشركة غير guepex.

422

unsupported_provider

المعرّف ليس في GET /v1/shipping/providers.

422

invalid_api_url، api_url_mismatch

عنوان customecotrack ليس عنوان Ecotrack بصيغة https، أو يختلف عن العنوان المحفوظ مع إعادة استعمال بيانات الدخول المحفوظة.

422

credentials_rejected

رفضت الشركة بيانات الدخول. لم يُحفظ شيء.

422

rate_sync_unsupported

mdm وneardelivery ليس لهما قائمة أسعار.

422

provider_not_linked

مزامنة الأسعار: الشركة لم تُربط من قائمة شركات التوصيل، أو معطّلة.

404

provider_not_linked

الشركة الافتراضية أو الفصل أو التغطية: المتجر لم يربط هذه الشركة.

422

store_wilaya_required

مزامنة أسعار شركة من عائلة Yalidine قبل ضبط ولاية المتجر.

422

confirmation_required، confirmation_stale

انظر قسم التأكيد أعلاه.

422

snapshot_too_large، snapshot_failed

تعذّر حفظ الأسعار السابقة، فرُفضت الكتابة بدل أن تصبح غير قابلة للتراجع.

422

no_courier_linked

التغطية لمتجر ليس له شركة توصيل.

422

shipping_not_available

كتابة على متجر يبيع منتجات رقمية.

422

idempotency_key_reuse

المفتاح Idempotency-Key نفسه مع جسم مختلف.

403

forbidden

المفتاح لا يملك الصلاحية، مثلاً Missing scope: shipping:write، أو مفتاح تاجر متجره ليس على خطة Enterprise سارية.

404

not_found

بلديات ولاية غير موجودة.

404

store_not_found

متجر المفتاح لم يعد موجوداً.

429

sync_cooldown

جرت مزامنة الشركة نفسها قبل أقل من 5 دقائق. الرسالة تقول كم دقيقة بقيت.

429

rate_limited، too_many_concurrent

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

503

sync_queue_failed

تعذّر بدء المزامنة ولم تتغير الأسعار. أعد المحاولة لاحقاً.

500

server_error

أعد المحاولة بالمفتاح Idempotency-Key نفسه.

هل أجاب هذا عن سؤالك؟