← Back to WhatsApp dashboard

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:///api/wa/webhook` |

| 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.