Booking Whatsapp E2e Tutorial

Nexaflow Editor

5 MIN READ

Nexaflow Booking: WhatsApp end-to-end testing tutorial

Version: 27 October 2026. Scope: connection, templates, outbound booking notifications, inbound replies, delivery receipts and failure recovery.

This is a test procedure, not a record of completed live testing. Test against the deployed build containing the communication fixes. A passing unit test or a green “queued” toast does not prove a message reached a phone.

#1. Test strategy and equipment

Use four checkpoints in order:

  1. Connection: Meta can send to a test handset and Nexaflow receives its replies.
  2. Templates and callbacks: Nexaflow can send an approved template, and a real delivery callback updates its log.
  3. Business flows: booking, reminders, rescheduling, estimates, bills and receipts produce the right messages and database changes.
  4. Failure and isolation: disabled sending, opt-out, invalid templates, duplicates and other clinics cannot produce incorrect messages or mutations.

Use a staging clinic and synthetic patient records. Use actual consenting test handsets; do not use invented numbers that might belong to someone. Keep the clinic sender separate from patient and doctor recipient numbers. Do not use a real clinical history, diagnosis or financial transaction.

Test assetSetup
Clinic senderDedicated test Cloud API number or staging clinic number, connected to Nexaflow
Patient ATester-controlled WhatsApp number; normal booking recipient
Patient BSecond tester-controlled number; guardian and wrong-recipient tests
Doctor AProvider profile with a tester-controlled mobile number
Doctor BDifferent provider; preferably a different test handset
Service“Test consultation”, 30 minutes, INR 1,000
Treatment“Test treatment course”, agreed cost INR 10,000, four instalments
Location“Staging clinic”, timezone Asia/Kolkata, future availability

If handsets are limited, run recipient roles sequentially, but do at least one reschedule with different patient and doctor numbers. Otherwise a routing error is difficult to spot.

Create a test register with: case ID, build/version, clinic/module, sender phone-number ID, booking ID, action time with timezone, expected recipient, outbox ID, Meta message ID, final status, handset evidence, result and defect reference. Never record access tokens or app secrets.

#2. Connect WhatsApp before testing bookings

2.1 Choose the sender route

For an initial transport check, Meta's developer setup provides test assets. Add and verify the recipient numbers allowed by the test setup, then send the supplied sample template from Meta's API Setup/Get Started screen. Screen labels may vary.

For a full Nexaflow test, use the actual embedded onboarding flow with a dedicated staging account/number, or an already connected staging sender. A sample message sent from Meta alone does not prove the sender is connected to Nexaflow's booking module.

For your Tech Provider setup, use the clinic account owner/admin to select the correct WhatsApp assets during onboarding. Keep the WABA/account ID, phone-number ID, and display telephone number distinct. The phone-number ID is the numeric sender identifier used by the API; it is not the telephone number.

2.2 Verify the Nexaflow links

  1. Complete WhatsApp onboarding in Nexaflow.
  2. Confirm that the intended clinic number appears as connected.
  3. Assign the number to the intended agent/bot.
  4. Link that agent to the booking module and enable the link.
  5. Confirm the sender and booking module belong to the same account owner.
  6. Open Booking Settings → Communications → WhatsApp appointment updates.
  7. Confirm the sender is offered in the sender dropdown. If it is absent, fix the account/agent/module linkage first.

Pass: the correct sender is selectable. Do not continue by selecting another clinic's sender.

2.3 Validate the webhook independently

The application endpoint is:

https://YOUR-STAGING-HOST/api/whatsapp/webhook text

On the server, verify the deployed environment has the intended META_APP_ID, META_APP_SECRET, META_GRAPH_API_VERSION, META_WEBHOOK_CALLBACK_URL, and META_WEBHOOK_VERIFY_TOKEN. Use your existing server configuration; do not paste secrets into test records. Embedded onboarding also uses the configured signup IDs and phone-registration PIN.

  1. Configure/verify the HTTPS callback in Meta using the server's verification token.
  2. Ensure the app is subscribed to the clinic's account and the WhatsApp messages webhook field. Nexaflow's webhook-sync action can be used to check or repair the account subscription.
  3. Confirm the active callback points at staging rather than another deployment.
  4. From Patient A's handset, send Hello, this is an E2E booking test to the clinic number.
  5. Verify the inbound message reaches the intended Nexaflow agent/conversation and generates a reply.
  6. Send an outbound message and verify real status callbacks arrive too.

Pass: both inbound content and outbound status receipts reach the application. A successful webhook verification handshake alone is insufficient. If a real clinic recipient is outside the app's developer/test users, check the app's production access and the connected business assets as well.

#3. Create and approve the templates

In WhatsApp Manager, select the clinic's account, open Message Templates, create a template, choose its language and submit it for approval. Use Utility content describing a requested booking or transaction; Meta decides the final category and approval. Enter realistic synthetic examples for every variable when requested.

Current Nexaflow contract: BODY-only templates, positional variables, no header, footer or buttons. The variable count and order below must match exactly. Use the exact approved identifier and language code in Nexaflow; en and en_US are different configurations. Suggested names below are examples, not templates that already exist.

PurposeSuggested namePositional parameters, in exact order
General appointment updatebooking_appointment_update1 event; 2 booking reference; 3 location; 4 local date/time
Patient registrationpatient_registration_confirmation1 clinic; 2 patient; 3 patient ID; 4 mobile; 5 DOB
Walk-in bookingwalk_in_booking_confirmation1 patient; 2 patient ID; 3 service and provider; 4 date/time; 5 location
Reminderbooking_reminder1 patient; 2 doctor; 3 date; 4 time; 5 visit instructions
Estimatetreatment_estimate1 patient; 2 treatment; 3 doctor; 4 visit date; 5 estimate; 6 clinic
Treatment billtreatment_bill1 patient; 2 treatment; 3 total cost; 4 total paid; 5 balance; 6 payment plan
Payment receiptpayment_receipt1 patient; 2 treatment; 3 receipt number; 4 payment amount; 5 cumulative paid; 6 balance; 7 method; 8 receipt URL
Reschedule proposalappointment_reschedule_proposal1 clinic; 2 doctor; 3 original date/time; 4 proposed date/time; 5 confirmation URL
Patient reschedule confirmationReuse booking_appointment_updateSame four parameters as general appointment update
Doctor reschedule confirmationdoctor_reschedule_confirmation1 doctor; 2 patient; 3 service; 4 new date/time; 5 location

Patient and doctor confirmation settings can fall back to the main four-parameter appointment template. A dedicated doctor template gives clearer wording.

Copyable template bodies

General appointment update — 4 variables

Appointment update: {{1}}. Reference: {{2}}. Location: {{3}}. Date and time: {{4}}. Please contact the clinic if you need assistance. text

Patient registration — 5 variables

Registration confirmed at {{1}}. Patient: {{2}}. Patient ID: {{3}}. Registered mobile: {{4}}. Date of birth: {{5}}. Please contact the clinic to correct any details. text

Walk-in appointment — 5 variables

Hello {{1}}, your appointment is registered. Patient ID: {{2}}. Service and provider: {{3}}. Date and time: {{4}}. Location: {{5}}. Please contact reception when you arrive. text

Reminder — 5 variables

Hello {{1}}, this is a reminder of your appointment with {{2}} on {{3}} at {{4}}. Visit instructions: {{5}}. Thank you. text

Estimate — 6 variables

Hello {{1}}, your requested estimate for {{2}} with {{3}}, scheduled for {{4}}, is {{5}}. Clinic: {{6}}. Please contact us if you have questions about this estimate. text

Treatment bill — 6 variables

Hello {{1}}, your bill for {{2}} has been updated. Total cost: {{3}}. Total paid: {{4}}. Balance: {{5}}. Payment plan: {{6}}. Please contact the clinic if a correction is needed. text

Receipt — 8 variables

Hello {{1}}, payment for {{2}} has been recorded. Receipt: {{3}}. Amount received: {{4}}. Total paid: {{5}}. Balance: {{6}}. Payment method: {{7}}. View your receipt: {{8}}. Thank you. text

Reschedule proposal — 5 variables

Appointment change from {{1}}: your visit with {{2}} is proposed to move from {{3}} to {{4}}. Review and confirm here: {{5}}. Your original appointment remains active until the change is confirmed. text

Doctor reschedule confirmation — 5 variables

Hello {{1}}, the appointment for {{2}}, service {{3}}, has been rescheduled to {{4}} at {{5}}. Please check your updated appointment list. text

Do not assume submission means approval. Continue only when each template needed for the next test is approved and available in the sender's account. You can start with the general template and add the remaining templates in stages.

#4. Enable the application in stages

  1. Open Booking Settings → Communications → WhatsApp appointment updates.
  2. Enable the channel and select the staging sender.
  3. Set the main appointment template and language.
  4. Set registration, walk-in, reminder and reschedule templates in their respective sections.
  5. Under Estimates & Payments, set the estimate, bill and receipt template names.
  6. Enable the relevant booking events in Appointment communications.
  7. Set one reminder lead time first, e.g. 30 minutes, and provide visit instructions.
  8. Save and reopen settings to confirm values persisted.
  9. Confirm Doctor A's Service Provider profile has the correct recipient mobile, with country code.
  10. Inspect pending staging notifications before enabling the server gate. On the intended server set:
BOOKING_WHATSAPP_ENABLED=true env

Restart the backend using the project's normal deployment/service process. Starting only the Vite frontend does not run the booking notification worker; the worker starts through the backend server entrypoint. It checks approximately every 10 seconds, but that is not a delivery guarantee.

Pass: the app no longer reports server sending as disabled, the sender is linked, and the notification log is available. Keep the gate restricted to your staging sender/test recipients during this exercise.

#5. Understand what a passing message looks like

For each action, verify all three layers:

  1. Business record: correct booking, treatment, payment or proposal exists.
  2. Transport evidence: an outbox entry and Meta message ID/status can be correlated to that record and recipient role.
  3. Handset evidence: the intended person receives the correctly populated message and any link opens the correct record.
Nexaflow statusMeaning and test action
pendingQueued; check worker/server gate if it persists
sendingClaimed by worker; do not trigger another send
acceptedMeta accepted the request; not yet proof of handset delivery
sentSending status reported by WhatsApp
deliveredDelivery reported; verify the intended handset too
readRead reported when available; do not require this for every pass
blockedNo send attempted; inspect template, sender or configuration
failedDefinite provider failure; inspect error and supported retry action
unknownDelivery outcome ambiguous; do not blindly resend
skippedSuppressed, e.g. opt-out, superseded reminder or missed window; inspect reason

Notifications can arrive out of order or omit intermediate states. Do not require every run to visibly show every status. Missing read alone is not a failure.

#6. Run this first happy-path journey

Use one future booking for most of this sequence; create fresh bookings where the scenario needs it. Record evidence after every step.

CaseActionRequired result
E01 Inbound connectionPatient A sends a greetingCorrect agent receives it; response returns to A
E02 RegistrationRegister synthetic Patient A using reception/QR flowCorrect registration message, patient ID and synthetic DOB go to A
E03 AppointmentBook with explicit WhatsApp consentExactly one applicable confirmation; patient, doctor, date/time and location are correct
E04 Appointment listSearch by A's name and mobileName and mobile remain visible, even in filtered results
E05 EstimateOpen payment tracker and send estimateExactly one estimate; amount/range and currency correct; UI says queued until real delivery
E06 BillSet INR 10,000, four instalments; enable bill checkboxBill shows 10,000 total, 0 paid, 10,000 balance; no payment is created
E07 First paymentRecord INR 2,500 with receipt checkbox enabledOne payment and one receipt; paid 2,500, balance 7,500; receipt URL opens on A's phone
E08 ReminderCreate a booking more than 30 minutes away, then wait until the 30-minute thresholdOne timely reminder; current doctor/date/time and instructions are correct
E09 Reschedule proposalPropose a future slotA receives proposed time and working confirmation link; original slot is still booked
E10 Confirm proposalOpen link and acceptOriginal slot released; new slot reserved; one patient and one doctor confirmation; calendars updated
E11 Follow-upCreate another visit and manually link the ongoing treatmentFollow-up label; shared bill counted once; another instalment updates the same account
E12 Unrelated visitBook A with Doctor B for a different treatmentIt does not show or charge the first treatment's payment account
E13 Final paymentPay the remaining balance on the treatment accountCorrect cumulative paid, zero balance, settled status and matching receipt
E14 CancellationCancel a separate future appointmentSlot released; appropriate cancellation message; no duplicate confirmation/cancellation
E15 Complete/no-showComplete one visit and mark another no-showCorrect configured notification behavior and final booking states

For E08, choose a slot around 35–40 minutes away for a 30-minute reminder, or prepare a future test slot appropriately. Do not move the production clock or lower the supported reminder lead time. A reminder more than 15 minutes late is intentionally skipped in this implementation.

Do not complete/cancel/reschedule a booking immediately after creating it during the initial confirmation test. A newer event can legitimately suppress an older unsent event. Test this suppression separately.

Booking conversation

Have Patient A send: “I would like an appointment with Doctor A tomorrow.” Verify the agent discovers actual availability, confirms the selected slot and patient identity, obtains the required confirmation/consent and creates one booking. Verify the slot in the admin UI. Do not pass this case based on an AI reply alone.

Repeat for an unavailable slot and two testers competing for the last slot. Exactly one appointment should reserve it; the other tester should be asked to choose another slot.

Guardian routing

Book a synthetic dependent with Patient B as guardian. Confirm the intended guardian receives notices and receipt/estimate messages, and Patient A is not notified by mistake. Change the booking contact and verify consent/contact routing is re-evaluated appropriately. Opening a link must not expose unrelated patient records.

STOP / START

  1. From A send STOP; verify acknowledgement.
  2. Trigger a fresh notification for A; expect suppression with RECIPIENT_OPTED_OUT.
  3. Verify B still receives its own notifications.
  4. From A send START; verify acknowledgement.
  5. Trigger a new event; expect delivery to resume.

Use new events for step 5. Do not assume START retroactively resends previously skipped messages. Also test UNSUBSCRIBE and RESUME; ordinary sentences containing “stop” should not be interpreted as the exact opt-out command.

YES / NO replies

Test recall campaigns separately: send one recall, reply YES, verify the booking link, select an available slot, then verify the booking/campaign state. Use another recipient to test NO and a preferred-time reply.

For a reschedule proposal, use its secure confirmation URL for the deterministic end-to-end test. A generic YES reply is not proof that a specific reschedule proposal was applied. Check the Known gaps section before signing off any reply-to-confirm claim.

#8. Run inside and outside the 24-hour window

Run the critical outbound cases twice:

  • Open conversation: tester messages the clinic immediately before the test.
  • Closed conversation: use a tester who has not sent the clinic a message for more than 24 hours. Do not send a greeting just before this run.

An outbound message from the clinic does not reset the customer's inbound-message window. Approved templates are the intended path for proactively sending these notifications. Changing a Nexaflow database timestamp is not a valid simulation of Meta's real messaging window.

Repeat appointment confirmation, reminder, estimate, bill, receipt and reschedule confirmation under both conditions. Add cancellation and recall to this run specifically to expose any remaining direct-text paths.

#9. Failure, recovery and isolation tests

CaseDeliberate conditionExpected result
F01Server gate offNo actual send; financial action reports not queued, not sent
F02Module WhatsApp channel offNo actual send; booking/payment still saves correctly
F03Missing financial template nameExplicit configuration error; no false delivery success
F04Wrong template name/language or not approvedBlocked before send; visible error in notification log
F05Wrong variable count/orderCount mismatch blocked; order checked on handset against expected values
F06Unlink sender or disable agent-module linkSender rejected; no other clinic's number used
F07Invalid/missing patient or doctor mobileExplicit failure/warning; no fallback to another person's number
F08Receipt delivery failsRecorded payment and balance remain correct; do not record the payment again just to resend a receipt
F09Same confirmation request retried with same idempotency keyOne booking mutation and one set of applicable notifications
F10Meta redelivers same inbound message/webhookNo duplicate booking/payment/proposal application
F11Delivered/read callback arrives before an older sent/failed callbackFinal status does not regress
F12Network timeout after dispatchUnknown outcome; no automatic duplicate resend; late callback can resolve it
F13Restart or two workers claim messagesNo duplicate dispatch for one queued event
F14Reschedule/cancel before old reminder sendsOld reminder suppressed; future reminder uses new time
F15Finish/reschedule after payment receipt is queuedReceipt is not discarded merely because appointment lifecycle changed
F16Same contact used in two staging clinicsCorrect sender/module handles replies, opt-out and booking links; no cross-clinic mutations
F17Invalid webhook signatureRejected; no business mutation or status update
F18Status persistence failureWebhook is not falsely acknowledged as successfully persisted

Use controlled test fixtures for transport faults, signatures, out-of-order callbacks and worker races. Keep manual handset tests for actual delivery, identity, wording and link behavior. Never replay signed production webhooks against production as a test.

#10. Troubleshooting by symptom

SymptomFirst checks
Sender absent in booking settingsWhatsApp number → intended agent → enabled booking-module link; owner match
No outbox entry after financial actionServer gate, channel, dedicated template, recipient and returned error
Pending indefinitelyBackend/worker running, sending gate, database access, worker logs
BlockedExact approved template name/language, parameter contract, linked sender, opt-out reason
Accepted but no delivery confirmationReal handset receipt, Meta failure callbacks, webhook subscription and correct callback deployment
Handset received it but log is staleSigned status callbacks, sender/account/recipient/message correlation, persistence errors
Patient got update but doctor did notDoctor's stored mobile, selected doctor, event/channel settings and doctor outbox entry
Nothing arrives inboundWebhook verification AND account subscription/messages field; assigned agent; app/account access
Receipt link failsPublic APP_URL/APP_BASE_URL, HTTPS host, route availability and receipt identity
Works only after tester sends “Hi”Possible direct-text dependency; repeat closed-window template test
Wrong booking confirmed by YESSeparate recall vs reschedule context; inspect exact proposal/campaign and module scope

For a blocked event, correct the captured template/account configuration and use the supported retry. Retrying does not rewrite the original recipient, template name or language. An event captured with the wrong values needs a deliberately corrected new notification; do not blindly repeat the financial action. Unknown outcomes are not retryable through the normal UI.

#11. Known gaps to treat as release checks

Code inspection identified these paths; the tutorial does not claim they are already live-tested:

  • The legacy cancellation service still contains a direct-text send in addition to booking lifecycle notification handling. Test closed-window cancellation and duplicate-message behavior explicitly.
  • Recall campaign dispatch still uses direct text. Do not assume proactive recall delivery outside the 24-hour window is solved by configuring the new financial templates.
  • The webhook explicitly handles recall replies and STOP/START. There is no dedicated reschedule-proposal YES/CONFIRM handler in that dispatch path; verify link-based rescheduling, and treat plain-reply confirmation as an unverified feature/gap.
  • The current inbound webhook dispatch selects the first inbound message from a received batch. Include multi-message batch tests; complete outbound-status batching is not proof of complete inbound-message batching.
  • Recalls look up a recent recipient by phone suffix. Cross-clinic reply attribution must be tested; do not sign off tenant isolation based solely on separate sender numbers.
  • A treatment bill on saving a plan is not a scheduled instalment-due reminder. Automatic payment-pending/due-date schedules need their own trigger/template tests when implemented.
  • Developer test assets and passing mocks are not proof of production app/account access or handset delivery.

#12. Sign-off criteria and repeatable regression

Sign off only when:

  • All critical happy paths pass with business state, message correlation and handset evidence.
  • Critical template sends pass inside and outside the 24-hour window.
  • Patient and doctor recipients are independently verified, including guardian and unrelated-treatment cases.
  • No duplicate messages or duplicate financial/booking mutations occur in retry tests.
  • Failures are honest: no “sent” claim for disabled, blocked or unconfigured sending.
  • Outstanding gaps are recorded as defects or explicitly excluded from release scope.

Run the unit tests after changes to communication code. Example from the repository root:

npm test -- tests/unit/TransactionalWhatsApp.test.ts tests/unit/BookingPaymentService.test.ts tests/unit/BookingRescheduleService.test.ts tests/unit/BookingCommunicationSettings.test.ts tests/unit/BookingWhatsAppDelivery.test.ts tests/unit/BookingWhatsAppRegression.test.ts bash

Frontend checks:

cd frontend npm run test:run -- src/components/modules/booking/BookingPaymentTracker.test.tsx src/components/modules/booking/BookingReschedule.test.tsx src/components/modules/booking/BookingWhatsAppSettings.test.tsx src/components/modules/booking/BookingNotifications.test.tsx bash

Database integration tests require a dedicated DATABASE_URL_TEST and run sequentially because setup resets the test schema. Do not point the test runner at a live clinic database. Re-run the short real-handset smoke journey after deployment, sender reconnection, template changes or webhook changes.

Suggested execution order

Session 1: connection, inbound/outbound smoke, general template, registration and booking. Session 2: estimates, bills, receipts, reminders and link-based rescheduling. Session 3: guardian, STOP/START, recalls, failure recovery and isolation. Next day: closed-24-hour-window repetitions and release sign-off.

#Official references

Application details above were checked against the repository; Meta screen labels and account eligibility should be verified against the current dashboard and documentation.

Helpful for you?

Help us improve the world of AI agents.

Keep Learning

View All Guides