How TripOps connects to WhatsApp
A technical description of the integration, for agencies evaluating TripOps and for reviewers assessing our use of the WhatsApp Business Platform.
TripOps is a multi-tenant platform. Its customers are independent travel
agencies. Each one connects its own WhatsApp Business Account, and TripOps
sends, receives and manages templates on that account under the permission the agency
grants. The accounts being acted on belong to our clients — which is why Advanced access
to whatsapp_business_messaging and whatsapp_business_management
is required rather than Standard access to our own account.
1. Connecting an agency
- The agency keeps ownership of its WhatsApp Business Account and its phone number. TripOps never takes custody of either.
- The agency shares its WABA with our business portfolio as a partner. We assign it to a system user and mint a permanent system-user token — never a temporary one, which would expire in 24 hours and present as a broken integration.
- We call
POST /{waba-id}/subscribed_appsso that account's messages are delivered to our webhook. - The agency can revoke this from its own Meta Business Settings at any time, without contacting us.
2. Receiving messages
- Meta delivers to a single endpoint,
POST https://tripops.in/webhook. - Every delivery is authenticated: the
X-Hub-Signature-256header is verified as an HMAC-SHA256 of the raw request body against the app secret, using a constant-time comparison. Unsigned or mismatched deliveries are rejected. - Routing uses
changes[].value.metadata.phone_number_id— the id of the number the message arrived on. That is the primary key of our channel records, so identifying the owning agency is a direct lookup rather than a scan. - The message is written against that agency alone.
3. Sending messages
(whatsapp_business_messaging)
- Replies call
POST /{phone-number-id}/messagesusing the credentials of the agency that owns the conversation. - Tokens are stored AES-256-GCM encrypted at rest and decrypted only at the moment of sending. They are never returned by any listing screen.
- There is one outbound function in the codebase and it resolves credentials per tenant. If they cannot be resolved it throws: a message is never sent from another agency's number, and a failed send is never recorded as delivered.
- Free-form replies are sent only inside WhatsApp's 24-hour customer service window. Outside it, a pre-approved template is required.
4. Managing templates
(whatsapp_business_management)
- Templates are listed with
GET /{waba-id}/message_templatesand created withPOST /{waba-id}/message_templates, on the agency's own WABA. - Agencies need this because template approval is how they may legitimately re-open a conversation — a quote follow-up, a booking confirmation, a departure reminder.
5. Keeping agencies apart
- Every stored record carries the id of the agency that owns it.
- Conversation records are keyed
{company-id}:{phone}. This matters: two agencies can legitimately be talking to the same traveller, and a key based on the phone number alone would silently merge those two conversations into one. - An automated test suite attempts a cross-tenant read on every build — one agency asking for another's conversation by the same phone number — and fails the build if it succeeds.
6. Billing
TripOps charges agencies a subscription for the software. WhatsApp conversation charges are billed by Meta directly to each agency, against the payment method on its own WhatsApp Business Account. TripOps does not resell Meta messaging and extends no credit line to its customers.
7. Data and deletion
For an agency's own account data we are the data fiduciary; for the travellers it talks to, the agency is the fiduciary and we are its processor. What we hold, for how long, and how to have it removed is set out in the privacy policy and the data deletion page.