WhatsApp Service Architecture
This document describes the separation of the WhatsApp domain from merchant_core_api into its own internal service.
Goals
- Separate WhatsApp delivery from merchant business logic.
- Reduce coupling between OTP/auth and the WhatsApp provider.
- Provide a clean audit log, retry, and delivery-status webhook.
- Make swapping WhatsApp providers easy without touching the entire main API.
Service Scope
whatsapp-service is only responsible for the delivery layer:
- render the message template
- send the message to the WhatsApp provider
- record provider request/response
- receive delivery/read/failed status webhooks
- retry failed sends
What stays in merchant_core_api:
- generate OTP
- validate OTP
- the rules for when a message must be sent
- merchant business orchestration
Integration Boundary
Core API to WhatsApp Service
Recommended initial communication:
- internal HTTP
- auth via internal API key
Minimum internal endpoints:
POST /internal/whatsapp/otpPOST /internal/whatsapp/messagesGET /internal/whatsapp/messages/{id}GET /health
Provider to WhatsApp Service
The provider webhook only enters the whatsapp-service, not merchant_core_api.
Example endpoint:
POST /webhooks/whatsapp/status
OTP Flow
- Mobile requests OTP from
merchant_core_api - Core API generates the OTP challenge
- Core API calls
POST /internal/whatsapp/otp - WhatsApp service persists the request to
notification.whatsapp_messages - WhatsApp service renders the OTP template
- WhatsApp service sends to the provider
- WhatsApp service stores the attempt result in
notification.whatsapp_send_attempts - The provider callback delivery status reaches
whatsapp-service - Status and delivery events can be re-read from
GET /internal/whatsapp/messages/{id}
Business Notification Flow
- A business event happens in the core API
- Core API calls
POST /internal/whatsapp/messages - WhatsApp service persists the request to
notification.whatsapp_messages - WhatsApp service sends to the provider
- The send status is recorded in
notification.whatsapp_send_attempts - If needed, the core API can query the message status via the internal endpoint
Database
Schemas in use:
notification.whatsapp_provider_configsnotification.whatsapp_templatesnotification.whatsapp_messagesnotification.whatsapp_send_attemptsnotification.whatsapp_delivery_events
Important notes:
- the
notificationschema does not replace the existing OTP runtime tables - OTP tables like challenge/cooldown/rate limit stay in the auth/runtime domain
- the
notificationschema only holds the WhatsApp delivery log, templates, provider config, and delivery events
See migration:
merchant_database/db_kesles_merchant/migrations/032_create_notification_whatsapp_tables.sql
Initial Technical Decisions
- the database stays shared PostgreSQL for now
- the schema is split into
notification - internal transport uses HTTP
- retry can still be synchronous/manual at first, queues come later
Evolution Phases
Phase 1
- separate service
- internal HTTP
- synchronous send
Phase 2
- queue for high-volume notifications
- retry worker
- rate limit per recipient/provider
Phase 3
- provider failover
- template approval workflow
- dedicated delivery monitoring dashboard