WhatsApp Webhook Meta Setup
Audience: external (Meta vendor configuration). Written in English — sibling docs in this folder (
architecture.md,deploy-runbook.md,extraction-plan.md,whatsapp-service-status.md) are in Bahasa Indonesia for internal team use. Indonesian translation tracked atmerchant_docs/docs/i18n/id/services/whatsapp/webhook-meta-setup.md.
This document describes the steps to set up the Meta Cloud API webhook for services/whatsapp_service.
Goal
The Meta webhook is used to deliver WhatsApp delivery status into:
notification.whatsapp_delivery_eventsnotification.whatsapp_messages.delivery_status
The service endpoints used:
GET /webhooks/whatsapp/statusPOST /webhooks/whatsapp/status
Prerequisites
whatsapp-serviceis running- a public domain for the service is available
- migration
032_create_notification_whatsapp_tables.sqlhas been run - the production env is correct:
WHATSAPP_PROVIDER=meta-cloud-apiWHATSAPP_BASE_URL=https://graph.facebook.com/v23.0WHATSAPP_API_KEY=...WHATSAPP_PHONE_NUMBER_ID=...WHATSAPP_VERIFY_TOKEN=...
Webhook URL
Use the public URL:
https://<public-domain>/webhooks/whatsapp/status
Example:
https://wa.kesles.com/webhooks/whatsapp/status
Verify Token
The verify token value in Meta must match:
WHATSAPP_VERIFY_TOKEN
When Meta calls:
GET /webhooks/whatsapp/status?hub.mode=subscribe&hub.verify_token=...&hub.challenge=...
the service will:
- check
hub.verify_token - echo back
hub.challenge
Setup Steps in Meta
- open the Meta App Dashboard
- select the WhatsApp product
- open the webhook / configuration menu
- fill in the callback URL:
https://<public-domain>/webhooks/whatsapp/status
- fill in the verify token:
<the WHATSAPP_VERIFY_TOKEN value>
- click verify and save
- subscribe the field:
messages
Payloads Processed
The service processes the nested status payload from Meta, in particular:
sentdeliveredreadfailed
Current mapping:
sent->sentdelivered->deliveredread->readfailed->failed
Verification After Setup
- trigger an OTP from the application or API
- check
notification.whatsapp_messages - confirm
provider_message_idis populated - wait for the Meta callback
- check
notification.whatsapp_delivery_events - confirm
delivery_statuson the message changes accordingly
See the document:
WhatsApp Verification Checklist
Troubleshooting
Verify fails
Check:
WHATSAPP_VERIFY_TOKENin the service env- the registered webhook URL
- the service is actually publicly reachable
- the reverse proxy does not block
GET /webhooks/whatsapp/status
Callback does not arrive
Check:
- the
messagesfield is subscribed - the public domain is correct
- TLS/HTTPS is valid
- service logs do not show
4xx/5xx
Delivery event is empty
Check:
provider_message_idonnotification.whatsapp_messages- the Meta status payload actually carries
statuses[].id - the
messagesevent is actually being sent by Meta