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

صفحات الهبوط

صفحة الهبوط صفحة تحويل مركّزة لمنتج واحد. مستقلة عن كتالوج الواجهة — يمكنك امتلاك صفحة هبوط بدون منتج حي (لإطلاقات قادمة)، أو واحدة مرتبطة بمنتج لإعلانات مدفوعة.

تُدار الأقسام (السلايدرات، الزوار الوهميون، العدّاد التنازلي…) من لوحة التحكم في v1؛ الواجهة البرمجية تُجري CRUD على السجل الأم فقط. تحديث v1.1 سيكشف CRUD الأقسام أيضًا.

حدود الخطة

الخطةصفحات الهبوط (كل الحالات — المسودات محسوبة)
Free0 (شراء لمرة واحدة: 1000 دج/مدى الحياة لكل منها)
Pro3
Unlimited / Enterpriseغير محدود

الحد يُفرض من تدفّقي الإنشاء والنسخ في لوحة التحكم فقط، مع احتساب كل صفحة هبوط بما فيها المسودات. أما الواجهة البرمجية فلا تفرض شيئًا: POST /v1/landing-pages متبوعًا بـ /publish يتجاوز الحد بالكامل، وعلى خطة مدفوعة تُعرض الصفحات الزائدة حيّة على واجهة المتجر. أما صفحات الخطة المجانية فتبقى غير مرئية ما لم تكن الصفحة مشتراة (is_purchased).

GET /v1/landing-pages

اسرد صفحات الهبوط. ترقيم بالمؤشّر. مخزَّنة مؤقتًا لمدة 30 ثانية — تحقّق من ترويسة الاستجابة X-Cache: HIT|MISS. أما GET /v1/landing-pages/{id} فغير مُخزَّنة.

المصادقة: أي مفتاح منصة نشِط للمتجر (landing_pages:read غير مطبَّقة في v1؛ المفحوصة هي landing_pages:write فقط على نقاط الكتابة).

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

المعاملالنوعملاحظات
limitint 1–200الافتراضي 50
cursorstringغير شفاف
statusactive | draftتصفية

القيمة غير المعروفة في status تُتجاهَل فتُرجَع كل الصفحات بدل 400.

الاستجابة 200

{
"data": {
"items": [
{
"id": 42,
"title": "Black T-Shirt — 30% off",
"slug": "black-tshirt-30-off",
"status": "active",
"language": "ar",
"product_id": 26,
"views": 1543,
"is_purchased": false,
"created_at": "2026-03-01 10:00:00",
"updated_at": "2026-03-15 14:22:11"
}
],
"next_cursor": null,
"has_more": false
}
}

GET /v1/landing-pages/{id}

تفاصيل مع section_count.

{
"data": {
"id": 42,
"title": "Black T-Shirt — 30% off",
"slug": "black-tshirt-30-off",
"status": "active",
"language": "ar",
"product_id": 26,
"views": 1543,
"is_purchased": false,
"meta_title": "Black T-Shirt — Cotton 200gsm — 30% off | DZBuild",
"meta_description": "Limited-time offer on our cotton black t-shirt.",
"section_count": 7,
"created_at": "2026-03-01 10:00:00",
"updated_at": "2026-03-15 14:22:11"
}
}

مرجع الحقول

الحقلملاحظات
statusactive أو draft فقط بصرامة — لا توجد حالة archived لصفحات الهبوط.
languagear أو fr أو en.
product_idالمنتج المرتبط، أو null. الصفحة بلا معرّف منتج لا تستطيع تسعير نموذج طلبها بشكل صحيح.
viewsللقراءة فقط. تُحتسب في كل مرة تُشاهَد فيها الصفحة العامة؛ ولا تستطيع الواجهة البرمجية كتابتها ولا توجد طريقة لتصفيرها.
is_purchasedtrue بمجرد شراء الصفحة نهائيًا (1000 دج/مدى الحياة). على الخطة المجانية هذا ما يجعل الصفحة مرئية على واجهة المتجر.
section_countفي نقطة التفاصيل فقط — عدّ حيّ لأقسام الصفحة يُحسب مع كل طلب.
meta_title / meta_descriptionوسوم SEO. انظر الملاحظة تحت الإنشاء.

POST /v1/landing-pages — إنشاء

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

الجسم

الحقلالنوعإلزاميملاحظات
titlestring 1–255
slugstringيُشتق تلقائيًا من title إن أُغفل. أما الـ slug الذي ترسله هنا فيُخزَّن بدون تطبيع — أرسل قيمة نظيفة
statusactive | draftالافتراضي draft. أي قيمة أخرى تُحوَّل بصمت إلى draft
languagear | fr | enالافتراضي ar. أي قيمة أخرى تُحوَّل بصمت إلى ar
product_idintيجب أن ينتمي إلى متجرك؛ الصفحة تربط بهذا المنتج
meta_titlestring ≤ 255عنوان SEO. إن أغفلته عبر الواجهة البرمجية يُخزَّن ويُرجَع كـ null (بخلاف نموذج لوحة التحكم الذي ينسخ title إليه). ومع ذلك تعرض الصفحة العامة title كبديل، فعنوان الصفحة الظاهر صحيح في الحالتين
meta_descriptionstringوصف SEO

تُجعل الـ slugs فريدة داخل متجرك بإلحاق -2 و-3 وهكذا. وإن كان أساس الـ slug فارغًا فيُستعمل landing- متبوعًا بـ 6 أحرف hex.

الأخطاء

الكودالسبب
bad_request "Body must be valid JSON"Content-Type خاطئ أو JSON تالف
bad_request "title is required (1-255 chars)"العنوان مفقود أو طويل جدًا
bad_request "product_id N does not belong to this store"معرّف من متجر آخر

الطلب

curl -X POST 'https://api.dzbuild.app/v1/landing-pages' \
-H "Authorization: Bearer $DZ_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"title": "Black T-Shirt — 30% off",
"language": "ar",
"product_id": 26,
"status": "draft"
}'

تُرجع 200 (وليس 201) وبنفس شكل GET /v1/landing-pages/{id}. صفحة الهبوط الجديدة بدون أقسام — أضفها من لوحة التحكم.

PATCH /v1/landing-pages/{id}

تحديث جزئي.

يتحقّق PATCH بصرامة أكبر من الإنشاء: status غير صالح يُرجع 400 bad_request ("status must be active or draft")، وlanguage غير صالح يُرجع 400 ("language must be ar, fr, or en") بدل التحويل الصامت. ويجب أن يبقى title بين 1 و255 حرفًا. أما الـ slug المُرسَل في PATCH فيُطبَّع، بخلاف الإنشاء.

curl -X PATCH 'https://api.dzbuild.app/v1/landing-pages/42' \
-H "Authorization: Bearer $DZ_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{ "title": "Black T-Shirt — Spring promo" }'

تغيير العنوان يُعيد توليد slug تلقائيًا فقط إن لم تُرسل slug صراحةً.

POST /v1/landing-pages/{id}/publish

اختصار: تحويل الحالة إلى active. يكافئ PATCH ... { status: "active" }.

curl -X POST 'https://api.dzbuild.app/v1/landing-pages/42/publish' \
-H "Authorization: Bearer $DZ_KEY" \
-H "Idempotency-Key: publish-42-$(date +%s)"

DELETE /v1/landing-pages/{id}

حذف نهائي. وتُحذف أقسام الصفحة معها.

curl -X DELETE 'https://api.dzbuild.app/v1/landing-pages/42' \
-H "Authorization: Bearer $DZ_KEY" \
-H "Idempotency-Key: del-42"

الاستجابة: { "data": { "deleted": true, "id": 42 } }.