واجهة WhatsApp
يستطيع تطبيقك إرسال رسائل WhatsApp إلى مشتري المتجر عبر أربع نقاط وصول. تستعمل الرسائل قوالب الطلبات التي اعتمدتها Meta لـ DZBuild، وتُدفع كل رسالة من رصيد WhatsApp الخاص بالمتجر، تمامًا مثل الرسائل التي ترسلها إضافة WhatsApp Sender تلقائيًا. لا يمكنك إرسال نص حر ولا قوالبك الخاصة.
المرجع الكامل للطلبات والردود موجود في وصف OpenAPI، ورابطه في صفحة مرجع الواجهة البرمجية. تشرح هذه الصفحة كيف تترابط هذه الأجزاء.
الصلاحيات
| الصلاحية | تسمح بـ |
|---|---|
whatsapp:read | GET /v1/whatsapp/templates، GET /v1/whatsapp/balance، GET /v1/whatsapp/messages |
whatsapp:send | POST /v1/orders/{id}/whatsapp |
لا تطلب في رابط التفويض إلا الصلاحيات التي تحتاجها. الطلب الذي تنقصه الصلاحية يُجاب بـ 403 مع رمز الخطأ forbidden والرسالة Missing scope: whatsapp:send (أو whatsapp:read). راجع الصلاحيات.
القوالب
تعرض GET /v1/whatsapp/templates القوالب الستة. تقرأ حالة الاعتماد التي تحفظها DZBuild ولا تتصل بـ Meta أبدًا.
| المفتاح | يُرسل عندما |
|---|---|
received | استُلم الطلب. |
confirmed | أُكّد الطلب. |
shipped_home | الطرد في الطريق إلى عنوان المشتري. |
shipped_desk | الطرد في الطريق إلى مكتب شركة التوصيل. |
delivery_failed | فشلت محاولة التوصيل. |
desk_ready | الطرد جاهز للاستلام. |
يحمل كل عنصر key وname (اسم القالب لدى Meta، مثل dz_order_confirmed) وtoggle (زر التفعيل المقابل لدى التاجر في الإضافة) وlanguages. يحتوي كل من languages.ar وlanguages.fr على body بمتغيّراته، وexample، وstatus. لا يُرسل القالب إلا بلغة حالتها APPROVED. وتعني UNKNOWN أن DZBuild لا تملك بعدُ أي حالة محفوظة.
الرصيد
تُرجع GET /v1/whatsapp/balance:
| الحقل | المعنى |
|---|---|
balance | عدد الرسائل المتبقية في رصيد المتجر. كل رسالة تكلّف رصيدًا واحدًا. |
low_balance | true عندما يبقى أقل من 50 رسالة. |
addon_active | هل فعّل التاجر إضافة WhatsApp Sender. |
stats | عدد الرسائل خلال آخر 30 يومًا حسب الحالة (sent، delivered، read، failed) وused_month، أي الرصيد المستهلك منذ أول يوم من الشهر الجاري. |
يشحن التاجر رصيده من لوحة تحكم DZBuild. لا يستطيع تطبيقك إضافة رصيد.
إرسال رسالة
تضع POST /v1/orders/{id}/whatsapp قالبًا واحدًا لطلب واحد من طلبات المتجر في طابور الإرسال. هي عملية كتابة، لذا تحتاج ترويسة Idempotency-Key (راجع حدود معدّل الطلبات).
POST /v1/orders/98765/whatsapp HTTP/1.1
Host: api.dzbuild.app
Authorization: Bearer dzpk_live_xxxxxxxx
Idempotency-Key: wa-98765-confirmed
Content-Type: application/json
{"template": "confirmed", "language": "fr"}
| حقل الجسم | إلزامي | المعنى |
|---|---|---|
template | نعم | أحد المفاتيح الستة، أو shipped. يختار shipped القالب المناسب حسب نوع توصيل الطلب: shipped_home للتوصيل إلى المنزل، shipped_desk للمكتب، desk_ready للاستلام. |
language | لا | ar أو fr. من دونه تُستعمل اللغة المضبوطة في إضافة WhatsApp Sender للمتجر، أو لغة المتجر إن لم تكن الإضافة مضبوطة. وإن لم تكن هذه اللغة البديلة ar ولا fr، تُرسَل الرسالة بالعربية. |
الإرسال اليدوي يتجاهل أزرار الإرسال التلقائي التي ضبطها التاجر في الإضافة. لكن يجب أن تكون الإضافة نفسها مفعّلة في المتجر.
يُجاب الطلب بـ 202 عندما تدخل الرسالة الطابور ويُخصم الرصيد:
{
"data": { "message_id": 4411, "status": "queued", "template": "confirmed", "language": "fr" },
"meta": { "request_id": "8f2c1a9d4b7e6035", "api_version": "v1" }
}
ترسل DZBuild الرسائل الموجودة في الطابور في الخلفية. تابع النتيجة عبر GET /v1/whatsapp/messages.
الردود ورموز الأخطاء
| الحالة | رمز الخطأ | المعنى |
|---|---|---|
202 | في الطابور، وخُصم رصيد واحد. | |
400 | bad_request | معرّف الطلب ليس رقمًا، أو الجسم ليس JSON صالحًا. |
402 | no_credit | رصيد WhatsApp للمتجر فارغ. لم يدخل شيء الطابور ولم يُخصم شيء. |
403 | addon_not_active | لم يفعّل التاجر إضافة WhatsApp Sender. |
403 | forbidden | الرمز لا يملك whatsapp:send. |
404 | not_found | لا يوجد طلب بهذا المعرّف في هذا المتجر. |
409 | already_sent | أُرسل هذا القالب من قبل لهذا الطلب. يحمل كائن الخطأ id وstatus الرسالة الموجودة. |
422 | unknown_template | قيمة template ليست من المفاتيح المقبولة. |
422 | invalid_language | قيمة language ليست ar ولا fr. |
422 | invalid_number | هاتف المشتري ليس رقم هاتف محمول جزائريًا صالحًا. |
422 | suppressed | رقم المشتري محظور من رسائل WhatsApp على المنصة. |
422 | template_not_approved | القالب غير معتمد بهذه اللغة. |
422 | empty_param | قيمة يحتاجها القالب فارغة في الطلب. |
500 | send_failed | تعذّر إدخال الرسالة إلى الطابور. أعد المحاولة لاحقًا. |
يمكن إرسال كل قالب مرة واحدة لكل طلبية عبر الواجهة البرمجية. أي استدعاء لاحق للقالب نفسه والطلبية نفسها يُجاب بـ 409، حتى لو فشلت الرسالة الأولى. أما ردود 422 من invalid_number إلى empty_param فمختلفة: لم يُخصم شيء، والاستدعاء الموالي لذلك القالب وتلك الطلبية يعيد المحاولة. أصلح السبب (رقم الهاتف في الطلبية مثلًا)، ثم أعد الاستدعاء بقيمة Idempotency-Key جديدة.
سجل الرسائل
تعرض GET /v1/whatsapp/messages رسائل المتجر من الأحدث إلى الأقدم. معاملات الاستعلام: order_id لتصفية طلب واحد، وlimit (50 افتراضيًا، 200 كحد أقصى)، وcursor (قيمة next_cursor من الصفحة السابقة). لا يُرجع رقم هاتف المشتري أبدًا.
| الحقل | المعنى |
|---|---|
id | معرّف الرسالة، وهو نفس message_id في رد الإرسال. |
order_id | الطلب. |
event | مفتاح القالب للرسائل المرسلة عبر الواجهة البرمجية، أو حدث الإضافة (received، confirmed، shipped، delivery_failed، desk_ready) للرسائل التلقائية. |
source | api للرسائل المرسلة عبر الواجهة البرمجية، وauto للرسائل التلقائية من الإضافة. |
status | queued أو sending أو sent أو delivered أو read أو failed أو skipped. |
language | ar أو fr. |
template_name | اسم القالب لدى Meta. |
error_title | سبب فشل الرسالة أو تخطيها، أو null. |
refunded | true عندما يُعاد الرصيد. |
billing | charged عندما يفوتر WhatsApp الرسالة، وfree عندما يعود رصيدها، وnull ما دام WhatsApp لم يبلّغ عن النتيجة. |
created_at | وقت دخول الرسالة إلى الطابور. |
الرسالة التي تفشل، أو لا تصل خلال 30 يوماً، أو تصل دون أن يفوترها WhatsApp، يُعاد رصيدها مرة واحدة: تصبح refunded هي true وbilling هي free. الرسالة التي يفوترها WhatsApp تستقر على charged.