Les webhooks sont la colonne vertébrale de toute intégration API WhatsApp Business : sans eux, vous êtes aveugle. Vous pouvez envoyer des messages, mais vous ne recevez ni les réponses de vos contacts, ni les confirmations de livraison, ni les alertes de statut des templates. Implémenter correctement les webhooks WhatsApp, c'est construire la moitié de l'intégration qui rend le canal réellement utilisable en production.
L'architecture des webhooks Meta
Meta envoie tous les événements WhatsApp via HTTP POST vers un endpoint HTTPS que vous déclarez dans votre app Meta for Developers. Plusieurs types d'événements coexistent dans le même flux :
messages: messages texte, média, boutons, réactions et notifications de lecture envoyés par vos contacts.message_template_status_update: changement de statut d'un template (APPROVED, REJECTED, PAUSED).phone_number_quality_update: évolution du score qualité d'un numéro.account_update: modifications du compte WABA (restrictions, vérifications).message_status_updates(oustatusesdans le payload) : confirmations de livraison — sent, delivered, read, failed.
Ces événements arrivent dans un payload JSON encapsulé dans un objet entry > changes : c'est la structure commune de l'API Graph pour tous les webhooks Meta.
Étape 1 — Exposer et vérifier votre endpoint
Avant que Meta commence à envoyer des événements, il vérifie que votre endpoint existe et vous appartient via un "challenge de vérification".
Meta envoie une requête GET avec trois paramètres :
hub.mode=subscribehub.challenge= une valeur aléatoirehub.verify_token= le token de vérification que vous avez défini dans Meta for Developers
Votre endpoint doit :
- Vérifier que
hub.verify_tokencorrespond bien à votre token configuré. - Retourner exactement la valeur de
hub.challengeavec un statut200 OK.
En Node.js/Express :
app.get('/webhook', (req, res) => {
const mode = req.query['hub.mode'];
const token = req.query['hub.verify_token'];
const challenge = req.query['hub.challenge'];
if (mode === 'subscribe' && token === process.env.WEBHOOK_VERIFY_TOKEN) {
res.status(200).send(challenge);
} else {
res.sendStatus(403);
}
});
Étape 2 — Valider la signature HMAC sur chaque POST
Chaque requête POST de Meta contient un header X-Hub-Signature-256 avec un HMAC-SHA256 calculé sur le corps brut de la requête, signé avec l'App Secret de votre app.
Règle absolue : traitez le corps comme un buffer brut avant tout parsing JSON. Si vous parsez le JSON en premier, les parseurs peuvent reformater les espaces ou l'ordre des clés et invalider la signature.
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-hub-signature-256'];
const expectedSig = 'sha256=' + crypto
.createHmac('sha256', process.env.APP_SECRET)
.update(req.body)
.digest('hex');
if (!crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSig)
)) {
return res.sendStatus(403);
}
// Parsing sûr après validation
const payload = JSON.parse(req.body);
// Répondre 200 immédiatement, traiter de façon asynchrone
res.sendStatus(200);
processWebhookAsync(payload);
});
Note : utilisez crypto.timingSafeEqual et non une comparaison de chaînes classique, pour prévenir les attaques temporelles.
Étape 3 — Structurer le traitement asynchrone des événements
Meta exige une réponse 200 OK dans les 5 secondes. Si votre endpoint prend plus longtemps à répondre, Meta considère la livraison comme échouée et retente jusqu'à 7 fois avec un backoff croissant.
La conséquence pratique : votre endpoint doit répondre 200 immédiatement, et déléguer le traitement à un système asynchrone.
Architecture recommandée :
[Meta] → POST /webhook → [Votre endpoint]
↓ 200 OK (< 1 s)
↓ Publication dans la queue
[Queue (SQS / RabbitMQ / BullMQ)]
↓
[Worker de traitement]
↓
[Base de données / Logique métier]
Dans le worker, implémentez une logique d'idempotence basée sur le message_id retourné par Meta : si un événement est livré deux fois (ce qui peut arriver lors des retries Meta), votre traitement ne doit pas créer de doublons.
Cartographie des événements et leur traitement
| Événement | Champ discriminant | Action typique |
|---|---|---|
| Message texte entrant | messages[].type == "text" |
Créer une conversation, notifier le support |
| Message média entrant | messages[].type == "image/audio/video" |
Télécharger le média via l'API Media |
| Statut "delivered" | statuses[].status == "delivered" |
Mettre à jour le statut du message en BDD |
| Statut "read" | statuses[].status == "read" |
Marquer le message comme lu dans l'UI |
| Statut "failed" | statuses[].status == "failed" |
Logger l'erreur, déclencher un retry si approprié |
| Template APPROVED | entry.changes[].value.event == "APPROVED" |
Notifier le client, activer le template dans l'UI |
| Template REJECTED | entry.changes[].value.event == "REJECTED" |
Alerter le client avec le motif de refus |
Pour la gestion des erreurs de livraison et la stratégie de retry associée, consultez l'article Gérer les erreurs et les retries de l'API WhatsApp Business. Pour les aspects de sécurité et de conformité RGPD liés aux données transitant dans les webhooks, référez-vous à Sécuriser son intégration API WhatsApp.
FAQ
Meta peut-il envoyer le même événement webhook plusieurs fois ?
Oui. Meta garantit la livraison "at-least-once" mais pas "exactly-once". En cas de timeout ou d'erreur côté votre serveur, Meta retente la livraison. Votre système doit être idempotent : utiliser le message_id de Meta comme clé d'idempotence dans votre base de données prévient les doublons.
Peut-on configurer plusieurs endpoints webhook pour le même WABA ?
Non. Meta accepte un seul URL de callback par app. Pour un éditeur multi-tenant, vous exposez un seul endpoint qui reçoit tous les événements, puis vous routez vers le bon tenant en fonction du phone_number_id contenu dans le payload. Ce fan-out doit être implémenté dans votre couche applicative.
Comment tester les webhooks en local pendant le développement ?
Utilisez un outil de tunneling (ngrok, localtunnel, Cloudflare Tunnel) pour exposer votre port local via HTTPS. Configurez l'URL temporaire dans Meta for Developers, déclenchez des événements depuis le Business Manager ou depuis un numéro de test, et observez les payloads en local. Changez l'URL dans Meta for Developers quand vous déployez en staging puis en production.
Que se passe-t-il si mon endpoint est indisponible pendant plusieurs heures ?
Meta tente de livrer l'événement pendant une durée limitée (quelques dizaines de minutes à quelques heures selon le type d'événement). Au-delà de cette fenêtre, l'événement est abandonné. Pour les événements critiques (messages entrants), une indisponibilité prolongée peut entraîner des pertes. Assurez-vous que votre endpoint a un SLA de disponibilité adapté (99,9 % minimum en production) et des alertes sur les codes non-200 retournés.
Implémenter les webhooks WhatsApp correctement — validation de signature, réponse rapide, traitement asynchrone, idempotence — est ce qui sépare un proof of concept d'une intégration en production. Ces fondations robustes vous permettront de monter en charge sans réarchitecturer. Pour accéder à l'API WhatsApp Business et à une documentation d'intégration complète via un Meta Tech Provider certifié, explorez la solution Whakup pour les développeurs et les éditeurs.

Head of Growth chez Whakup, Stéphane pilote la stratégie d'acquisition et les partenariats en Afrique francophone. Expert en marketing digital et expansion marché.
Prêt à passer à l'action ?
Essayez Whakup gratuitement pendant 15 jours. Aucune carte bancaire requise.
Démarrer l'essai gratuitArticles similaires
Ajouter un numéro WhatsApp Business à sa plateforme : les 5 étapes
Ajouter un numéro WhatsApp Business à votre plateforme : découvrez les 5 étapes concrètes pour activer un numéro via l'API et commencer à envoyer des messages.
Connecter WhatsApp à un CRM : options, APIs et bonnes pratiques
Connecter WhatsApp à votre CRM via l'API Business : comparatif des options, architecture technique et bonnes pratiques pour agences et éditeurs SaaS.
Embedded signup WhatsApp : guide pas à pas pour les éditeurs
Embedded signup WhatsApp : implémentez le flux d'onboarding Meta dans votre plateforme pour connecter vos clients en moins de 5 minutes, sans friction.