Connect your OrderPin bot to a real WhatsApp number using the Meta WhatsApp Cloud API, and run the Order Placing flow end‑to‑end from your own phone.
Three moving parts have to meet in the middle: (1) a public HTTPS tunnel so Meta can reach your local backend, (2) your Meta credentials entered into OrderPin's notification channel, and (3) Meta's webhook pointed back at your tunnel. Then you message the number and the bot replies.
Have these ready before you start. The first two are already true in your dev environment.
| Requirement | How to confirm | |
|---|---|---|
| ☑ | Backend running on port 8001 | cd orderpin-backend && ./venv/bin/python manage.py runserver 8001 |
| ☑ | Frontend running on port 5175 | cd orderpin-frontend && npm run dev → log in at /admin/login |
| ☑ | A published flow ("Order Placing") | Already live. (Re-seed any time: ./venv/bin/python manage.py seed_order_flow) |
| ☐ | A Facebook/Meta account | Personal account is fine for testing. |
| ☐ | Your phone with WhatsApp installed | You'll message the bot from it and it must be on Meta's test recipient list. |
| ☐ | Homebrew (to install the tunnel) | brew --version — or use ngrok instead (Step 1). |
OrderPin uses Meta's WhatsApp Cloud API (Meta‑hosted). The old On‑Premises API has been deprecated by Meta — you don't need it. Everything below uses the free test phone number Meta gives every app, so you can verify the full flow before bringing your own business number.
Meta's servers must reach your webhook, but your backend is on localhost:8001. A tunnel gives it a public HTTPS address.
# install once brew install cloudflared # start the tunnel (leave this running in its own terminal tab) cloudflared tunnel --url http://localhost:8001
It prints a line like:
+--------------------------------------------------------+
| https://random-words-1234.trycloudflare.com |
+--------------------------------------------------------+
That HTTPS address is your public base URL. Your webhook callback URL will be that + /api/v1/whatsapp/webhook/ — keep it handy for Step 6.
brew install ngrok # or download from ngrok.com ngrok config add-authtoken <your-token> # free account required now ngrok http 8001
Use the https://…ngrok-free.app URL it shows.
Your dev settings have DEBUG=True and ALLOWED_HOSTS=['*'], so Django will happily accept requests arriving via the tunnel host — no extra config needed. Keep the tunnel running for the whole session; the URL changes each time you restart it (so you'd re-paste it in Step 6).
This is all on Meta's side.
Exact button labels and menu positions shift between updates. If something is named slightly differently, the official, always‑current walkthrough is WhatsApp Cloud API · Get Started. The concepts below don't change.
From the app dashboard → WhatsApp → API Setup (sometimes "Getting Started").
| You need | Where to find it |
|---|---|
| Phone number ID | WhatsApp → API Setup, in the "From" section (a long numeric ID — not the phone number itself). |
| WhatsApp Business Account ID | Same API Setup page, usually just below — or under WhatsApp → Configuration. |
| Access token | API Setup page → "Temporary access token" (valid 24 hours — perfect for a test session). Click to copy. |
| App Secret | App dashboard → App Settings → Basic → App Secret → "Show". |
| Verify token | You invent this — any random string, e.g. orderpin-verify-7f3k9. You'll type the same value into OrderPin and Meta. |
Test numbers can only message numbers you explicitly allow. On the API Setup page, in the "To" field, click "Manage phone number list" → add your personal WhatsApp number (with country code) → confirm the code WhatsApp sends you. You can add up to 5.
The temporary token expires after 24h — if testing the next day, just copy a fresh one from the same page and re‑save it in OrderPin (Step 4). For longer‑lived setups you'd create a System User token (Business Settings → Users → System Users) with the whatsapp_business_messaging permission — see "Beyond testing" at the end.
OrderPin reads all WhatsApp connection settings from one place: the Meta channel under Notifications. OrderPin
meta_wa). Fill in:| Field | Value |
|---|---|
| Phone Number ID | from Step 3 |
| Access Token | your 24h temporary token |
| Business Account ID | your WABA ID |
| App Secret | from App Settings → Basic verifies inbound webhooks |
| Webhook Verify Token | the random string you invented |
If the channel is not enabled, the bot still receives your messages but logs its replies to the backend console instead of sending them — so you'll see nothing on your phone. Make sure the toggle is ON.
The bot identifies a sender by matching their WhatsApp number to an Outlet.phone (last 10 digits). OrderPin
The seeded demo outlets use fake numbers (9876500001…), so the bot won't know your real phone yet. Fix it in one of two ways:
98765 43210) → save.# from orderpin-backend/ ./venv/bin/python manage.py shell -c " from apps.masters.models import Outlet o = Outlet.objects.exclude(phone='').first() o.phone = '9876543210' # ← your real WhatsApp number, 10 digits o.save() print('Bot will now recognise', o.phone, 'as', o.name) "
The match is forgiving about the country code: if you message from +91 98765 43210, it matches an outlet stored as 9876543210.
If the sender's number doesn't match any outlet, the bot replies "this number isn't linked to a registered outlet" and stops — by design. That's your signal that Step 5 wasn't done.
Now tell Meta where to deliver incoming messages.
https://random-words-1234.trycloudflare.com/api/v1/whatsapp/webhook/
GET with a challenge; OrderPin's webhook checks your verify token and echoes it back. ✅ Success = the dialog closes without error.messages field. This is mandatory — without it, no inbound messages are delivered.Meta calls GET …/whatsapp/webhook/?hub.mode=subscribe&hub.verify_token=…&hub.challenge=…. OrderPin compares the token to the one on your channel and returns the hub.challenge verbatim. If verification fails, it's almost always a token mismatch or the tunnel isn't running.
Everything's wired. Time to talk to your bot.
hi.The same number now runs whichever flow is most recently published. Edit "Order Placing" (or build a new flow) in the builder, hit Publish, and the live bot updates instantly — no Meta reconfiguration needed.
| Symptom | Likely cause & fix |
|---|---|
| "Verify and Save" fails in Meta | Verify token doesn't match the channel's, or the tunnel isn't running / the URL changed. Re‑copy the current tunnel URL and the exact token. |
| I message the bot, nothing comes back | ① Channel not Enabled (replies log to console). ② messages field not subscribed. ③ Your number isn't on Meta's recipient allow‑list. ④ Token expired (grab a fresh 24h one). |
| "This number isn't linked to a registered outlet" | Step 5 — set an outlet's phone to your real number. |
| Bot says "no products available" | No stock. Run ./venv/bin/python manage.py seed_order_flow (it tops up demo stock), or sync/seed stock for the outlet's warehouse. |
| Webhook returns 403 | Signature check failed — the App Secret in the channel doesn't match the app. Re‑copy it from App Settings → Basic. (Leaving App Secret blank disables the check — fine for a quick test, not for production.) |
| Replies are delayed or stop after a while | WhatsApp's 24‑hour customer‑service window: the bot can only send free‑form messages within 24h of the user's last message. Just message it again to reopen the window. |
Keep an eye on the backend terminal (the one running runserver 8001) while you test — every inbound delivery shows as a POST /api/v1/whatsapp/webhook/ 200 line, and console‑mode replies print there too.
| Item | Value |
|---|---|
| Backend | http://localhost:8001 |
| Admin portal | http://localhost:5175/admin |
| Webhook path | /api/v1/whatsapp/webhook/ |
| Full callback URL | https://<tunnel>/api/v1/whatsapp/webhook/ |
| Channel config | Settings → Notifications → Channels → Meta Business API |
| Live switch | the channel's Enabled toggle |
| Identity match | sender's WhatsApp # → Outlet.phone (last 10 digits) |
| Live bot | the most recently published flow (currently "Order Placing") |
| Re‑seed flow + stock | ./venv/bin/python manage.py seed_order_flow |
whatsapp_business_messaging + whatsapp_business_management). It doesn't expire.https://api.yourdomain.com/api/v1/whatsapp/webhook/), not a tunnel. Set it once in Meta and you're done.