المنتجات
المنتج هو الوحدة الأساسية القابلة للبيع في المتجر. كل نداءات المنتجات مقيّدة بمتجر المفتاح المنادي — لا يمكنك أبدًا الوصول إلى بيانات تاجر آخر بالخطأ.
GET /v1/products
قائمة المنتجات. ترقيم بالمؤشّر. مخزَّنة في ذاكرة الحافة لمدة 30 ثانية.
المصادقة: مفتاح منصة بصلاحية products:read.
معاملات الاستعلام
| المعامل | النوع | الافتراضي | ملاحظات |
|---|---|---|---|
limit | int (1–200) | 50 | حجم الصفحة |
cursor | string | — | من next_cursor لاستجابة سابقة |
status | active | draft | archived | — | تصفية حسب الحالة |
search | string | — | يطابق name (LIKE) وsku بالضبط |
الطلب
curl 'https://api.dzbuild.app/v1/products?limit=10&status=active' \
-H "Authorization: Bearer $DZ_KEY"
الاستجابة 200
{
"data": {
"items": [
{
"id": 26,
"name": "PRO",
"slug": "pro",
"short_description": null,
"price": 1000,
"compare_price": null,
"sku": "",
"stock_quantity": 0,
"track_stock": false,
"status": "active",
"has_variants": true,
"featured": false,
"primary_image": "13_1768313552_b33d660c_1562f6687591.webp",
"created_at": "2026-01-13 15:06:06",
"updated_at": "2026-01-13 15:12:32"
}
],
"next_cursor": null,
"has_more": false
},
"meta": { "request_id": "...", "api_version": "v1" }
}
primary_image هو اسم ملف. حوّله إلى رابط بـ https://cdn.dzbuild.app/<store_id>/products/<filename> (أو نطاق CDN المخصص لديك). المسار الكامل موجود في images[].url على GET /v1/products/{id}.
GET /v1/products/{id}
تفاصيل المنتج كاملة بما فيها الصور والمتغيرات.
المصادقة: مفتاح منصة بصلاحية products:read.
الطلب
curl https://api.dzbuild.app/v1/products/26 \
-H "Authorization: Bearer $DZ_KEY"
الاستجابة 200
{
"data": {
"id": 26,
"name": "PRO",
"slug": "pro",
"description": "- Single store\n- Up to 300 products\n- ...",
"short_description": null,
"category_id": null,
"pricing": {
"price": 1000,
"compare_price": null,
"cost_price": null
},
"inventory": {
"sku": "",
"barcode": null,
"track_stock": false,
"stock_quantity": 0,
"low_stock_alert": 5
},
"shipping": {
"weight": null, "height": null, "width": null, "length": null,
"do_insurance": false
},
"status": "active",
"featured": false,
"has_variants": true,
"images": [
{ "id": 28, "url": "13_1768313552_b33d660c_1562f6687591.webp",
"is_primary": true, "sort_order": 0 }
],
"variants": [
{
"id": 11,
"name": "Duration",
"type": "text",
"options": [
{ "id": 14, "value": "30 days", "color_code": null, "image_id": null, "stock": null },
{ "id": 15, "value": "90 days", "color_code": null, "image_id": null, "stock": null },
{ "id": 16, "value": "180 days", "color_code": null, "image_id": null, "stock": null },
{ "id": 17, "value": "365 days", "color_code": null, "image_id": null, "stock": null }
]
}
],
"created_at": "2026-01-13 15:06:06",
"updated_at": "2026-01-13 15:12:32"
}
}
POST /v1/products — إنشاء
المصادقة: مفتاح منصة بصلاحية products:write. يتطلب Idempotency-Key.
الجسم
| الحقل | النوع | إلزامي | ملاحظات |
|---|---|---|---|
name | string (1–255) | ✅ | |
price | number ≥ 0 | ✅ | بالدينار الجزائري |
compare_price | number ≥ 0 | null | السعر المشطوب | |
cost_price | number ≥ 0 | null | للتاجر فقط — لا يُعرض للعميل | |
description | string | وصف طويل، يقبل الأسطر | |
short_description | string ≤ 500 | عبارة قصيرة | |
sku | string ≤ 100 | SKU داخلي | |
barcode | string ≤ 100 | UPC/EAN | |
weight | number | كغ، للشحن | |
shipping_height / width / length | number | سم | |
do_insurance | bool | فرض تأمين الشحن لهذا المنتج | |
track_stock | bool | الافتراضي false | |
stock_quantity | int ≥ 0 | إن كان track_stock | |
low_stock_alert | int ≥ 0 | الافتراضي 5. يُطلق webhook product.stock_low. | |
variant_stock_enabled | bool | SKUs لكل متغيّر | |
combination_stock_enabled | bool | SKUs لكل (لون × مقاس). يستلزم variant_stock_enabled. | |
category_id | int | يجب أن يكون موجودًا في متجرك | |
status | active | draft | archived | الافتراضي draft | |
featured | bool | الافتراضي false |
عند تفعيل variant_stock_enabled أو combination_stock_enabled، يُعطَّل track_stock تلقائيًا (المتغيرات تتحكم بمخزونها).
حد الخطة
Free: 5 منتجات نشطة. Pro: 300. Unlimited / Enterprise: غير محدود. يحسب فقط الصفوف بحالة active. المسوّدات لا تُحسب. عند بلوغ الحد:
{ "error": { "code": "bad_request",
"message": "Plan 'free' allows at most 5 active products. Upgrade to add more." } }
الطلب
curl -X POST 'https://api.dzbuild.app/v1/products' \
-H "Authorization: Bearer $DZ_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"name": "T-shirt - Cotton 200gsm",
"price": 1500,
"compare_price": 1900,
"description": "100% cotton, made in Algeria.",
"sku": "TS-COT-200",
"stock_quantity": 50,
"track_stock": true,
"status": "draft"
}'
الاستجابة 201
تردّ بنفس شكل GET /v1/products/{id}. id و slug و created_at صارت معبّأة. slug يُولَّد تلقائيًا من name ويُجعل فريدًا داخل متجرك. يمكنك تجاوزه بإرسال slug خاص (يخضع لتطبيع [a-z0-9-]).
الأخطاء
| الكود | السبب |
|---|---|
bad_request "Body must be valid JSON" | Content-Type خاطئ أو JSON تالف |
bad_request "name is required (1-255 chars)" | الاسم مفقود أو طويل جدًا |
bad_request "price must be a non-negative number" | سعر غير صالح |
bad_request "category_id N does not belong to this store" | فئة من متجر آخر |
bad_request "Plan 'free' allows at most …" | تجاوز حد الخطة |
PATCH /v1/products/{id} — تعديل
المصادقة: مفتاح منصة بصلاحية products:write. يتطلب Idempotency-Key.
تحديث جزئي — أرسل فقط الحقول التي تريد تغييرها. الحقول غير المرسلة تُحفظ كما هي.
curl -X PATCH 'https://api.dzbuild.app/v1/products/26' \
-H "Authorization: Bearer $DZ_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{ "price": 1200, "status": "active" }'
تُرجع 200 والمنتج الكامل المحدَّث. إذا لم يكن المنتج موجودًا (أو ينتمي لمتجر آخر) ستحصل على 404 not_found.
عند تغيير الاسم عبر PATCH { name: ... } يُعاد توليد الـ slug تلقائيًا فقط إن لم تُرسل slug صراحةً. أرسل slug للحفاظ على رابط محدد بعد إعادة التسمية.
DELETE /v1/products/{id}
المصادقة: مفتاح منصة بصلاحية products:write. يتطلب Idempotency-Key.
curl -X DELETE 'https://api.dzbuild.app/v1/products/26' \
-H "Authorization: Bearer $DZ_KEY" \
-H "Idempotency-Key: del-26-2026-04-30"
الاستجابة:
{ "data": { "deleted": true, "id": 26 } }
هذا حذف نهائي — صف المنتج يُحذف، وتسلسل المفاتيح الأجنبية ينظّف الصور والمتغيرات والعروض والتركيبات. ملفات الصور في R2 تُترك لعملية تنظيف غير متزامنة (لا نُؤخّر نداء API بحذف R2).
POST /v1/products/{id}/images (قادم في v1.1)
سيُعيد رابط PUT موقّعًا مسبقًا لـ R2 ليرفع عميلك الملفات مباشرة إلى Cloudflare R2 — بدون رحلة عبر الخادم الجزائري وبدون عرقلة FPM بمعالجة الصور.
حتى ذلك الحين، يتم رفع الصور من لوحة التحكم: المنتجات → تعديل → الصور.