HailMe Platform docsOpen cabinet โ†’

WhatsApp โ€” simulation and controlled Cloud API OTP

Ordinary TEST projects use simulated WhatsApp verification. A separately configured operator profile can admit a real Cloud API control for one approved recipient and authentication template. This is not general customer BYOC activation. There is no automatic WhatsApp fallback from SMS or Telegram.

Try the TEST verification

Open your project's TEST environment, show Verify in Options & channels, and select WhatsApp in Verify. Use a synthetic recipient such as `test:whatsapp-customer-001`. Create the challenge, view its FAKE code, and check it. A successful check settles the accepted sample fee once. Cancellation, expiry and exhausted checks release the reservation. Project budgets apply before creation.

Backend clients use `POST /v1/verify/verifications` with the same project TEST key and Verify scopes:

{"channel":"WHATSAPP","recipient":"test:whatsapp-customer-001","purpose":"signup"}

Affiliated projects inherit a zero platform fee unless the owner explicitly enables it for VERIFY. This does not waive future Meta charges. FAKE delivery has zero provider cost and uses TEST funds only. The generic notification API does not yet accept WHATSAPP; it must not be sent as SMS or Telegram. See the API reference. Verify uses HTTP; the published JVM SDK dev.3 covers notifications and does not yet expose a typed Verify client.

Protocol adapter

The backend-only `platform-provider-whatsapp` module uses a fixed Meta Graph host and version v26.0. It sends approved utility templates and authentication templates with a copy-code button, using the same locally generated code in the template body and button. The template registry must supply the approved name, category, locale and ordered parameter names. Callers cannot inject arbitrary components.

One call performs one request. Redirects and automatic retries are disabled. Known provider rejections retain only numeric error codes. Timeouts, connection loss, invalid receipts and server failures are AMBIGUOUS: they require reconciliation rather than an automatic second message or channel fallback. Acceptance and quality holds are separate from delivered/read receipts and from a price quote.

The webhook parser authenticates X-Hub-Signature-256 over raw request bytes before parsing, then checks the configured business-account and sending-number IDs. It extracts sanitized delivery status, time, numeric failure codes and pricing category. Incoming chats, contacts, history, code values and raw provider errors are not imported. The durable HTTP route binds each message ID or signed opaque claim to an immutable scoped attempt and credential version. Repeated events are deduplicated; late sent reports cannot overwrite read. A delivered/read report never authenticates the user. Expired, failed, cancelled and verified codes cannot be revived by late reports.

Controlled real-provider pilot

`PLATFORM_WHATSAPP_VERIFY_PROFILE` defines the exact project, mode, admission switch, resource and credential pins, approved template/language, recipient and send ceilings. FAKE does not construct a Meta client or accept real credentials. META_TEST additionally requires the reviewed free Meta TEST account and `PLATFORM_WHATSAPP_CONTROL_IO_ENABLED=true`, while ordinary real delivery remains off. It admits at most one send per UTC day and month, including resends. It uses the TEST wallet and is labelled `TEST_PROVIDER_CONTROL`, never FAKE. LIVE is initially restricted to the HailMe first-party project and fee-exempt admission; it remains closed until separate production acceptance.

An admitted backend uses the same Verify endpoint and scopes:

{"channel":"WHATSAPP","recipient":"+12025550123","purpose":"signup","whatsappConsent":true}

The number above is documentation data, not an admitted recipient. The backend must attest the recipient's explicit channel choice. Language must match the configured approved template. The code expires in five minutes. The initial template's Meta delivery window is sixty seconds; late resends are refused. Creating a challenge reserves the accepted platform fee; checking its code successfully settles it once. TEST provider controls exercise TEST accounting only. Affiliation waives the platform fee, not Meta's charges. Billable/category observations are not a numeric price; unknown provider cost stays unknown and is reported separately.

Owner-only settings at the scoped cabinet `verify/whatsapp-connection` endpoint encrypt the access token and App Secret as immutable versions. Ordinary reads never return either secret. Expected version and request ID guard concurrent changes and replay. One Meta sender cannot silently move to another project. Access-token rotation retains prior claim identity; App Secret rotation requires a deliberate separate change, with no fallback to a revoked secret.

The historical cloud TEST callback is `https://localhost:8444/hooks/whatsapp/{configurationId}` on TEST and `https://platform.hailme.app/hooks/whatsapp/{configurationId}` on production. GET verifies Meta's subscription challenge; POST requires TLS, the canonical host and raw-body HMAC. This initial one-recipient pilot caps a body at64KiB and four concurrent callbacks. Meta can send larger batches; general-volume admission requires expanding and testing that bound. Keep TEST and LIVE WABA/phone callback overrides separate; never overwrite another service's existing callback or enable history sync.

Before real delivery

For an existing WhatsApp Business app, use supported Coexistence onboarding. Do not deregister its number to satisfy an ordinary Cloud API migration wizard. Confirm feature and linked-device changes and history-sharing scope before linking. A Tech Provider requirement or App Review may be a separate external prerequisite; do not promise activation until the actual Meta account permits it.

Official references: Cloud API overview, copy-code authentication templates, Business App Coexistence.

The cloud stage was retired on 2026-10-27. The local TEST host cannot receive provider callbacks directly. Keep the real pilot closed; a new external callback rehearsal requires an explicitly configured temporary HTTPS tunnel and validated origin/signature policy. Do not register localhost with Meta.