# 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 1. [Overview](#overview) 2. [Prerequisites](#prerequisites) 3. [Step 1: Create Meta Business Account](#step-1-create-meta-business-account) 4. [Step 2: Register WhatsApp Business](#step-2-register-whatsapp-business) 5. [Step 3: Get API Credentials](#step-3-get-api-credentials) 6. [Step 4: Create Message Templates](#step-4-create-message-templates) 7. [Step 5: Configure Webhooks](#step-5-configure-webhooks) 8. [Step 6: Configure Environment Variables](#step-6-configure-environment-variables) 9. [Step 7: Run Database Migration](#step-7-run-database-migration) 10. [Step 8: Test Integration](#step-8-test-integration) 11. [Pricing & Free Tier](#pricing--free-tier) 12. [Troubleshooting](#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 1. Go to **Meta Business Suite**: https://business.facebook.com/ 2. Navigate to **Business Settings** 3. Click **Accounts** → **WhatsApp Accounts** 4. 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**: 1. Click **Add Phone Number** 2. Select your country code (e.g., +34 for Spain) 3. Enter your phone number 4. Choose verification method (SMS or Voice Call) 5. 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 1. Go to **Meta for Developers**: https://developers.facebook.com/ 2. Click **My Apps** → **Create App** 3. Select **Business** as app type 4. Fill in app details: - **App Name**: `Bakery Notification System` - **Contact Email**: Your email - **Business Account**: Select your business ### 3.2 Add WhatsApp Product 1. In your app dashboard, click **Add Product** 2. Find **WhatsApp** and click **Set Up** 3. 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)** 1. Go to **Business Settings** → **Users** → **System Users** 2. Click **Add** and create a system user 3. Click **Generate New Token** 4. Select your app 5. Select permissions: - `whatsapp_business_messaging` - `whatsapp_business_management` 6. Click **Generate Token** 7. **⚠️ Copy and save this token immediately** - you won't see it again! **Option B: Page Access Token** 1. Go to **App Dashboard** → **WhatsApp** → **API Setup** 2. Click **Generate Token** (24-hour token) 3. 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 1. Go to **Meta Business Suite**: https://business.facebook.com/ 2. Navigate to **WhatsApp Manager** 3. Click **Message Templates** 4. 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. **{{1}}** = Supplier name (e.g., "Proveedor ABC") 2. **{{2}}** = PO number (e.g., "PO-2024-001") 3. **{{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 1. Click **Submit** 2. Wait for approval (usually 15 minutes to 24 hours) 3. 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): ```bash 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: ```bash # Generate random token openssl rand -hex 32 ``` Save this as `WHATSAPP_WEBHOOK_VERIFY_TOKEN` in your environment. ### 5.3 Configure Webhook in Meta 1. Go to **App Dashboard** → **WhatsApp** → **Configuration** 2. Click **Edit** next to Webhook 3. Fill in: - **Callback URL**: `https://your-domain.com/api/v1/whatsapp/webhook` - **Verify Token**: Your generated token (from 5.2) 4. 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 ```bash # 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) ```bash 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 ```yaml # 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 ```bash 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 ```sql -- 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 ```bash 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) ```bash 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: ```bash 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 ```sql 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**: 1. Check `WHATSAPP_WEBHOOK_VERIFY_TOKEN` matches Meta configuration 2. Ensure webhook URL is publicly accessible 3. Check logs: `kubectl logs -f deployment/notification-service` ### Issue: "Template not found" **Cause**: Template not approved or name mismatch **Solution**: 1. Check template status in Meta Business Suite 2. Verify `template_name` in code matches exactly 3. Ensure template language matches (e.g., "es") ### Issue: "Access token expired" **Cause**: Using temporary token **Solution**: 1. Generate permanent system user token (see Step 3.4) 2. Update `WHATSAPP_ACCESS_TOKEN` environment variable 3. Restart service ### Issue: "Message failed to send" **Cause**: Multiple possible reasons **Debug Steps**: 1. Check WhatsApp message status: ```sql SELECT * FROM whatsapp_messages WHERE status = 'FAILED' ORDER BY created_at DESC; ``` 2. Check error_message field 3. 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**: 1. Test webhook manually: ```bash curl https://your-domain.com/api/v1/whatsapp/webhook/health ``` 2. Check Meta webhook configuration 3. Verify firewall/ingress allows incoming requests 4. Check webhook logs in Meta (App Dashboard → WhatsApp → Webhooks) --- ## Next Steps After successful setup: 1. ✅ **Add more templates** for different notification types 2. ✅ **Monitor usage** in Meta Business Suite → Analytics 3. ✅ **Set up alerting** for failed messages 4. ✅ **Add supplier phone numbers** to supplier records 5. ✅ **Test with real suppliers** (with their permission) --- ## Additional Resources - [WhatsApp Business Cloud API Docs](https://developers.facebook.com/docs/whatsapp/cloud-api) - [Message Templates Guide](https://developers.facebook.com/docs/whatsapp/message-templates) - [WhatsApp Business Pricing](https://developers.facebook.com/docs/whatsapp/pricing) - [Webhook Setup Guide](https://developers.facebook.com/docs/graph-api/webhooks) --- ## Support For issues with this integration: 1. Check logs: `kubectl logs -f deployment/notification-service -n bakery-ia` 2. Query database: Check `whatsapp_messages` table 3. 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