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

الرموز الترويجية

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

يُخصم الرمز من المجموع الفرعي للمنتجات، ولا يُخصم أبداً من التوصيل. الرمز من نوع percentage يأخذ تلك النسبة من المجموع الفرعي. والرمز من نوع fixed يطرح مبلغه بالدينار، ولا يطرح أبداً أكثر من المجموع الفرعي. لا يمكن حصر رمز في منتج أو فئة أو زبون، ولا وضع سقف للخصم على سلة كبيرة، ولا منح التوصيل المجاني به.

قبل أن تبدأ​

  • يجب أن تكون إضافة الرموز الترويجية مفعّلة في المتجر (/dashboard/addons). القائمة تعمل بدونها وتُخبرك بحالتها في addon_enabled. كل كتابة تُرجع 409 addon_inactive ما دامت الإضافة معطّلة، ولا يستطيع الزبائن استعمال أي رمز عند إتمام الطلب خلال ذلك.
  • يحتاج المفتاح صلاحيات الرموز الترويجية. المفاتيح المُنشأة من لوحة التحكم (/dashboard/api) تحصل على الاثنتين. الصلاحيات تُجمَّد لحظة إنشاء المفتاح، فالمفتاح الذي لا يملكهما يُرجع 403 forbidden: أنشئ مفتاحاً جديداً من لوحة التحكم.
  • الحقلان starts_at وexpires_at بتوقيت الجزائر، بالشكل YYYY-MM-DD HH:MM:SS.
النطاقالوصف
promos:readالاطلاع على الرموز الترويجية.
promos:writeإنشاء الرموز الترويجية وتعديلها وحذفها. هذا يغيّر الأسعار التي يدفعها زبائنك.

كائن الرمز الترويجي​

الحقلالنوعالمعنى
idintرقم الرمز في المتجر.
codestringما يكتبه الزبون. بأحرف كبيرة، A-Z و0-9 و- و_، وفريد داخل المتجر.
discount_typestringpercentage أو fixed.
discount_valuenumberالنسبة (أكبر من 0 وحتى 100) أو المبلغ بالدينار.
min_order_amountnumber أو nullالمجموع الفرعي للمنتجات الذي يجب أن يبلغه الطلب حتى يُطبَّق الرمز. null تعني بلا حد أدنى.
max_usesint أو nullعدد الطلبات التي يمكنها استعمال الرمز. null تعني بلا حد.
used_countintعدد الطلبات التي استعملته. للقراءة فقط.
is_activeboolالرمز غير المفعّل يُرفض عند إتمام الطلب.
starts_atstring أو nullقبل هذا الوقت يُرفض الرمز. null تعني أنه يعمل فوراً.
expires_atstring أو nullبعد هذا الوقت يُرفض الرمز. null تعني أنه لا ينتهي أبداً.
created_at، updated_atstringYYYY-MM-DD HH:MM:SS، بتوقيت الخادم.

GET /v1/promo-codes​

رموز المتجر، الأحدث أولاً. لا يوجد نداء يقرأ رمزاً واحداً برقمه: تصفّح هذه القائمة.

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

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

المعاملالنوعالافتراضيملاحظات
is_activestringلا شيءtrue أو 1 أو yes أو on تُرجع الرموز المفعّلة. أي قيمة أخرى تُرجع الرموز المعطّلة. اتركه للحصول على كل الرموز.
limitint50من 1 إلى 200.
cursorstringلا شيءقيمة next_cursor من الصفحة السابقة. انظر الترقيم.

الطلب​

curl 'https://api.dzbuild.app/v1/promo-codes?is_active=true' \
-H "Authorization: Bearer $DZ_KEY"

الاستجابة 200​

{
"data": {
"items": [
{
"id": 20,
"code": "WELCOME10",
"discount_type": "percentage",
"discount_value": 10,
"min_order_amount": 3000,
"max_uses": 100,
"used_count": 7,
"is_active": true,
"starts_at": null,
"expires_at": "2026-11-30 23:59:00",
"created_at": "2026-10-06 14:20:11",
"updated_at": "2026-10-06 14:20:11"
}
],
"next_cursor": null,
"has_more": false,
"addon_enabled": true
}
}

يُبيّن addon_enabled إن كانت إضافة الرموز الترويجية مفعّلة. عندما تكون قيمته false تبقى القائمة تعمل، لكن الكتابة تفشل ولا يستطيع الزبائن استعمال الرموز.

POST /v1/promo-codes​

يُنشئ رمزاً. يعمل الرمز عند إتمام الطلب بمجرد إنشائه، إلا إذا أرسلت is_active: false أو starts_at بتاريخ لاحق.

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

الجسم​

الحقلالنوعإلزاميملاحظات
codestringنعمتُحذف المسافات من طرفيه وتتحوّل الأحرف إلى كبيرة، ثم يجب أن يكون من 2 إلى 30 حرفاً من A-Z أو 0-9 أو - أو _. الرمز الموجود من قبل في المتجر يُرجع 409 code_exists.
discount_typestringنعمpercentage أو fixed، بأحرف كبيرة أو صغيرة. لا توجد قيمة افتراضية.
discount_valuenumberنعمأكبر من 0. لا يتجاوز 100 مع percentage، والقيمة 100 تحتاج تأكيد التاجر (انظر قسم خصم 100% أسفله). لا حد أعلى مع fixed.
min_order_amountnumber أو nullلاالحد الأدنى للمجموع الفرعي للمنتجات بالدينار. 0 أو "" أو null تعني بلا حد أدنى.
max_usesint أو nullلا1 أو أكثر. 0 أو "" أو null تعني بلا حد.
is_activeboolلاالافتراضي true. أرسل قيمة JSON منطقية: النص "false" مثلاً يُقرأ true.
starts_atstring أو nullلاصيغة تاريخ وساعة شائعة، مثل 2026-11-01 08:00 أو نص بصيغة ISO 8601. يُخزَّن بالشكل YYYY-MM-DD HH:MM:SS بتوقيت الجزائر، والقيمة التي تحمل فارقاً عن UTC تُحوَّل. null أو "" تعني بلا تاريخ بدء.
expires_atstring أو nullلاالصيغ نفسها. يجب أن يكون في المستقبل وبعد starts_at. null أو "" تعني بلا تاريخ انتهاء.
confirm_tokenstringلالخصم 100% فقط.
confirm_full_discountboolلالخصم 100% فقط.

الطلب​

curl -X POST 'https://api.dzbuild.app/v1/promo-codes' \
-H "Authorization: Bearer $DZ_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: promo-welcome10-create" \
-d '{"code": "welcome10", "discount_type": "percentage", "discount_value": 10, "min_order_amount": 3000, "max_uses": 100, "expires_at": "2026-11-30 23:59"}'

الاستجابة 201​

{
"data": {
"id": 20,
"code": "WELCOME10",
"discount_type": "percentage",
"discount_value": 10,
"min_order_amount": 3000,
"max_uses": 100,
"used_count": 0,
"is_active": true,
"starts_at": null,
"expires_at": "2026-11-30 23:59:00",
"created_at": "2026-10-06 14:20:11",
"updated_at": "2026-10-06 14:20:11"
}
}

PATCH /v1/promo-codes/{id}​

يغيّر الحقول التي ترسلها فقط، بقواعد الإنشاء نفسها. الحقل الذي لا ترسله يحتفظ بقيمته.

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

  • يمكن تغيير code. يجب ألا يكون النص الجديد مستعملاً في المتجر، وإلا يُرجع النداء 409 code_exists.
  • يُفحص discount_type وdiscount_value معاً. إرسال discount_type: "percentage" وحده على رمز fixed بـ 500 د.ج يُرجع 422 invalid_discount_value، لأن 500 أكبر من 100. أرسل الحقلين.
  • يجب أن يكون expires_at الجديد في المستقبل. الرمز المنتهي الصلاحية يبقى قابلاً للتعديل ما دمت لا ترسل expires_at.
  • لا يمكن كتابة used_count.
  • الجسم الفارغ لا يغيّر شيئاً ويُرجع الرمز.
  • رمز متجر آخر يُرجع 404، مثل رمز غير موجود.

الطلب​

curl -X PATCH 'https://api.dzbuild.app/v1/promo-codes/20' \
-H "Authorization: Bearer $DZ_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: promo-20-extend" \
-d '{"max_uses": 200, "expires_at": "2026-12-31 23:59"}'

الاستجابة 200​

{
"data": {
"id": 20,
"code": "WELCOME10",
"discount_type": "percentage",
"discount_value": 10,
"min_order_amount": 3000,
"max_uses": 200,
"used_count": 7,
"is_active": true,
"starts_at": null,
"expires_at": "2026-12-31 23:59:00",
"created_at": "2026-10-06 14:20:11",
"updated_at": "2026-10-20 09:05:42"
}
}

DELETE /v1/promo-codes/{id}​

يحذف الرمز، فلا يستطيع الزبائن استعماله بعدها. الطلبات التي استعملته من قبل تحتفظ بخصمها. لإيقاف رمز مؤقتاً دون أن تفقد عدد استعمالاته، أرسل is_active: false عبر PATCH بدل الحذف.

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

الطلب​

curl -X DELETE 'https://api.dzbuild.app/v1/promo-codes/20' \
-H "Authorization: Bearer $DZ_KEY" \
-H "Idempotency-Key: promo-20-delete"

الاستجابة 200​

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

خصم 100%​

رمز percentage بقيمة 100 يجعل المنتجات مجانية لكل زبون يملك الرمز. الإنشاء، أو التعديل الذي يرسل discount_type أو discount_value، لا يُكتب من النداء الأول إذا كانت النتيجة رمز percentage بنسبة 100%:

  1. يُرجع النداء 422 confirmation_required ولا يكتب شيئاً. يحمل الخطأ confirm_token (يُستعمل مرة واحدة، صالح 600 ثانية) وaction وwill_change، وهو ملخّص تعرضه على التاجر.
  2. بعد موافقة التاجر، أعد الجسم نفسه مع إضافة confirm_token وبـ Idempotency-Key جديد (المفتاح الأول مربوط بالجسم الذي لا يحمل رمز التأكيد). رمز التأكيد المنتهي، أو المستعمل من قبل، أو الذي لم يعد يطابق الطلب، يُرجع 422 confirmation_stale مع رمز تأكيد جديد.

بمفتاح مُنشأ من لوحة التحكم يمكنك تجاوز هذه الجولة بإرسال confirm_full_discount: true في النداء الأول. أما DZBuild Copilot فلا يستطيع استعمال هذا الحقل ويمرّ دائماً عبر رمز التأكيد.

{
"error": {
"code": "confirmation_required",
"message": "A 100% discount makes every order free ...",
"confirm_token": "cft_xxxxxxxxxxxxxxxx",
"confirm_token_expires_in": 600,
"action": "promo.full_discount:new",
"will_change": {
"action": "Create a promo code that makes orders free",
"code": "FREEGIFT",
"discount": "100% off the whole order subtotal",
"reversible": true,
"note": "Any customer with this code pays 0 for the goods. Orders already placed with it cannot be reversed by deleting the code."
}
}
}

في التعديل، ينتهي action برقم الرمز بدل new، ويصبح نص will_change.action هو Change promo code #20 to make orders free.

curl -X POST 'https://api.dzbuild.app/v1/promo-codes' \
-H "Authorization: Bearer $DZ_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: promo-freegift-approved" \
-d '{"code": "FREEGIFT", "discount_type": "percentage", "discount_value": 100, "max_uses": 1, "confirm_token": "cft_REPLACE_WITH_TOKEN"}'

سجل التغييرات والتراجع​

كل إنشاء وتعديل وحذف يتم عبر الواجهة البرمجية يُسجَّل. الرموز التي تُعدَّل من صفحة لوحة التحكم لا تُسجَّل، فلا يمكن التراجع عنها عبر الواجهة البرمجية.

  • يعرض GET /v1/changes?entity=promo_code تغييرات الرموز الترويجية، الأحدث أولاً، بصلاحية store:read. كل عنصر يحمل id التغيير، ورقم الرمز في entity_id، وaction (create أو update أو delete) وsummary.
  • يحتاج POST /v1/changes/{id}/undo إلى promos:write وإلى Idempotency-Key وإلى أن تكون الإضافة مفعّلة، مثل أي كتابة.
  • التراجع عن تعديل يُرجع القيم السابقة دون أي تأكيد، حتى لو كانت خصماً بـ 100% أو تاريخ انتهاء قد مضى. وإذا حُذف الرمز بعد ذلك، يُرجع التراجع 422 restore_target_missing.
  • التراجع عن حذف يُعيد إنشاء الرمز مع عدد استعمالاته، ويحتفظ برقمه إذا كان هذا الرقم ما يزال شاغراً.
  • التراجع عن إنشاء يُرجع 422 nothing_to_restore: احذف الرمز بدلاً من ذلك.
  • لا يستطيع رمز التطبيق المثبّت قراءة التغييرات ولا التراجع عنها: كلاهما يُرجع 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": "promo_code",
"undo_change_id": 510
}
}

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

الأخطاء​

HTTPالرمزالسبب
400bad_requestالرقم في المسار ليس أرقاماً فقط، أو الجسم ليس JSON صالحاً، أو Idempotency-Key غائب أو غير صالح.
403forbiddenMissing scope: promos:read أو Missing scope: promos:write، أو API access requires an active Enterprise plan لمفتاح تاجر متجره ليس على خطة Enterprise سارية.
404not_foundلا يوجد رمز ترويجي بهذا الرقم في المتجر.
409addon_inactiveإضافة الرموز الترويجية غير مفعّلة في المتجر. في الكتابة فقط.
409code_existsرمز آخر في المتجر يحمل هذا النص.
422invalid_codecode أقصر من حرفين أو أطول من 30 حرفاً، أو يحتوي حرفاً غير A-Z و0-9 و- و_.
422invalid_discount_typediscount_type غائب، أو ليس percentage ولا fixed.
422invalid_discount_valuediscount_value غائب، أو ليس رقماً، أو يساوي 0 أو أقل، أو أكبر من 100 مع percentage.
422invalid_min_order_amountmin_order_amount ليس رقماً.
422invalid_max_usesmax_uses ليس رقماً، أو أقل من 1.
422invalid_starts_at، invalid_expires_atتعذّرت قراءة التاريخ.
422expires_at_in_pastقيمة expires_at التي أرسلتها ليست في المستقبل.
422invalid_date_windowexpires_at ليس بعد starts_at.
422confirmation_required، confirmation_staleخصم 100% ينتظر موافقة التاجر. انظر القسم أعلاه.
422idempotency_key_reuseاستُعمل Idempotency-Key نفسه مع جسم أو مسار مختلف.
500server_errorفشلت الكتابة. أعد المحاولة بـ Idempotency-Key نفسه.

استجابة 4xx تُحفظ مع Idempotency-Key الخاص بها 24 ساعة، وتُعاد لكل إعادة محاولة بالجسم نفسه. بعد تفعيل الإضافة أو تصحيح الجسم، أرسل النداء بمفتاح جديد. الأخطاء المشتركة بين كل النقاط، مثل 401 و402 و429، موجودة في الأخطاء، وقواعد إعادة المحاولة في Idempotency.

حدود معروفة​

  • قد تتجاوز الاستعمالات max_uses. عندما يُتمّ عدة زبائن طلباتهم بالرمز نفسه في اللحظة نفسها، قد يتجاوز used_count قيمة max_uses.
  • لا يوجد webhook. إنشاء رمز ترويجي أو تعديله أو حذفه لا يُرسل أي حدث webhook.
هذه الصفحة لأدوات الذكاء الاصطناعيعرض بصيغة Markdownفتح في ChatGPTفتح في Claude