Flow Endpoints, RSA Encryption & Dynamic Routing

Dynamic WhatsApp Flows require an encrypted HTTPS endpoint to exchange data between WhatsApp user screens and your business backend in real time.

This guide details the cryptographic requirements (Data API v3.0), the action lifecycle protocol (INIT, data_exchange, BACK, and ping), and SMSPort's automated key management.


1. Cryptography Architecture (Data API v3.0)

Every request from WhatsApp to your endpoint is encrypted using a hybrid cryptosystem:

  1. Asymmetric Layer (RSA-OAEP-2048):
    • Your business creates an RSA-2048 keypair.
    • The public key is uploaded and registered with Meta for your sender phone number.
    • WhatsApp encrypts a newly generated 128-bit AES symmetric key using your RSA public key with SHA-256 and MGF1 padding.
  2. Symmetric Layer (AES-GCM-128):
    • The user's screen submission data is encrypted using AES-128-GCM with a 12-byte initialization vector (IV) and a 16-byte authentication tag.
  3. Response Encryption:
    • To send data back to WhatsApp, your endpoint encrypts the JSON response using the same AES key and an inverted bitwise IV (IV ^ 0xFF).

2. Dynamic Action Lifecycle Protocol

Your HTTPS endpoint must handle 4 primary action types dispatched in the decrypted JSON payload:

{
  "version": "3.0",
  "action": "data_exchange",
  "screen": "APPOINTMENT",
  "data": {
    "department": "cardiology"
  },
  "flow_token": "usr_94208a7b_token"
}

1. `INIT` Action

Triggered when a user opens a Flow that has endpoint mode enabled:

  • Server Responsibility: Return default options, dynamic user greeting, and first screen layout data.
  • Response: Next screen name (screen: "DETAILS") and initial data dictionary.

2. `data_exchange` Action

Triggered when a user clicks a button or footer with "on-click-action": { "name": "data_exchange" }:

  • Server Responsibility: Validate submitted inputs (e.g., credit score, appointment date availability), run database lookups, and return the next screen.
  • Response: Return the target screen and updated dynamic options.

3. `BACK` Action

Triggered when a user taps the client header back arrow on a screen configured with "refresh_on_back": true:

  • Server Responsibility: Re-fetch dynamic availability without storing form mutations.

4. `ping` Health Check Action

WhatsApp automatically pings your endpoint to monitor uptime and health:

  • Server Request: {"action": "ping"}
  • Mandatory Response: {"data": {"status": "active"}} (Must return HTTP 200 within 10 seconds).

3. SMSPort Automated Key Management

SMSPort eliminates manual OpenSSL CLI operations through its built-in encryption service:

  1. One-Click Key Generation:
    • In /whatsapp-flows, open Flow Details > Encryption & Endpoints.
    • Click Generate Keypair to automatically generate a compliant RSA-2048 key in the database.
  2. Automatic Meta Registration:
    • Click Register Public Key to transmit your PEM certificate to Meta's Graph API (/{phone_number_id}/whatsapp_business_encryption).
  3. Built-in Decryption & Routing Engine:
    • Incoming webhook payloads to /webhooks/meta/whatsapp/flows/:flowId/exchange are decrypted, processed, and re-encrypted seamlessly.

4. Media Upload CDN Handling & Decryption (Flow 4.0+)

When a user submits files via PhotoPicker or DocumentPicker, WhatsApp encrypts each file before uploading to WhatsApp's MMG CDN. Your business endpoint or Cloud API response receives a payload containing CDN download URLs alongside AES-256 decryption keys and HMAC authentication parameters:

Media Payload Schema

{
  "signed_contract": [
    {
      "cdn_url": "https://mmg.whatsapp.net/v/t62.7119-24/31415926_...",
      "encryption_metadata": {
        "encryption_key": "dGVzdF9hZXNfMjU2X2tleV9leGFtcGxlMTIzNDU2Nzg5MDE=",
        "iv": "ZXhhbXBsZV9pdl8xNmJ5dGU=",
        "hmac_key": "dGVzdF9obWFjXzMyYnl0ZV9rZXlfZXhhbXBsZTEyMzQ1Njc4",
        "plaintext_hash": "c2hhMjU2X3BsYWludGV4dF9oYXNoX2V4YW1wbGVfMTIzNDU2",
        "encrypted_hash": "c2hhMjU2X2VuY3J5cHRlZF9oYXNoX2V4YW1wbGVfMTIzNA=="
      }
    }
  ]
}

Decryption Algorithm (AES-256-CBC + HMAC-SHA256)

To decrypt uploaded user files, execute the following cryptographic pipeline:

  1. Download Ciphertext: Issue an HTTP GET request to cdn_url and download the raw bytes into a buffer.
  2. Verify Encrypted Hash: Calculate the SHA-256 hash of the downloaded buffer and confirm it matches Base64-decoded encrypted_hash.
  3. Split Ciphertext and HMAC Signature:
    • In WhatsApp MMG files, the last 10 bytes of the downloaded buffer represent the truncated HMAC-SHA256 signature (mac_tag).
    • The preceding bytes (buffer.subarray(0, buffer.length - 10)) represent the actual encrypted payload (file_ciphertext).
  4. Authenticate HMAC:
    • Compute HMAC-SHA256 over (iv + file_ciphertext) using Base64-decoded hmac_key.
    • Take the first 10 bytes of this computed HMAC and compare against mac_tag. Reject if mismatch.
  5. Decrypt AES-256-CBC:
    • Decrypt file_ciphertext using AES-256-CBC with Base64-decoded encryption_key and iv.
    • Remove PKCS#7 padding to recover the raw file bytes.
  6. Verify Plaintext Integrity:
    • Compute SHA-256 of the decrypted bytes and verify it matches Base64-decoded plaintext_hash.
  7. Storage:
    • Save or stream the plaintext buffer directly to your S3 bucket or local document archive.