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

أقسام الصفحة الرئيسية

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

بقلم: Support

تخطيط الصفحة الرئيسية هو القائمة المرتّبة للأقسام التي يعرضها المتجر في صفحته الرئيسية. لكل قسم نوع وإعدادات. يمكن إضافة عشرة أنواع في كل قالب: category-products وfeatured وcategories وbanner وimage-with-text وrich-text وtrust-badges وtestimonials وfaq وvideo. ويقدّم قالب مبني على الأقسام مثل atlas أيضاً hero وproduct-grid. يعطي types في استجابة GET إعدادات كل نوع. كل كتابة في هذه الصفحة تظهر في المتجر بمجرد أن تُرجع استجابتها.

هذه النقاط ليست GET /v1/store/home-sections التي تقرأ مفاتيح الصفحة الرئيسية في قوالب Digital وAriana وPrestige. وهذه المفاتيح مشروحة في آخر هذه الصفحة.

قبل أن تبدأ

  • تحتاج GET إلى store:read، وتحتاج الكتابات إلى store:write. مفاتيح التاجر تحمل الاثنتين.

  • تحتاج POST وPATCH وDELETE إلى Idempotency-Key. وهو اختياري مع PUT. انظر Idempotency.

  • رقم الفئة يأتي من GET /v1/categories التي تحتاج إلى products:read.

كائن القسم

الحقل

النوع

ملاحظات

id

int

ثابت ما دام القسم موجوداً. القسم الذي يعود بالتراجع يأخذ رقماً جديداً.

type

string

إحدى قيم type المذكورة في types ضمن GET /v1/store/home-layout.

settings

object

كل إعدادات النوع، والقيم الافتراضية مملوءة.

is_active

bool

false تُخفي القسم عن الزبائن وتُبقيه في القائمة.

available

bool

false عندما لا يعود قالب المتجر يملك هذا النوع. يبقى القسم كما خُزّن، ويمكن لأي كتابة أن تُبقيه.

إعدادات category-products

الإعداد

النوع

الافتراضي

القواعد

category

رقم فئة

0

فئة من هذا المتجر. 0 تعني بلا فئة، وعندها لا يعرض القسم شيئاً للزبائن. رقم فئة من متجر آخر يُرجع 422 invalid_settings.

title

text

""

حتى 80 حرفاً، ويُزال منه HTML. الفارغ يُظهر اسم الفئة.

count

range

8

من 4 إلى 12. الرقم خارج هذا المجال يُنقل إلى أقرب حدّ.

layout

select

grid

grid أو slider.

show_view_all

checkbox

true

رابط إلى صفحة الفئة.

الفئة التي لا منتجات فيها لا تعرض شيئاً للزبائن كذلك. اقرأ قواعد أي نوع من settings_schema الخاص به بدل كتابتها في برنامجك: قائمة الأنواع تتبع قالب المتجر.

صيغ الإعدادات

نوع الإعداد

القيمة المقبولة

category

رقم من GET /v1/categories، أو 0 لعدم الاختيار.

link

#anchor، أو مسار /path داخل المتجر، أو عنوان http:// أو https://، أو رابط tel: أو mailto:، حتى 500 حرف، أو "". العنوان المرسل بلا بادئته، مثل wa.me/213...، يُحفظ مع https:// في أوله.

youtube

رابط فيديو YouTube أو معرّفه ذو 11 حرفاً. يُحفظ المعرّف.

image

مسار صورة رُفعت من لوحة التحكم لهذا المتجر، /uploads/banners/{store_id}/...، أو "". لا يمكن رفع الصور عبر الواجهة البرمجية حالياً: يرفع التاجر الصورة أولاً من إعدادات القسم في لوحة التحكم، ثم تُرجع GET مسارها.

متى يرى الزبائن القسم

القسم الذي لم يُملأ محتواه بعد يُخزَّن وتُرجع الكتابة 2xx، لكن الزبائن لا يرونه حتى يُملأ:

النوع

يراه الزبائن عندما

category-products

تكون category فئة من المتجر فيها منتجات.

featured

تكون في source المختار منتجات.

categories

تكون في المتجر فئة فيها منتجات، أو أي فئة عندما تكون show_empty بقيمة true.

banner

تُملأ image.

image-with-text

تُملأ image مع title أو text.

rich-text

يُملأ title أو text.

trust-badges

دائماً. الشارتان 1 و2 الفارغتان تُظهران سطري التوصيل والدفع عند الاستلام الافتراضيين.

testimonials

يُملأ tN_text واحد على الأقل.

faq

يُملأ qN واحد على الأقل مع aN الخاص به.

video

تحمل video معرّف فيديو YouTube.

لا تتغيّر rendered لهذا السبب: فهي تقول إن كان القالب يعرض الأقسام المخزّنة، لا إن كان قسم بعينه ظاهراً. في قالب مبني على الأقسام (atlas) لا تحلّ الأقسام المحفوظة محل الصفحة الرئيسية للقالب إلا ما دامت تتضمن قسم product-grid ظاهراً، وتبقى rendered بقيمة false حتى ذلك الحين؛ وقبل ذلك يرى الزبائن الصفحة الأصلية للقالب، ولا تعرض GET إلا الأقسام المحفوظة، لا أقسام القالب نفسه.

GET /v1/store/home-layout

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

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

الطلب

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

الاستجابة 200

{
  "data": {
    "theme": "starter",
    "rendered": true,
    "max_sections": 25,
    "cap": 25,
    "version": "9c1e04b7a2d35f68",
    "sections": [
      {
        "id": 412,
        "type": "category-products",
        "settings": {
          "category": 57,
          "title": "",
          "count": 8,
          "layout": "grid",
          "show_view_all": true
        },
        "is_active": true,
        "available": true
      },
      {
        "id": 415,
        "type": "category-products",
        "settings": {
          "category": 61,
          "title": "Nos parfums",
          "count": 10,
          "layout": "slider",
          "show_view_all": false
        },
        "is_active": false,
        "available": true
      }
    ],
    "types": [
      {
        "type": "category-products",
        "name": {"ar": "منتجات فئة", "fr": "Produits d'une catégorie"},
        "description": {"ar": "اعرض منتجات فئة واحدة في شبكة أو شريط تمرير.", "fr": "Affichez les produits d'une catégorie en grille ou en carrousel."},
        "icon": "bi-grid-3x3-gap",
        "limit": 12,
        "settings_schema": [
          {"id": "category", "type": "category", "default": 0, "label": {"ar": "الفئة", "fr": "Catégorie"}},
          {"id": "title", "type": "text", "max": 80, "default": "", "label": {"ar": "العنوان (إذا تركته فارغاً يظهر اسم الفئة)", "fr": "Titre (si vide, le nom de la catégorie s'affiche)"}},
          {"id": "count", "type": "range", "min": 4, "max": 12, "default": 8, "label": {"ar": "عدد المنتجات", "fr": "Nombre de produits"}},
          {"id": "layout", "type": "select", "options": ["grid", "slider"], "default": "grid", "label": {"ar": "طريقة العرض", "fr": "Affichage"}, "option_labels": {"ar": ["شبكة", "شريط تمرير"], "fr": ["Grille", "Carrousel"]}},
          {"id": "show_view_all", "type": "checkbox", "default": true, "label": {"ar": "زر عرض الكل", "fr": "Lien « Voir tout »"}}
        ]
      }
    ]
  },
  "meta": {"request_id": "8f2c1a9d4b7e6035", "api_version": "v1"}
}

الحقل

المعنى

theme

مفتاح قالب المتجر.

rendered

false عندما لا يعرض قالب المتجر الحالي أقسام الصفحة الرئيسية. تبقى الأقسام محفوظة وتظهر من جديد مع قالب يعرضها. وفي قالب مبني على الأقسام لا تكون true إلا ما دام قسم product-grid ظاهر محفوظاً.

max_sections

25، أقصى عدد من الأقسام تحمله صفحة رئيسية واحدة.

cap

عدد الأقسام الذي تسمح به خطة المتجر: 3 في الخطة المجانية أو خطة منتهية، و25 ابتداءً من Pro.

version

بصمة التخطيط المخزَّن. أرسلها في version مع PUT لرفض تخطيط تغيّر منذ هذه القراءة.

sections

الأقسام بترتيب عرضها، ومعها الأقسام المخفية.

types

الأنواع التي يمكن إضافتها في هذا القالب، مع name وdescription وicon وlimit (أقصى عدد من أقسام هذا النوع في الصفحة) وsettings_schema. يعرض المثال أعلاه نوعاً واحداً منها.

القراءة بعد الكتابة

عبر api.dzbuild.app يُخدَم كل طلب GET حديثًا: طلب GET المُرسَل مباشرة بعد الكتابة يُرجع التخطيط الجديد. ونادرًا ما تحتاج إليه، لأن كل كتابة تُرجع القائمة كاملة بترتيب العرض مع version الجديدة.

POST /v1/store/home-layout/sections

يضيف قسماً واحداً.

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

الجسم

الحقل

النوع

إلزامي

ملاحظات

type

string

نعم

قيمة type من types.

settings

object

لا

الإعدادات التي لا ترسلها تأخذ القيم الافتراضية للنوع.

position

int

لا

0 يضع القسم في الأعلى، و24 آخر مكان. بدونه يُضاف القسم في النهاية.

الطلب

curl -X POST 'https://api.dzbuild.app/v1/store/home-layout/sections' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: hs-add-sacs-1" \
  -d '{"type": "category-products", "settings": {"category": 64, "layout": "slider"}, "position": 0}'

الاستجابة 201

{
  "data": {
    "section": {
      "id": 418,
      "type": "category-products",
      "settings": {"category": 64, "title": "", "count": 8, "layout": "slider", "show_view_all": true},
      "is_active": true,
      "available": true
    },
    "sections": [
      {"id": 418, "type": "category-products", "settings": {"category": 64, "title": "", "count": 8, "layout": "slider", "show_view_all": true}, "is_active": true, "available": true},
      {"id": 412, "type": "category-products", "settings": {"category": 57, "title": "", "count": 8, "layout": "grid", "show_view_all": true}, "is_active": true, "available": true},
      {"id": 415, "type": "category-products", "settings": {"category": 61, "title": "Nos parfums", "count": 10, "layout": "slider", "show_view_all": false}, "is_active": false, "available": true}
    ],
    "version": "e27a90c4b1f36d05",
    "change_id": 90231,
    "rendered": true
  },
  "meta": {"request_id": "3b7d0e5a9c14f862", "api_version": "v1"}
}

PATCH /v1/store/home-layout/sections/{id}

يغيّر قسماً واحداً. الإعدادات التي ترسلها تُدمج فوق الإعدادات المخزّنة. أرسل settings أو is_active أو كليهما.

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

الجسم

الحقل

النوع

إلزامي

ملاحظات

settings

object

لا

تُدمج فوق الإعدادات المخزّنة.

is_active

bool

لا

false تُخفي القسم، وtrue تُظهره.

replace

bool

لا

مع settings، القيمة true تُرجع كل إعداد لا ترسله إلى قيمته الافتراضية.

الطلب

curl -X PATCH 'https://api.dzbuild.app/v1/store/home-layout/sections/415' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: hs-415-show-1" \
  -d '{"settings": {"count": 6}, "is_active": true}'

الاستجابة 200

للاستجابة الحقول نفسها التي لاستجابة POST: section (القسم بعد التغيير)، وsections، وversion، وchange_id، وrendered.

{
  "data": {
    "section": {
      "id": 415,
      "type": "category-products",
      "settings": {"category": 61, "title": "Nos parfums", "count": 6, "layout": "slider", "show_view_all": false},
      "is_active": true,
      "available": true
    },
    "sections": [
      {"id": 418, "type": "category-products", "settings": {"category": 64, "title": "", "count": 8, "layout": "slider", "show_view_all": true}, "is_active": true, "available": true},
      {"id": 412, "type": "category-products", "settings": {"category": 57, "title": "", "count": 8, "layout": "grid", "show_view_all": true}, "is_active": true, "available": true},
      {"id": 415, "type": "category-products", "settings": {"category": 61, "title": "Nos parfums", "count": 6, "layout": "slider", "show_view_all": false}, "is_active": true, "available": true}
    ],
    "version": "51d8c3e06fa2b974",
    "change_id": 90232,
    "rendered": true
  },
  "meta": {"request_id": "c90a6e1f2d7b4538", "api_version": "v1"}
}

DELETE /v1/store/home-layout/sections/{id}

يحذف قسماً واحداً.

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

الطلب

curl -X DELETE 'https://api.dzbuild.app/v1/store/home-layout/sections/412' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Idempotency-Key: hs-del-412-1"

الاستجابة 200

{
  "data": {
    "deleted": true,
    "id": 412,
    "sections": [
      {"id": 418, "type": "category-products", "settings": {"category": 64, "title": "", "count": 8, "layout": "slider", "show_view_all": true}, "is_active": true, "available": true},
      {"id": 415, "type": "category-products", "settings": {"category": 61, "title": "Nos parfums", "count": 6, "layout": "slider", "show_view_all": false}, "is_active": true, "available": true}
    ],
    "version": "0f6b2d9e84a1c357",
    "change_id": 90233,
    "rendered": true
  },
  "meta": {"request_id": "71e4b08c3a5d9f26", "api_version": "v1"}
}

POST /v1/store/home-layout/reorder

يحدّد ترتيب العرض. تذكر ids كل أقسام الصفحة مرة واحدة بالضبط، ومعها الأقسام المخفية.

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

الطلب

curl -X POST 'https://api.dzbuild.app/v1/store/home-layout/reorder' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: hs-order-2" \
  -d '{"ids": [415, 418]}'

الاستجابة 200

تحمل الاستجابة sections بالترتيب الجديد، وversion، وchange_id، وrendered. الرقم الذي ليس في الصفحة يُرجع 404 section_not_found. والرقم الناقص أو المكرر يُرجع 422 invalid_order.

PUT /v1/store/home-layout

يستبدل التخطيط كله بالقائمة التي ترسلها، بترتيبها.

المصادقة: مفتاح منصة بصلاحية store:write. Idempotency-Key اختياري.

الجسم

الحقل

النوع

إلزامي

ملاحظات

sections

array

نعم

25 عنصراً على الأكثر، كل عنصر {id?, type, settings?, is_active?}. القائمة الفارغة تحذف كل الأقسام.

version

string

لا

قيمة version من آخر قراءة لك. إذا تغيّر التخطيط منذها، يُرجع النداء 409 write_conflict مع sections وversion الحاليتين ولا يكتب شيئاً.

كيف يُقرأ كل عنصر:

  • العنصر الذي يحمل id يُبقي ذلك القسم. ويجب أن يكون type هو النوع الحالي للقسم.

  • العنصر الذي بلا id ينشئ قسماً.

  • كل قسم في الصفحة غير موجود في القائمة يُحذف.

  • settings هو الكائن كاملاً: الإعداد الذي تتركه يعود إلى قيمته الافتراضية. أرسل الإعدادات كاملة لكل قسم تُبقيه.

  • قيمة is_active الافتراضية true.

الطلب

curl -X PUT 'https://api.dzbuild.app/v1/store/home-layout' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: hs-replace-7" \
  -d '{
    "version": "0f6b2d9e84a1c357",
    "sections": [
      {"id": 415, "type": "category-products", "settings": {"category": 61, "title": "Nos parfums", "count": 6, "layout": "slider", "show_view_all": false}},
      {"type": "category-products", "settings": {"category": 57}}
    ]
  }'

الاستجابة 200

تحمل الاستجابة sections وversion وchange_id وrendered. القسم 418 لم يُرسل، لذلك يُحذف. وإعادة إرسال التخطيط الذي قرأته كما هو تُرجع change_id: null.

مع Idempotency-Key، إعادة المحاولة بالمفتاح نفسه والجسم نفسه تُرجع الاستجابة المخزّنة لمدة 24 ساعة مع Idempotency-Replay: 1، والمفتاح نفسه مع جسم آخر يُرجع 422 idempotency_key_reuse. وبدون مفتاح يُنفَّذ النداء في كل مرة، وهذا آمن: إرسال القائمة نفسها مرتين يترك التخطيط نفسه.

التراجع

كل كتابة تُرجع change_id، أو null عندما لا تغيّر شيئاً. يُرجع POST /v1/changes/{change_id}/undo الصفحة الرئيسية كلها كما كانت قبل ذلك التغيير.

  • يمكن التراجع عن إضافة قسم أيضاً: التراجع يزيله. في الموارد الأخرى يرفض التراجع أي تغيير أنشأ شيئاً.

  • إذا تغيّرت الصفحة الرئيسية بعد ذلك التغيير، عبر الواجهة البرمجية أو من لوحة التحكم، يُرجع التراجع 409 layout_changed ولا يكتب شيئاً. اقرأ التخطيط واكتب ما تريده مباشرة.

  • القسم الذي يعود بعد حذفه يأخذ رقماً جديداً.

  • التراجع نفسه يُسجَّل تغييراً مستقلاً، undo_change_id، ويمكنك التراجع عنه بدوره. التراجع عن تراجعٍ عن حذف يُرجع 409 layout_changed، لأن القسم عاد برقم جديد.

  • التغييرات التي يحفظها التاجر من لوحة التحكم لا تُسجَّل، فلا يمكن التراجع عنها عبر الواجهة البرمجية.

  • يعرض GET /v1/changes?entity=store.home_layout تغييرات تخطيط الصفحة الرئيسية، الأحدث أولاً، بصلاحية store:read.

  • لا يستطيع رمز التطبيق المثبّت قراءة التغييرات ولا التراجع عنها: يُرجع GET /v1/changes والتراجع 403 forbidden (Apps cannot use this endpoint). وتبقى استجابات الكتابة تحمل change_id.

  • لا تحمل استجابة التراجع التخطيط. اقرأه من جديد عبر GET /v1/store/home-layout؛ القراءة تُخدَم حديثًا.

يحتاج التراجع إلى store:write وإلى Idempotency-Key.

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

{
  "data": {
    "undone": true,
    "change_id": 90231,
    "entity": "store.home_layout",
    "undo_change_id": 90240
  },
  "meta": {"request_id": "5ad2f7c01e9b8634", "api_version": "v1"}
}

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

الأخطاء

HTTP

الرمز

السبب

400

bad_request

الجسم ليس كائن JSON، أو حقل من نوع خاطئ (type غائب، أو settings ليس كائناً، أو is_active أو replace ليس قيمة منطقية، أو position خارج 0 إلى 24، أو ids ليس مصفوفة من أرقام الأقسام، أو version ليس نصاً)، أو رقم القسم في المسار ليس رقماً موجباً، أو Idempotency-Key غائب أو غير صالح مع POST أو PATCH أو DELETE.

401

unauthorized

مفتاح خاطئ أو غائب.

402

quota_exceeded

انتهت حصة الطلبات الشهرية للمتجر. انظر حدود المعدل.

403

forbidden

Missing scope: store:read أو Missing scope: store:write، أو API access requires an active Enterprise plan لمفتاح تاجر متجره ليس على خطة Enterprise سارية.

403

plan_required

الكتابة تترك أقساماً أكثر مما تسمح به الخطة. يحمل الخطأ plan وcap.

404

section_not_found

لا يوجد قسم بهذا الرقم في الصفحة.

409

write_conflict

وصلت كتابة أخرى قبلك، أو version المرسلة مع PUT ليست الحالية. عندما يحمل الخطأ sections وversion فهما التخطيط الحالي: أعد المحاولة انطلاقاً منهما. وإلا فاقرأ التخطيط وأعد المحاولة.

409

layout_changed

للتراجع فقط: تغيّرت الصفحة الرئيسية بعد هذا التغيير.

409

already_undone

للتراجع فقط: سبق التراجع عن هذا التغيير.

413

payload_too_large

الجسم أكبر من 1 ميغابايت.

422

invalid_settings

رُفضت قيمة. تذكر fields كل إعداد مرفوض في القسم، مثل settings.category. ومع PUT تذكر إعدادات أول قسم مرفوض فقط، مثل sections.2.settings.layout، وتشمل أيضاً id ليس في الصفحة (sections.N.id) وقسماً مُبقى أُرسل بنوع آخر (sections.N.type). وتذكر message المسارات أيضاً.

422

invalid_section_type

النوع غير موجود أو لا يمكن إضافته في هذا القالب. تعطي fields المسار.

422

limit_reached

أكثر من 25 قسماً، أو أكثر من limit لنوع واحد. يحمل الخطأ limit، إلا عندما ترسل PUT أكثر من 25 عنصراً.

422

invalid_order

ids في إعادة الترتيب ينقصها قسم أو تكرر قسماً.

422

no_changes

PATCH بلا settings ولا is_active.

422

idempotency_key_reuse

استُعمل Idempotency-Key نفسه مع جسم آخر.

429

rate_limited

طلبات كثيرة، ومنها أكثر من 30 كتابة على تخطيط الصفحة الرئيسية في الدقيقة للمتجر. انتظر المدة في Retry-After.

429

too_many_concurrent

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

500

server_error

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

هكذا تبدو استجابة invalid_settings.

{
  "error": {
    "code": "invalid_settings",
    "message": "Invalid value at settings.category: category not found in this store; accepted values are in settings_schema of GET /v1/store/home-layout",
    "fields": [{"path": "settings.category", "code": "invalid"}]
  },
  "meta": {"request_id": "e4c19a0b7d2f5836", "api_version": "v1"}
}

الحدود

  • 25 قسماً في الصفحة الرئيسية (max_sections).

  • حدّ الخطة (cap): 3 أقسام في الخطة المجانية أو خطة منتهية، و25 ابتداءً من Pro. الأقسام المخفية تُحسب. المتجر الذي تجاوز حدّه بعد نزول خطته يُبقي أقسامه ويستطيع تعديلها وإخفاءها وترتيبها وحذفها. الكتابة التي تترك أقساماً أكثر من الحدّ وأكثر مما كانت تُرجع 403 plan_required.

  • لكل نوع: لكل نوع limit في types، وهو 12 لـ category-products.

  • الإعدادات: 8 كيلوبايت لكل قسم بعد الترميز. النص الأطول يُقصّ عند max الخاص بالإعداد.

  • الجسم: 1 ميغابايت.

  • الكتابات: 30 في الدقيقة و5 في الوقت نفسه لكل متجر، فوق حدّ المتجر في الدقيقة. انظر حدود المعدل.

مفاتيح الصفحة الرئيسية في Digital وAriana وPrestige

تبني قوالب Digital وAriana وPrestige صفحتها الرئيسية من كتل ثابتة. ومجموعة أقدم من المفاتيح تُظهر هذه الكتل أو تخفيها وتحدّد عناوينها وفئاتها وبنراتها. يقرأ GET وPATCH /v1/store/home-sections هذه المفاتيح ويغيّرانها. وهي محفوظة بمعزل عن تخطيط الصفحة الرئيسية المشروح أعلاه، فالكتابة في أحدهما لا تغيّر الآخر أبداً.

القالب

الحقول التي يقرؤها

Digital وAriana

show_hero_slider، hero_slides، show_sidebar_widget، sidebar_widget_title، sidebar_widget_category_id، show_category_cards، show_top_sellers، top_sellers_title، show_popular_by_category، popular_by_category_title، show_promo_banners، banner_1_* وbanner_2_* (title وsubtitle وbutton_text وbutton_link وimage)، show_multi_column_lists، من column_1_title إلى column_4_title، من column_1_category_id إلى column_4_category_id، section_order

Prestige

show_testimonials وtestimonials_title وtestimonials

لا يقرأ أي قالب آخر هذه المفاتيح: في قالب آخر تُحفظ الكتابة وتُرجع 200، ولا يرى الزبائن أي تغيير. والمفتاح الذي لم يُحفظ أبداً يغيب عن الاستجابة، وعندها يُظهر Digital وAriana كتلته بينما يخفي Prestige آراء العملاء. يحدّد section_order ترتيب كتل Digital وAriana بالقيم hero_slider وcategory_cards وtop_sellers وpopular_by_category وpromo_banners وmulti_column_lists. والكتلة التي لا تَرِد في هذه القائمة لا تظهر.

GET /v1/store/home-sections

المصادقة: مفتاح منصة بصلاحية store:read. وكما في GET /v1/store/home-layout، تُخدَم الاستجابة حديثًا في كل نداء.

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

{
  "data": {
    "theme": "digital",
    "settings": {"show_top_sellers": 1, "top_sellers_title": "Meilleures ventes", "column_1_category_id": 57}
  },
  "meta": {"request_id": "...", "api_version": "v1"}
}

لا يحمل settings إلا الحقول التي حُفظت. والمتجر الذي لم يحفظ أي حقل يُرجع "settings": [].

PATCH /v1/store/home-sections

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

أرسل الحقول التي تريد تغييرها فقط: تحتفظ البقية بقيمها، وتُتجاهل الحقول غير المعروفة. تُحفظ حقول show_* على شكل 1 أو 0. ويأخذ *_category_id فئة من فئات هذا المتجر، و0 يُفرغه. يُنزع الفراغ من طرفي النص ثم يُقصّ عند 500 حرف، وtestimonials_title عند 200. ويقبل banner_1_button_link وbanner_2_button_link رابط https:// أو http:// أو mailto: أو tel:، أو /path، أو #anchor. ويحتفظ testimonials بـ 24 عنصراً كحد أقصى، لكل منها name وcomment وstars من 1 إلى 5.

curl -X PATCH 'https://api.dzbuild.app/v1/store/home-sections' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: hs-top-sellers-off-1" \
  -d '{"show_top_sellers": false, "column_1_category_id": 61}'

{
  "data": {
    "updated": ["show_top_sellers", "column_1_category_id"],
    "settings": {"show_top_sellers": 0, "top_sellers_title": "Meilleures ventes", "column_1_category_id": 61}
  },
  "meta": {"request_id": "...", "api_version": "v1"}
}

يسرد updated الحقول التي كُتبت، ويحمل settings كل الحقول المحفوظة بعد الكتابة. ولا تحمل الاستجابة change_id: يسرد GET /v1/changes?entity=store.home_sections هذه التغييرات، وPOST /v1/changes/{change_id}/undo يتراجع عن أحدها. التراجع عن أول كتابة لمفتاح لا يُرجع قيمته الافتراضية: يعود مفتاح show_* بالقيمة 0 ويعود section_order بالقيمة []، وهذا يخفي في Digital وAriana تلك الكتلة، أو كل الكتل. وللرجوع إلى القيم الافتراضية، أرسل 1 أو قائمة section_order كاملة عبر PATCH.

HTTP

الرمز

السبب

400

bad_request

الجسم ليس JSON، أو Idempotency-Key غائب أو غير صالح.

403

forbidden

Missing scope: store:read أو Missing scope: store:write، أو API access requires an active Enterprise plan لمفتاح تاجر متجره ليس على خطة Enterprise سارية.

422

no_writable_fields

لا يحمل الجسم أيّاً من الحقول التي تقبلها نقطة النهاية هذه.

422

invalid_category

*_category_id ليس فئة من فئات هذا المتجر.

422

invalid_url

رابط زر يستعمل مخططاً آخر، مثل javascript:.

422

idempotency_key_reuse

استُعمل Idempotency-Key نفسه مع جسم آخر.

معنى 401 و402 و413 و500 هو نفسه في كتابات تخطيط الصفحة الرئيسية. أما 429 rate_limited فيأتي فقط من الحدود العامة في الدقيقة المشروحة في حدود المعدل: حدود كتابات تخطيط الصفحة الرئيسية لا تنطبق هنا.

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