Aller au contenu principal

Messages WhatsApp

Ces quatre endpoints ouvrent l'addon WhatsApp Sender à l'API : les modèles de messages de commande validés pour la plateforme, le solde WhatsApp de la boutique, l'historique des messages envoyés aux acheteurs, et un appel qui envoie un modèle à l'acheteur d'une commande. Un message envoyé par l'API suit les mêmes règles que les messages automatiques. Il coûte un message du solde, un message refusé par WhatsApp est recrédité, et un message jamais envoyé n'est jamais débité.

Le texte libre n'est pas possible. Chaque message est l'un des six modèles listés plus bas, rempli à partir de la commande (prénom de l'acheteur, numéro de commande, nom de la boutique, transporteur, point de retrait, montant), en arabe ou en français, avec le bouton « Suivre ma commande ».

Avant de commencer​

  • L'addon WhatsApp Sender doit être activé sur la boutique (page Extensions du dashboard). Les trois endpoints de lecture fonctionnent sans lui ; l'envoi répond 403 addon_not_active.
  • Le solde se recharge depuis la page de l'addon dans le dashboard (/dashboard/whatsapp-sender, bouton Recharger). L'API lit le solde mais ne peut pas le recharger.
  • Les messages ne partent que vers des numéros mobiles algériens (05, 06 ou 07). Tout autre numéro est ignoré avec invalid_number, sans débit.
  • La clé a besoin des portées WhatsApp. Les nouvelles clés plateforme ont les deux par défaut. Les portées sont figées à la création de la clé : une clé créée avant la v1.6 ne les a pas. Créez une nouvelle clé pour utiliser ces endpoints.
PortéeDescription
whatsapp:readConsulter les modèles de messages WhatsApp, votre solde et l'historique des messages envoyés
whatsapp:sendEnvoyer des messages WhatsApp à vos acheteurs au sujet de leurs commandes (chaque message est débité de votre solde WhatsApp)

GET /v1/whatsapp/templates​

Le catalogue des modèles : le texte arabe et français, des valeurs d'exemple pour chaque champ, et le statut de validation de chaque langue.

Auth : clé plateforme avec whatsapp:read.

Le statut est le dernier lu par la plateforme auprès de WhatsApp. Il est rafraîchi au plus une fois toutes les 10 minutes tant que des messages partent, et UNKNOWN veut dire qu'il n'a pas encore été lu. Cet appel ne contacte jamais WhatsApp lui-même. Seuls les modèles APPROVED sont envoyés : un envoi dans une langue dont le modèle n'est pas validé est ignoré avec template_not_approved, sans débit.

Requête​

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

Réponse 200​

Un seul des six éléments est montré.

{
"data": {
"items": [
{
"key": "shipped_home",
"name": "dz_order_shipped_home",
"toggle": "shipped",
"languages": {
"ar": {
"body": "أهلاً {{1}}، طلبك رقم {{2}} من {{3}} في الطريق مع {{4}}.\nسيصلك خلال {{5}}. سيتصل بك عامل التوصيل قبل الوصول، يرجى إبقاء هاتفك متاحاً وتجهيز المبلغ: {{6}} دج.\nاضغط على الزر لتتبع طلبك.",
"example": ["أحمد", "1024", "متجري", "Yalidine", "يوم إلى 3 أيام", "3500"],
"status": "APPROVED"
},
"fr": {
"body": "Bonjour {{1}}, votre commande n° {{2}} chez {{3}} est en route avec {{4}}.\nLivraison prévue sous {{5}}. Le livreur vous appellera avant d'arriver : restez joignable et préparez le montant de {{6}} DA.\nAppuyez sur le bouton pour suivre votre commande.",
"example": ["Ahmed", "1024", "Ma Boutique", "Yalidine", "1 à 3 jours", "3500"],
"status": "APPROVED"
}
}
}
]
}
}

Les six modèles​

keytoggleCe que lit l'acheteur
receivedreceivedSa commande est arrivée et la boutique va l'appeler pour la confirmer.
confirmedconfirmedSa commande est confirmée et en préparation, avec le montant à payer.
shipped_homeshippedSa commande est en route vers son adresse, avec le délai de livraison réglé dans l'addon.
shipped_deskshippedSa commande est en route vers un point de retrait, que le message nomme.
delivery_faileddelivery_failedLe livreur n'a pas pu le joindre aujourd'hui et réessaiera demain.
desk_readydesk_readyLe colis l'attend au point de retrait.

toggle est l'interrupteur de message automatique, dans les réglages de l'addon, dont dépend le modèle. Il ne contrôle que les messages automatiques ; un envoi par l'API l'ignore.

GET /v1/whatsapp/balance​

Le solde, l'état de l'addon et les compteurs de messages affichés sur la page de l'addon.

Auth : clé plateforme avec whatsapp:read.

Requête​

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

Réponse 200​

{
"data": {
"balance": 412,
"low_balance": false,
"addon_active": true,
"stats": {
"sent": 12,
"delivered": 230,
"read": 158,
"failed": 4,
"used_month": 96
}
}
}
ChampSignification
balanceMessages restants dans le solde. Une boutique qui n'a jamais rechargé a 0.
low_balancetrue sous 50 messages.
addon_activeL'addon WhatsApp Sender est-il activé sur la boutique.
stats.sent, stats.delivered, stats.read, stats.failedMessages des 30 derniers jours, comptés selon leur statut actuel. Un message lu par l'acheteur compte seulement dans read.
stats.used_monthMessages débités du solde depuis le 1er du mois, y compris ceux recrédités ensuite.

GET /v1/whatsapp/messages​

Les messages de la boutique, du plus récent au plus ancien : les messages automatiques (source vaut auto) et ceux envoyés par l'API (source vaut api). Le numéro de téléphone de l'acheteur n'est jamais renvoyé.

Auth : clé plateforme avec whatsapp:read.

Paramètres de requête​

ParamTypeDéfautNotes
order_idchiffresaucunSeulement les messages de cette commande. Toute valeur qui n'est pas composée de chiffres renvoie 400 bad_request.
limitint50De 1 à 200.
cursorstringaucunLe next_cursor de la page précédente. Voir Pagination.

Requête​

curl 'https://api.dzbuild.app/v1/whatsapp/messages?order_id=6894' \
-H "Authorization: Bearer $DZ_KEY"

Réponse 200​

{
"data": {
"items": [
{
"id": 4181,
"order_id": 6894,
"event": "shipped_home",
"source": "api",
"status": "read",
"language": "fr",
"template_name": "dz_order_shipped_home",
"error_title": null,
"refunded": false,
"created_at": "2026-09-26 10:14:03"
},
{
"id": 4180,
"order_id": 6894,
"event": "confirmed",
"source": "auto",
"status": "delivered",
"language": "ar",
"template_name": "dz_order_confirmed",
"error_title": null,
"refunded": false,
"created_at": "2026-09-25 18:02:41"
}
],
"next_cursor": null,
"has_more": false
}
}
ChampSignification
eventPour un message automatique, l'événement de commande qui l'a déclenché (received, confirmed, shipped, delivery_failed, desk_ready). Pour un message API, la clé du modèle envoyé.
sourceauto ou api.
statusVoir le tableau ci-dessous.
languagear ou fr.
template_nameLe nom du modèle enregistré chez WhatsApp.
error_titlePourquoi un message a été ignoré ou a échoué, sinon null.
refundedtrue une fois le message d'un envoi échoué recrédité.
created_atYYYY-MM-DD HH:MM:SS, heure du serveur.
statusSignification
queuedPayé, en attente. La plateforme l'envoie en une minute environ.
sendingEnvoi en cours vers WhatsApp.
sentEnvoyé : accepté par WhatsApp.
deliveredLivré sur le téléphone de l'acheteur.
readLu par l'acheteur.
failedÉchoué : WhatsApp n'a pas pu le délivrer. Le message est recrédité en quelques minutes et refunded passe à true.
skippedNon envoyé et non débité. error_title donne la raison.

Un message ignoré porte l'une de ces raisons dans error_title :

error_titleSignification
invalid_numberNuméro invalide : ce n'est pas un mobile algérien.
suppressedNuméro sans WhatsApp.
template_not_approvedModèle en attente de validation dans cette langue.
empty_paramDonnées manquantes : il manque à la commande une valeur dont le modèle a besoin.

POST /v1/orders/{id}/whatsapp​

Met en file un modèle pour l'acheteur d'une commande et débite un message du solde. La plateforme l'envoie en une minute environ.

Auth : clé plateforme avec whatsapp:send. Nécessite Idempotency-Key.

Corps​

ChampTypeRequisNotes
templatestringouiUne key de GET /v1/whatsapp/templates, ou shipped, qui choisit shipped_home, shipped_desk ou desk_ready selon le type de livraison de la commande (domicile, bureau ou retrait).
languagear ou frnonPar défaut, la langue des messages choisie dans les réglages de l'addon, ou la langue de la boutique si aucune n'a été choisie.

Ce que fait l'appel​

  1. Il vérifie que l'addon est activé et que la commande appartient à la boutique. Une commande d'une autre boutique répond 404, comme une commande qui n'existe pas.
  2. Il ignore les interrupteurs de messages automatiques de l'addon : vous pouvez envoyer un modèle que le marchand a désactivé pour les messages automatiques.
  3. Chaque modèle ne peut être envoyé qu'une fois par commande via l'API. Un second appel répond 409 already_sent avec l'id et le status du message précédent. Seule exception : une tentative précédente ignorée, par exemple parce que le numéro était invalide et a été corrigé depuis sur la commande. L'appel réessaie alors.
  4. Il vérifie le numéro, la validation du modèle et les données de la commande. Un problème répond 422 avec la raison comme code d'erreur, enregistre un message ignoré et ne débite rien.
  5. Il débite un message du solde. Un solde vide répond 402 no_credit et n'enregistre rien.
  6. Il répond 202. Suivez le message avec GET /v1/whatsapp/messages?order_id= suivi de l'id de la commande. Un message refusé par WhatsApp passe à failed et est recrédité.

Les messages API sont comptés à part des messages automatiques. Envoyer shipped_home par l'API n'empêche pas le message automatique « Commande en route » pour la même commande, et le message automatique ne bloque pas l'envoi par l'API. Chacun est payé.

Requête​

curl -X POST 'https://api.dzbuild.app/v1/orders/6894/whatsapp' \
-H "Authorization: Bearer $DZ_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: wa-6894-shipped-1" \
-d '{"template": "shipped", "language": "fr"}'

Réponse 202​

template est la clé mise en file, avec shipped déjà résolu.

{
"data": {
"message_id": 4181,
"status": "queued",
"template": "shipped_home",
"language": "fr"
}
}

Erreurs​

HTTPCodeCause
400bad_requestL'id de commande n'est pas composé de chiffres, le corps n'est pas un JSON valide, ou Idempotency-Key manque ou est mal formé.
402no_creditLe solde WhatsApp est vide. Rien n'a été enregistré.
403forbidden« Missing scope: whatsapp:send »
403addon_not_activeL'addon WhatsApp Sender n'est pas activé sur la boutique.
404not_foundAucune commande avec cet id dans la boutique.
409already_sentCe modèle a déjà été envoyé pour cette commande via l'API.
422unknown_templatetemplate n'est ni shipped ni une clé du catalogue.
422invalid_languagelanguage n'est ni ar ni fr.
422invalid_numberLe téléphone de la commande n'est pas un mobile algérien.
422suppressedLe téléphone de la commande n'a pas de compte WhatsApp.
422template_not_approvedLe modèle n'est pas encore validé dans cette langue.
422empty_paramIl manque à la commande une valeur dont le modèle a besoin.
422idempotency_key_reuseLa même Idempotency-Key a servi avec un autre corps.
500send_failedLe message n'a pas pu être mis en file. Réessayez avec la même clé.

Voici un 409 already_sent.

{
"error": {
"code": "already_sent",
"message": "This template was already sent for this order",
"id": 4181,
"status": "delivered"
}
}

Réessais et Idempotency-Key​

La première réponse à une clé est conservée 24 heures. Un réessai avec la même clé et le même corps renvoie cette réponse avec Idempotency-Replay: 1, y compris un 402, un 403 ou un 422. Après avoir rechargé le solde, activé l'addon ou corrigé la commande, réessayez avec une nouvelle Idempotency-Key : l'ancienne clé continue de renvoyer l'ancienne erreur. Un 202 rejoué veut dire qu'aucun second message n'a été mis en file.

La même clé avec un autre corps répond 422 idempotency_key_reuse. Une réponse 5xx ou 429 n'est jamais conservée : réessayez-la avec la même clé. Si le message avait en fait été mis en file avant l'erreur, le réessai répond 409 already_sent avec son id, et rien n'est débité deux fois. Voir Idempotence.

Limites connues​

  • Texte du délai de livraison. shipped_home porte le délai de livraison tel que le marchand l'a saisi dans les réglages de l'addon. Un message en français d'une boutique dont le délai est écrit en arabe affiche ce texte arabe au milieu du message français. Un délai écrit en chiffres, comme 24-72h, se lit de la même façon dans les deux langues.
  • Envoi lent après une vérification de validation. Quand le statut de validation enregistré d'un modèle a plus de 10 minutes, l'envoi le relit auprès de WhatsApp avant de mettre le message en file. Cela arrive au plus une fois par modèle et par langue toutes les 10 minutes et peut retenir le POST jusqu'à 15 secondes : donnez à votre client HTTP un délai d'attente d'au moins 20 secondes.