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

الفئات

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

بقلم: Support

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

ينضم المنتج إلى فئة عبر حقله category_id، انظر المنتجات. وقسم category-products في الصفحة الرئيسية يأخذ رقم فئة أيضاً، انظر أقسام الصفحة الرئيسية.

قبل أن تبدأ

  • تحتاج القراءة إلى products:read وتحتاج الكتابات إلى products:write، وهما صلاحيتا المنتجات نفسهما. مفاتيح التاجر تحمل الاثنتين.

  • تحتاج POST وPATCH وDELETE إلى Idempotency-Key. انظر Idempotency.

  • صورة الفئة تُضاف من لوحة التحكم. الواجهة البرمجية تُرجع رابطها ولا تستطيع رفعها أو تغييرها.

كائن الفئة

الحقل

النوع

ملاحظات

id

int

رقم الفئة.

name

string

من 1 إلى 100 حرف.

slug

string

يُصنع من الاسم وهو فريد في المتجر. صفحة الفئة في المتجر تستعمله في عنوانها.

description

string أو null

نص حر.

image

string أو null

الرابط الكامل للصورة، أو null.

parent_id

int أو null

الفئة الأم، أو null للفئة الرئيسية.

show_subcategories

bool

يعرض الفئات الفرعية كبطاقات في صفحة الفئة على المتجر (عرض قسم الفئات الفرعية في نموذج الفئة). يُحفظ true للفئة الفرعية. وما دام الفئات الفرعية داخل الفئة الرئيسية فقط مفعّلاً (/dashboard/categories)، يعرض المتجر البطاقات في صفحة كل فئة مهما كانت قيمة هذا الحقل.

sort_order

int

الموضع في قوائم الفئات بالمتجر، الأصغر أولاً.

status

string

active أو inactive.

created_at

string

بصيغة YYYY-MM-DD HH:MM:SS بتوقيت الخادم.

تضيف القائمة والقراءة الفردية product_count، وهو عدد المنتجات في الفئة. وتضيف القراءة الفردية أيضاً children، أي فئاتها الفرعية.

GET /v1/categories

فئات المتجر، الأحدث أولاً، في قائمة بمؤشر. رتّبها حسب sort_order لتحصل على ترتيب المتجر.

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

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

المعامل

النوع

الافتراضي

ملاحظات

parent_id

رقم أو 0 أو null

لا شيء

رقم فئة يُرجع فئاتها الفرعية. و0 أو null أو قيمة فارغة تُرجع الفئات الرئيسية. وأي قيمة أخرى تُرجع 400 bad_request.

status

active أو inactive

لا شيء

الفئات التي لها هذه الحالة فقط. وأي قيمة أخرى تُتجاهل.

limit

int

50

من 1 إلى 200.

cursor

string

لا شيء

قيمة next_cursor من الصفحة السابقة. انظر الترقيم.

الطلب

curl 'https://api.dzbuild.app/v1/categories?parent_id=0' \
  -H "Authorization: Bearer $DZ_KEY"

الاستجابة 200

{
  "data": {
    "items": [
      {
        "id": 14,
        "name": "Montres",
        "slug": "montres",
        "description": null,
        "image": null,
        "parent_id": null,
        "show_subcategories": true,
        "sort_order": 4,
        "status": "active",
        "created_at": "2026-09-30 11:20:05",
        "product_count": 0
      },
      {
        "id": 10,
        "name": "Parfums",
        "slug": "parfums",
        "description": "Eaux de parfum et coffrets",
        "image": null,
        "parent_id": null,
        "show_subcategories": true,
        "sort_order": 1,
        "status": "active",
        "created_at": "2026-09-12 09:41:37",
        "product_count": 18
      }
    ],
    "next_cursor": null,
    "has_more": false
  }
}

GET /v1/categories/{id}

فئة واحدة مع product_count وchildren، أي فئاتها الفرعية مرتبة حسب sort_order.

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

إذا لم يكن رقم الفئة في المسار أرقاماً فقط، يُرجع النداء 400 bad_request. وفئة متجر آخر تُرجع 404 not_found، مثل فئة غير موجودة.

الطلب

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

الاستجابة 200

{
  "data": {
    "id": 10,
    "name": "Parfums",
    "slug": "parfums",
    "description": "Eaux de parfum et coffrets",
    "image": null,
    "parent_id": null,
    "show_subcategories": true,
    "sort_order": 1,
    "status": "active",
    "created_at": "2026-09-12 09:41:37",
    "children": [
      {"id": 11, "name": "Parfums femme", "slug": "parfums-femme", "sort_order": 2, "status": "active"},
      {"id": 12, "name": "Parfums homme", "slug": "parfums-homme", "sort_order": 3, "status": "active"}
    ],
    "product_count": 18
  }
}

POST /v1/categories

تنشئ فئة وتضعها في الأخير: قيمة sort_order لها تزيد بواحد على أكبر قيمة في المتجر.

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

الجسم

الحقل

النوع

إلزامي

ملاحظات

name

string

نعم

تُحذف المسافات من الطرفين، من 1 إلى 100 حرف.

description

string أو null

لا

تُحذف المسافات من الطرفين. النص الفارغ يُحفظ null.

parent_id

int أو null

لا

فئة رئيسية من هذا المتجر: تصبح الفئة الجديدة فئة فرعية لها. وnull أو 0 تُنشئ فئة رئيسية.

status

active أو inactive

لا

القيمة الافتراضية active.

show_subcategories

bool

لا

القيمة الافتراضية true. تُتجاهل وتُحفظ true للفئة الفرعية، أو ما دام الفئات الفرعية داخل الفئة الرئيسية فقط مفعّلاً.

يُصنع الـ slug من الاسم: بأحرف صغيرة، مع الإبقاء على الحروف والأرقام، وتتحول كل سلسلة من الرموز الأخرى إلى - واحدة. الاسم العربي يحتفظ بحروفه العربية. وإذا كان لفئة أخرى في المتجر الـ slug نفسه، تُضاف -2 ثم -3 وهكذا.

الطلب

curl -X POST 'https://api.dzbuild.app/v1/categories' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: cat-create-coffrets-1" \
  -d '{"name": "Coffrets cadeaux", "parent_id": 10}'

الاستجابة 201

الاستجابة هي كائن الفئة، دون product_count وchildren.

{
  "data": {
    "id": 15,
    "name": "Coffrets cadeaux",
    "slug": "coffrets-cadeaux",
    "description": null,
    "image": null,
    "parent_id": 10,
    "show_subcategories": true,
    "sort_order": 5,
    "status": "active",
    "created_at": "2026-10-06 14:02:11"
  }
}

PATCH /v1/categories/{id}

تغيّر الحقول التي ترسلها فقط. يأخذ الجسم حقول POST نفسها، وكلها اختيارية.

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

  • name جديد يعطي slug جديداً، فيتغير عنوان صفحة الفئة في المتجر وتتوقف الروابط إلى العنوان القديم عن العمل. وإرسال الاسم نفسه يُبقي الـ slug.

  • parent_id ينقل الفئة. رقم فئة رئيسية يجعلها فئة فرعية، وnull أو 0 يجعلها فئة رئيسية. الفئة التي لها فئات فرعية لا يمكن أن تصبح فئة فرعية، ولا يمكن أن تكون الفئة أُمّاً لنفسها.

  • الجسم الفارغ لا يغيّر شيئاً ويُرجع الفئة كما هي.

الطلب

curl -X PATCH 'https://api.dzbuild.app/v1/categories/15' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: cat-15-move-1" \
  -d '{"parent_id": null, "status": "inactive"}'

الاستجابة 200

{
  "data": {
    "id": 15,
    "name": "Coffrets cadeaux",
    "slug": "coffrets-cadeaux",
    "description": null,
    "image": null,
    "parent_id": null,
    "show_subcategories": true,
    "sort_order": 5,
    "status": "inactive",
    "created_at": "2026-10-06 14:02:11"
  }
}

DELETE /v1/categories/{id}

تحذف فئة فارغة مع صورتها.

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

الفئة التي ما زالت تضم منتجات أو فئات فرعية تُرجع 409 category_not_empty ولا يُحذف شيء. رسالة الخطأ تذكر العدد. لتفريغ الفئة:

  • الفئات الفرعية: اجعل كل واحدة فئة رئيسية بـ PATCH و"parent_id": null، أو احذفها أولاً.

  • المنتجات: الواجهة البرمجية لا تستطيع إخراج منتج من فئة. تحديد category_id لمنتج يضيف فئة ويُبقي الفئات التي ينتمي إليها من قبل، انظر المنتجات. غيّر فئات تلك المنتجات من لوحة التحكم.

الطلب

curl -X DELETE 'https://api.dzbuild.app/v1/categories/14' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Idempotency-Key: cat-14-delete-1"

الاستجابة 200

{
  "data": {
    "deleted": true,
    "id": 14
  }
}

POST /v1/categories/reorder

تضبط sort_order للفئات التي تذكرها دفعة واحدة: إما أن تتغير كلها أو لا يتغير أي منها.

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

الجسم

الحقل

النوع

إلزامي

ملاحظات

categories

array

نعم

الفئات بترتيبها الجديد. كل عنصر هو {"id": 10} أو {"id": 10, "sort_order": 7} أو رقم وحده مثل 10.

  • العنصر الذي ليس فيه sort_order يأخذ موضعه في المصفوفة: 1 ثم 2 ثم 3 وهكذا. والعنصر الذي فيه sort_order يأخذ ذلك الرقم.

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

  • الفئات التي لا تذكرها تحتفظ بقيمة sort_order الخاصة بها.

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

الطلب

curl -X POST 'https://api.dzbuild.app/v1/categories/reorder' \
  -H "Authorization: Bearer $DZ_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: cat-reorder-1" \
  -d '{"categories": [{"id": 14}, {"id": 10}]}'

الاستجابة 200

{
  "data": {
    "reordered": 2,
    "categories": [
      {"id": 14, "sort_order": 1},
      {"id": 10, "sort_order": 2}
    ]
  }
}

التراجع

تُسجَّل POST وPATCH وDELETE في سجل تغييرات المتجر. استجاباتها لا تحمل رقم التغيير: GET /v1/changes?entity=category تعرض تغييرات الفئات، الأحدث أولاً، بصلاحية store:read. والحقل entity_id هو رقم الفئة.

الطلب

curl 'https://api.dzbuild.app/v1/changes?entity=category&limit=1' \
  -H "Authorization: Bearer $DZ_KEY"

الاستجابة 200

{
  "data": {
    "items": [
      {
        "id": 120,
        "entity": "category",
        "entity_id": "15",
        "action": "update",
        "summary": "Updated category #15 (parent_id, status, show_subcategories)",
        "undone_at": null,
        "created_at": "2026-10-06 14:05:48",
        "undone": false
      }
    ],
    "next_cursor": "MTIw",
    "has_more": true
  }
}

يتراجع POST /v1/changes/{id}/undo عن تغيير واحد. ويحتاج إلى products:write وIdempotency-Key.

  • التراجع عن PATCH يُرجع القيم السابقة للحقول التي غيّرها ذلك النداء، مع فحوص PATCH نفسها.

  • التراجع عن DELETE يُنشئ الفئة من جديد برقمها القديم، دون صورتها. وإذا حُذفت فئتها الأم القديمة أو صارت فئة فرعية، يُرجع التراجع 422 invalid_parent.

  • لا يمكن التراجع عن الإنشاء: يُرجع التراجع 422 nothing_to_restore. احذف الفئة بدلاً من ذلك.

  • إذا لم تعد الفئة موجودة، أو أُخذ رقمها القديم، يُرجع التراجع 422 restore_target_missing.

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

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

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

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

{
  "data": {
    "undone": true,
    "change_id": 120,
    "entity": "category",
    "undo_change_id": 121
  }
}

الأخطاء

HTTP

الرمز

السبب

400

bad_request

الرقم في المسار ليس أرقاماً فقط، أو الجسم ليس JSON صالحاً، أو مرشّح parent_id ليس رقماً ولا 0 ولا null ولا قيمة فارغة، أو categories غائب أو ليس مصفوفة، أو Idempotency-Key غائب أو غير صالح.

401

unauthorized

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

402

quota_exceeded

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

403

forbidden

Missing scope: products:read أو Missing scope: products:write أو Missing scope: store:read، أو API access requires an active Enterprise plan لمفتاح تاجر متجره ليس على خطة Enterprise سارية، أو Apps cannot use this endpoint عندما يقرأ رمز تطبيق مثبّت التغييرات أو يتراجع عنها.

404

not_found

لا توجد فئة بهذا الرقم في المتجر، أو تذكر إعادة الترتيب رقماً ليس في المتجر، أو يذكر التراجع تغييراً ليس في سجل تغييرات المتجر.

409

category_not_empty

الفئة ما زالت تضم منتجات أو فئات فرعية.

409

already_undone

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

413

payload_too_large

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

422

validation_error

name غائب أو فارغ أو أطول من 100 حرف، أو status ليست active ولا inactive، أو parent_id ليس رقماً، أو إعادة الترتيب فارغة أو تكرر رقماً أو فيها رقم ليس عدداً صحيحاً موجباً أو sort_order ليس عدداً صحيحاً.

422

invalid_parent

parent_id ليس فئة من هذا المتجر، أو هو نفسه فئة فرعية، أو هو الفئة نفسها، أو للفئة فئات فرعية فلا يمكن نقلها تحت فئة أخرى.

422

nothing_to_restore

للتراجع فقط: التغيير أنشأ الفئة.

422

restore_target_missing

للتراجع فقط: الفئة لم تعد موجودة، أو أُخذ رقمها القديم.

422

idempotency_key_reuse

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

429

rate_limited

نداءات كثيرة في الدقيقة الحالية. انتظر الثواني المذكورة في Retry-After. انظر حدود المعدل.

500

server_error

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

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