This app supports multi-tenant onboarding: each customer org connects its own WhatsApp Business Account (WABA) via Embedded Signup (Facebook Login for Business). Operator login stays Supabase; Meta is only used to link customer WhatsApp assets.
1. Meta Business and app
- Create a Meta Business for your company and complete Business Verification when Meta requires it (required before App Review / Advanced Access for customer-facing onboarding).
- In Meta for Developers, create a Business app (or use an existing one) and add the WhatsApp product.
- Under WhatsApp → Getting started, note the App ID and App Secret (same secret used for webhook signature verification:
WHATSAPP_APP_SECRET).
2. Tech Provider onboarding (dashboard)
- Open App Dashboard → Use cases → WhatsApp → Customize and follow Tech Provider onboarding (see Become a Tech Provider).
- You must complete business verification before App Review for Tech Provider permissions.
- Request Advanced Access for at least:
whatsapp_business_management— onboard customers and manage WABA assetswhatsapp_business_messaging— send/receive messages for connected customers See WhatsApp App Review and WhatsApp solution providers App Review.
- Prepare separate screen recordings per permission (Meta rejects one video for multiple permissions).
3. Embedded Signup + Login for Business (OAuth)
The in-app flow uses the Facebook JS SDK (FB.login with config_id and response_type: code on the onboarding page). The server exchanges that code in exchangeEmbeddedSignupCode and must use the same redirect_uri Meta used for the dialog.
3a. Facebook Login for Business configuration
- In the Meta app, open Facebook Login for Business (under Use cases or Products) and create a configuration for WhatsApp Embedded Signup (per Meta’s Tech Provider / Embedded Signup docs).
- Copy the Configuration ID into
NEXT_PUBLIC_META_EMBEDDED_SIGNUP_CONFIG_ID* (and use the same value only in public env; it is not secret).*
3b. Client OAuth settings (Facebook Login → Settings)
Match the Client OAuth screen to this app’s behavior:
| Setting | Recommended for this codebase |
|---|---|
| Client OAuth login | Yes |
| Web OAuth login | Yes |
| Enforce HTTPS | Yes (production) |
| Use Strict Mode for redirect URIs | Yes — then URIs must match exactly |
| Login with the JavaScript SDK | Yes — required because MetaEmbeddedSignupButton calls FB.login |
Under Valid OAuth Redirect URIs, add every URL where users can finish the Embedded Signup dialog. In this repo the connect button is available on onboarding and Settings → Integrations, so include at least:
https://<your-production-domain>/onboardinghttps://<your-production-domain>/app/settings/whatsapphttp://localhost:3000/onboarding(local dev; ngrok URL if you test through a tunnel, e.g.https://<subdomain>.ngrok-free.app/onboarding)
Strict mode means a bare origin like https://yourdomain.com will not match /onboarding.
Under Allowed Domains for the JavaScript SDK, add your site hostnames (e.g. yourdomain.com, localhost for dev).
3c. Server env: META_OAUTH_REDIRECT_URI
Set META_OAUTH_REDIRECT_URI to the same redirect URI Meta uses when exchanging the code — typically the full URL of the onboarding page (scheme + host + path, no trailing slash mismatch). It must appear in Valid OAuth Redirect URIs. If token exchange fails with a redirect mismatch, compare this value character-for-character to the URI in the Meta dashboard.
3d. Deauthorize / data deletion URLs
The Basic app settings may ask for a Deauthorize callback URL and Data Deletion Request URL. This repository does not ship dedicated routes for those yet; for App Review and compliance you will need HTTPS endpoints that accept Meta’s callbacks and document the behavior in your privacy policy.
4. Post–Embedded Signup (server-side)
After a customer completes Embedded Signup, your backend must:
- Exchange the returned code for a business integration system user access token (Onboarding customers as a Tech Provider).
- Call
**POST /{waba-id}/subscribed_apps*** so your app receives webhooks for that WABA.* - Register the business phone number for Cloud API where required (
*POST /{phone-number-id}/register).*
This codebase performs these steps in lib/whatsapp/meta-onboarding.ts when the client posts the completion code to /api/integrations/meta/whatsapp/complete.
5. Webhooks
- Configure the Callback URL in the Meta app to
https://<your-domain>/api/webhooks/whatsapp. - Use a single Verify token (
WHATSAPP_VERIFY_TOKEN) for the app. - Webhook verification uses
WHATSAPP_APP_SECRETforX-Hub-Signature-256.
For multi-tenant inbound, org routing uses the phone number id in each webhook (metadata.phone_number_id) matched against rows in whatsapp_sessions / channel_connections.
6. Environment variables (summary)
| Variable | Purpose |
|---|---|
NEXT_PUBLIC_META_APP_ID | Meta app ID (used by FB JS SDK + server token exchange) |
NEXT_PUBLIC_META_EMBEDDED_SIGNUP_CONFIG_ID | Login for Business configuration ID |
META_OAUTH_REDIRECT_URI | Must match Valid OAuth Redirect URIs (e.g. onboarding page URL) |
WHATSAPP_APP_SECRET | Webhook signature + server calls |
WHATSAPP_VERIFY_TOKEN | Webhook GET verification |
WHATSAPP_TOKEN_ENCRYPTION_KEY | 32-byte key (base64) for encrypting per-org tokens at rest (required) |
See .env.local.example.
7. Policies and UX
- Publish a Privacy Policy and Terms URL in the Meta app settings when required.
- In-product: show connection status, reconnect, and disconnect; do not expose access tokens in the UI or client bundles.