WhatsApp Cloud API setup (Cliqr)
Cliqr uses **one platform Meta app** and a **shared webhook** (`/api/wa/webhook`). Each venue connects its own WhatsApp Business Account (WABA) and phone number.
What venue owners do
1. Ensure Supabase v4 schema is applied (`supabase/apply-v4-in-dashboard.sql`).
2. Dashboard → **WhatsApp** → connect via **Connect with Meta** (if enabled) or paste:
- WABA ID
- Phone Number ID
- System User access token (`whatsapp_business_messaging` + `whatsapp_business_management`)
3. Wait for message templates to show **approved** (24–48h after first connect).
4. Enable automations and test:
- Send a message from your phone to the business WhatsApp number (inbound test).
- Use **Send test OTP** in the dashboard (outbound test).
Venue owners **cannot** receive inbound messages until the platform admin completes the steps below.
What the platform admin does (one time)
1. Create a Meta app
1. [Meta for Developers](https://developers.facebook.com/) → **Create app** → type **Business**.
2. Add product **WhatsApp**.
3. **Settings → Basic**: note **App ID** and **App Secret**.
2. Configure the webhook (required for inbound messages)
**WhatsApp → Configuration**:
| Field | Value |
|--------|--------|
| Callback URL | `https://
| Verify token | Same string as `WA_WEBHOOK_VERIFY_TOKEN` in server `.env` |
| Webhook fields | `messages`, `message_template_status_update` |
Click **Verify and save**. If verification fails, check HTTPS, `WA_WEBHOOK_VERIFY_TOKEN`, and that Cliqr is running.
3. Server environment variables
In `cliqr/.env.local` (production: pm2 env):
NEXT_PUBLIC_SITE_URL=https://cliqr.shop
Generate: openssl rand -hex 32
WA_ENC_KEY=<64-hex-chars>
Random string — must match Meta webhook "Verify token"
WA_WEBHOOK_VERIFY_TOKEN=
From Meta app → Settings → Basic → App Secret
META_APP_SECRET=
Optional — default v22.0
WA_GRAPH_VERSION=v22.0
Phase 2 — Embedded Signup (optional)
META_APP_ID=
META_EMBEDDED_SIGNUP_CONFIG_ID=
Restart after changes:
cd /var/www/cliqr.shop && npm run build && pm2 restart cliqr
4. System User token (for manual connect or testing)
1. [Meta Business Settings](https://business.facebook.com/settings) → **Users → System users**.
2. Create a system user → **Generate token** for your Cliqr app.
3. Permissions: `whatsapp_business_messaging`, `whatsapp_business_management`.
4. Assign the system user to the WABA with full control.
5. Copy **WABA ID** and **Phone number ID** from WhatsApp Manager → API setup.
5. Embedded Signup (optional, easier for venues)
1. Meta app → **WhatsApp → Embedded Signup** → create configuration.
2. Set **OAuth redirect URI** in Facebook Login settings:
`https://
/api/dashboard/whatsapp/oauth-callback` 3. Set `META_APP_ID` and `META_EMBEDDED_SIGNUP_CONFIG_ID` in server env.
4. Venues use **Connect with Meta** on the WhatsApp dashboard page.
6. Broadcast cron
crontab — every minute
* * * * * /var/www/cliqr.shop/scripts/cliqr-cron.sh broadcast
Requires `CLIQR_CRON_SECRET` in `.env`.
Redirect URIs — when you need them
| Flow | Redirect URI needed? |
|------|------------------------|
| Manual paste (WABA + phone + token) | **No** |
| Embedded Signup / OAuth code exchange | **Yes** — `/api/dashboard/whatsapp/oauth-callback` |
| Instagram/Facebook via Scheduloid | **No change** — see `docs/social-connect.md` |
Troubleshooting
| Symptom | Likely cause |
|---------|----------------|
| Dashboard shows Connected but no inbound messages | Webhook not verified in Meta Console, or wrong callback URL |
| Meta webhook test returns 403 on POST | Wrong `META_APP_SECRET` |
| Meta webhook verify fails on GET | `WA_WEBHOOK_VERIFY_TOKEN` mismatch |
| OTP / rewards never send | Templates not **approved**; check dashboard health panel |
| Connect works, send fails | `WA_ENC_KEY` missing or changed after connect — reconnect |
| Embedded Signup fails token exchange | `META_APP_ID` / `META_APP_SECRET` wrong; redirect URI not registered |
Verify inbound in Supabase
select direction, msg_type, status, sent_at
from wa_messages
order by sent_at desc
limit 10;
Health API (authenticated)
`GET /api/dashboard/whatsapp/health?venueId=
` — returns credentials, webhook subscription, template, and last message timestamps.