14 KiB
WhatsApp Business Cloud API Setup Guide
Complete guide to setting up WhatsApp Business Cloud API for sending free template messages to suppliers.
Table of Contents
- Overview
- Prerequisites
- Step 1: Create Meta Business Account
- Step 2: Register WhatsApp Business
- Step 3: Get API Credentials
- Step 4: Create Message Templates
- Step 5: Configure Webhooks
- Step 6: Configure Environment Variables
- Step 7: Run Database Migration
- Step 8: Test Integration
- Pricing & Free Tier
- Troubleshooting
Overview
This integration uses WhatsApp Business Cloud API (Meta/Facebook) to send template-based notifications to suppliers about purchase orders.
Key Features
✅ 1,000 free conversations per month (business-initiated) ✅ Template-based messages with dynamic content ✅ Delivery tracking and read receipts ✅ Webhook-based status updates ✅ No Twilio fees (direct Meta integration)
Architecture
Purchase Order Approved
↓
RabbitMQ Event
↓
PO Event Consumer
↓
WhatsApp Business Service
↓
Meta WhatsApp Cloud API
↓
Supplier's WhatsApp
Prerequisites
Before starting, you need:
- Meta Business Account (free to create)
- Phone number for WhatsApp Business (can't be personal WhatsApp)
- Verified business on Meta Business Suite
- Public webhook URL (for receiving delivery status)
- Developer access to Meta Business Manager
Step 1: Create Meta Business Account
1.1 Go to Meta Business Suite
Visit: https://business.facebook.com/
Click "Create Account"
1.2 Fill Business Information
- Business Name: Your company name
- Your Name: Your full name
- Business Email: Your company email
Click "Next" and complete verification.
1.3 Verify Your Business (Optional but Recommended)
Go to: Business Settings → Business Info → Start Verification
Upload:
- Business registration documents
- Tax documents
- Proof of address
⏱️ Verification takes 1-3 business days but is not required to start using WhatsApp API.
Step 2: Register WhatsApp Business
2.1 Access WhatsApp Product
- Go to Meta Business Suite: https://business.facebook.com/
- Navigate to Business Settings
- Click Accounts → WhatsApp Accounts
- Click Add → Create a WhatsApp Business Account
2.2 Set Up Phone Number
You need a phone number that:
- ✅ Can receive SMS/voice calls
- ✅ Is NOT currently on WhatsApp (personal or business)
- ✅ Has international format support
- ❌ Cannot be VoIP (like Google Voice)
Recommended providers: Twilio, regular mobile number
Steps:
- Click Add Phone Number
- Select your country code (e.g., +34 for Spain)
- Enter your phone number
- Choose verification method (SMS or Voice Call)
- Enter the 6-digit code received
✅ Phone number verified!
2.3 Set Display Name
This is what recipients see as the sender name.
Example: Bakery Management or Your Bakery Name
Step 3: Get API Credentials
3.1 Create a WhatsApp App
- Go to Meta for Developers: https://developers.facebook.com/
- Click My Apps → Create App
- Select Business as app type
- Fill in app details:
- App Name:
Bakery Notification System - Contact Email: Your email
- Business Account: Select your business
- App Name:
3.2 Add WhatsApp Product
- In your app dashboard, click Add Product
- Find WhatsApp and click Set Up
- Select your Business Account
3.3 Get Credentials
Navigate to WhatsApp → API Setup
You'll find:
Phone Number ID
Copy this value - looks like: 123456789012345
WhatsApp Business Account ID
Copy this value - looks like: 987654321098765
Temporary Access Token
⚠️ Important: This token expires in 24 hours. For production, you need a permanent token.
3.4 Generate Permanent Access Token
Option A: System User Token (Recommended for Production)
- Go to Business Settings → Users → System Users
- Click Add and create a system user
- Click Generate New Token
- Select your app
- Select permissions:
whatsapp_business_messagingwhatsapp_business_management
- Click Generate Token
- ⚠️ Copy and save this token immediately - you won't see it again!
Option B: Page Access Token
- Go to App Dashboard → WhatsApp → API Setup
- Click Generate Token (24-hour token)
- For permanent, go to Access Token Tool: https://developers.facebook.com/tools/accesstoken/
Step 4: Create Message Templates
WhatsApp requires all business-initiated messages to use pre-approved templates.
4.1 Access Template Manager
- Go to Meta Business Suite: https://business.facebook.com/
- Navigate to WhatsApp Manager
- Click Message Templates
- Click Create Template
4.2 Create PO Notification Template
Template Details:
| Field | Value |
|---|---|
| Template Name | po_notification |
| Category | UTILITY |
| Language | Spanish (es) |
Message Content:
Hola {{1}}, has recibido una nueva orden de compra {{2}} por un total de {{3}}.
Parameters:
- {{1}} = Supplier name (e.g., "Proveedor ABC")
- {{2}} = PO number (e.g., "PO-2024-001")
- {{3}} = Total amount (e.g., "€1,250.00")
Example Preview:
Hola Proveedor ABC, has recibido una nueva orden de compra PO-2024-001 por un total de €1,250.00.
4.3 Submit for Approval
- Click Submit
- Wait for approval (usually 15 minutes to 24 hours)
- Check status in Message Templates
✅ Status will change to APPROVED when ready.
4.4 (Optional) Add Header/Footer
With Header:
[HEADER]
🛒 Nueva Orden de Compra
[BODY]
Hola {{1}}, has recibido una nueva orden de compra {{2}} por un total de {{3}}.
[FOOTER]
Sistema de Gestión de Panadería
4.5 (Optional) Add Buttons
You can add quick reply buttons:
- ✅ "Confirmar Recepción"
- 📞 "Llamar a Panadería"
Step 5: Configure Webhooks
Webhooks receive delivery status updates (sent, delivered, read, failed).
5.1 Set Up Public Webhook URL
Your webhook must be publicly accessible via HTTPS.
Production URL Example:
https://your-domain.com/api/v1/whatsapp/webhook
For Development (use ngrok):
ngrok http 8000
Then use: https://abc123.ngrok.io/api/v1/whatsapp/webhook
5.2 Generate Verify Token
Create a random secret token for webhook verification:
# Generate random token
openssl rand -hex 32
Save this as WHATSAPP_WEBHOOK_VERIFY_TOKEN in your environment.
5.3 Configure Webhook in Meta
- Go to App Dashboard → WhatsApp → Configuration
- Click Edit next to Webhook
- Fill in:
- Callback URL:
https://your-domain.com/api/v1/whatsapp/webhook - Verify Token: Your generated token (from 5.2)
- Callback URL:
- Click Verify and Save
✅ If successful, you'll see "Webhook verified"
5.4 Subscribe to Webhook Fields
Click Manage and subscribe to:
- ✅
messages(required for status updates) - ✅
message_template_status_update(optional)
Step 6: Configure Environment Variables
Update your notification service environment configuration.
6.1 Create/Update .env File
# services/notification/.env
# WhatsApp Business Cloud API Configuration
WHATSAPP_ACCESS_TOKEN=EAAxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
WHATSAPP_PHONE_NUMBER_ID=123456789012345
WHATSAPP_BUSINESS_ACCOUNT_ID=987654321098765
WHATSAPP_API_VERSION=v18.0
WHATSAPP_WEBHOOK_VERIFY_TOKEN=your-random-token-from-step-5.2
# Enable WhatsApp notifications
ENABLE_WHATSAPP_NOTIFICATIONS=true
6.2 Kubernetes Secret (Production)
kubectl create secret generic notification-whatsapp-secrets \
--from-literal=WHATSAPP_ACCESS_TOKEN='EAAxxxxxxxxxxxxx' \
--from-literal=WHATSAPP_PHONE_NUMBER_ID='123456789012345' \
--from-literal=WHATSAPP_BUSINESS_ACCOUNT_ID='987654321098765' \
--from-literal=WHATSAPP_WEBHOOK_VERIFY_TOKEN='your-token' \
-n bakery-ia
6.3 Update Deployment
# kubernetes/notification-deployment.yaml
env:
- name: WHATSAPP_ACCESS_TOKEN
valueFrom:
secretKeyRef:
name: notification-whatsapp-secrets
key: WHATSAPP_ACCESS_TOKEN
- name: WHATSAPP_PHONE_NUMBER_ID
valueFrom:
secretKeyRef:
name: notification-whatsapp-secrets
key: WHATSAPP_PHONE_NUMBER_ID
- name: WHATSAPP_BUSINESS_ACCOUNT_ID
valueFrom:
secretKeyRef:
name: notification-whatsapp-secrets
key: WHATSAPP_BUSINESS_ACCOUNT_ID
- name: WHATSAPP_WEBHOOK_VERIFY_TOKEN
valueFrom:
secretKeyRef:
name: notification-whatsapp-secrets
key: WHATSAPP_WEBHOOK_VERIFY_TOKEN
- name: ENABLE_WHATSAPP_NOTIFICATIONS
value: "true"
Step 7: Run Database Migration
Apply the WhatsApp database schema.
7.1 Run Alembic Migration
cd services/notification
# Check current migration
alembic current
# Run migration
alembic upgrade head
Expected output:
INFO [alembic.runtime.migration] Running upgrade 359991e24ea2 -> whatsapp001, add_whatsapp_business_tables
7.2 Verify Tables Created
-- Connect to database
psql -U notification_user -d notification_db
-- Check tables
\dt whatsapp*
-- Should see:
-- whatsapp_messages
-- whatsapp_templates
Step 8: Test Integration
8.1 Test Webhook Verification
curl -X GET "http://localhost:8000/api/v1/whatsapp/webhook?hub.mode=subscribe&hub.verify_token=YOUR_TOKEN&hub.challenge=test123"
Expected response: test123
8.2 Send Test Message (via API)
curl -X POST http://localhost:8000/api/v1/tenants/{tenant_id}/notifications/send-whatsapp \
-H "Content-Type: application/json" \
-d '{
"recipient_phone": "+34612345678",
"template_name": "po_notification",
"template_params": ["Test Supplier", "PO-TEST-001", "€100.00"]
}'
8.3 Trigger PO Notification
Create a test purchase order in the system and approve it. Check logs:
kubectl logs -f deployment/notification-service -n bakery-ia | grep "WhatsApp"
Expected log:
WhatsApp template message sent successfully
message_id=xxx
whatsapp_message_id=wamid.xxx
template=po_notification
8.4 Verify in Database
SELECT * FROM whatsapp_messages
ORDER BY created_at DESC
LIMIT 5;
Pricing & Free Tier
Free Tier
✅ 1,000 free conversations per month ✅ Applies to business-initiated conversations ✅ Resets monthly
Conversation-Based Pricing
WhatsApp charges per conversation (24-hour window), not per message.
| Conversation Type | Free Tier | After Free Tier |
|---|---|---|
| Business-Initiated | 1,000/month | ~€0.01-0.10 per conversation* |
| User-Initiated | 1,000/month | Free |
*Price varies by country
Cost Examples
Scenario 1: 50 PO notifications per month
- Cost: €0.00 (within free tier)
Scenario 2: 1,500 PO notifications per month
- First 1,000: €0.00
- Next 500: €5-50 (depending on country)
- Total: €5-50/month
Scenario 3: Multiple messages within 24 hours
- First message opens conversation: 1 conversation
- Follow-up within 24h: Same conversation (no additional charge)
Troubleshooting
Issue: "Webhook verification failed"
Cause: Verify token mismatch
Solution:
- Check
WHATSAPP_WEBHOOK_VERIFY_TOKENmatches Meta configuration - Ensure webhook URL is publicly accessible
- Check logs:
kubectl logs -f deployment/notification-service
Issue: "Template not found"
Cause: Template not approved or name mismatch
Solution:
- Check template status in Meta Business Suite
- Verify
template_namein code matches exactly - Ensure template language matches (e.g., "es")
Issue: "Access token expired"
Cause: Using temporary token
Solution:
- Generate permanent system user token (see Step 3.4)
- Update
WHATSAPP_ACCESS_TOKENenvironment variable - Restart service
Issue: "Message failed to send"
Cause: Multiple possible reasons
Debug Steps:
-
Check WhatsApp message status:
SELECT * FROM whatsapp_messages WHERE status = 'FAILED' ORDER BY created_at DESC; -
Check error_message field
-
Common errors:
- Invalid phone number format (must be E.164: +34612345678)
- Template not approved
- Recipient hasn't opted in
- Rate limit exceeded
Issue: "No webhook events received"
Cause: Webhook not configured or unreachable
Solution:
- Test webhook manually:
curl https://your-domain.com/api/v1/whatsapp/webhook/health - Check Meta webhook configuration
- Verify firewall/ingress allows incoming requests
- Check webhook logs in Meta (App Dashboard → WhatsApp → Webhooks)
Next Steps
After successful setup:
- ✅ Add more templates for different notification types
- ✅ Monitor usage in Meta Business Suite → Analytics
- ✅ Set up alerting for failed messages
- ✅ Add supplier phone numbers to supplier records
- ✅ Test with real suppliers (with their permission)
Additional Resources
- WhatsApp Business Cloud API Docs
- Message Templates Guide
- WhatsApp Business Pricing
- Webhook Setup Guide
Support
For issues with this integration:
- Check logs:
kubectl logs -f deployment/notification-service -n bakery-ia - Query database: Check
whatsapp_messagestable - Check Meta Status: https://developers.facebook.com/status
For Meta/WhatsApp API issues:
- Meta Business Help Center: https://www.facebook.com/business/help
- Developer Community: https://developers.facebook.com/community