Developer Guide 13 min read• Published on 2026-10-19

WhatsApp Flows Complete Developer Guide: Building High-Converting Native In-Chat Forms

Replace sluggish mobile web redirects with native multi-screen forms inside WhatsApp. Full tutorial on Flows JSON v3.0, endpoint encryption, and CRM ingestion.

R&B

R&B Platform Engineering

Principal Solutions Architect · R&B Group

Key Architectural Takeaways
  • WhatsApp Flows replace tedious back-and-forth conversational chatbots with native app-like multi-screen forms, boosting form completion rates by 45–60%.
  • Flow screens, input fields, validation rules, and layout components are declared via a strict declarative Flows JSON schema (v3.0).
  • Data exchange between WhatsApp client devices and your backend is end-to-end encrypted using an RSA-OAEP 2048-bit keypair and AES-128-GCM cipher.
  • Flows can be launched organically from WhatsApp templates, interactive buttons, or directly as destination payloads inside Click-to-WhatsApp ads.
  • R&B CRM provides native webhook decryptors and instant CRM pipeline synchronization for completed flow submissions.

When generating leads on mobile messaging channels, forcing users to click an external link to open a mobile browser causes up to 68% drop-off due to network latency, cookie prompts, and browser loading times. WhatsApp Flows solves this by rendering native, multi-screen forms directly inside the WhatsApp conversation window. In this technical deep dive, we build an end-to-end lead qualification flow using Flows JSON v3.0, handle cryptographic payload decryption in Node.js, and ingest lead records directly into R&B CRM.

1. WhatsApp Flows Architecture & Cryptographic Security Model

WhatsApp Flows operates on a hybrid client-server model. When a user taps a Flow Call-To-Action (CTA) button, the WhatsApp client renders the form natively using pre-compiled declarative JSON assets.

Because user responses often contain sensitive personal data (PII, phone numbers, identity credentials, financial preferences), Meta enforces strict end-to-end payload encryption. When the user taps Submit, the mobile device generates an ephemeral symmetric AES-128 key, encrypts the form responses using AES-GCM, encrypts the AES key using your uploaded RSA 2048-bit public key, and delivers the encrypted envelope via POST to your configured Flows webhook endpoint.

Your server decrypts the AES key using your RSA private key, decrypts the form payload, persists the record into your CRM, and returns an encrypted response payload telling the WhatsApp client to navigate to the Success Confirmation screen.

Key Requirement: Valid RSA-OAEP Keypair

Your Flow public key must be uploaded to Meta via the WhatsApp Manager or Flows API in PEM format (PKCS#8). The corresponding private key must be safely stored in environment variables.

2. Declarative Flows JSON (v3.0) Schema Implementation

The core blueprint of every WhatsApp Flow is its JSON specification. Flows JSON declares the screens, headers, input fields (TextInput, Dropdown, RadioButtonsGroup, CheckboxGroup, DatePicker), and action triggers.

Below is the production-ready Flows JSON schema for a multi-screen lead generation and quote request flow:

flows_v3_lead_generation.jsonjson
{
  "version": "3.0",
  "screens": [
    {
      "id": "LEAD_DETAILS_SCREEN",
      "title": "Request Custom Quote",
      "data": {},
      "layout": {
        "type": "SingleColumnLayout",
        "children": [
          {
            "type": "TextInput",
            "name": "full_name",
            "label": "Full Legal Name",
            "required": true,
            "input-type": "text"
          },
          {
            "type": "TextInput",
            "name": "phone_number",
            "label": "WhatsApp Phone Number",
            "required": true,
            "input-type": "phone"
          },
          {
            "type": "Dropdown",
            "name": "service_type",
            "label": "Service Required",
            "required": true,
            "data-source": [
              { "id": "crm_setup", "title": "WhatsApp CRM & Meta WABA Setup" },
              { "id": "capi_sync", "title": "Meta Conversions API (CAPI) Integration" },
              { "id": "ai_agent", "title": "Autonomous Gemini 2.5 Flash Agent" }
            ]
          },
          {
            "type": "Footer",
            "label": "Submit & Connect with Specialist",
            "on-click-action": {
              "name": "complete",
              "payload": {
                "full_name": "${form.full_name}",
                "phone_number": "${form.phone_number}",
                "service_type": "${form.service_type}"
              }
            }
          }
        ]
      }
    }
  ]
}

3. Webhook Decryption & Ingestion in Node.js

When a customer finishes filling out the flow, your backend receives a webhook with encrypted fields: `encrypted_aes_key`, `encrypted_flow_data`, and `initial_vector`. Here is the production Node.js decryption function utilizing native `node:crypto`:

decryptFlowPayload.ts (Node 22 / Express)typescript
import crypto from 'crypto';

interface EncryptedFlowRequest {
  encrypted_aes_key: string;
  encrypted_flow_data: string;
  initial_vector: string;
}

export function decryptFlowPayload(
  body: EncryptedFlowRequest, 
  privateKeyPem: string
): any {
  // 1. Decrypt AES key with RSA Private Key
  const decryptedAesKey = crypto.privateDecrypt(
    {
      key: privateKeyPem,
      padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
      oaepHash: 'sha256',
    },
    Buffer.from(body.encrypted_aes_key, 'base64')
  );

  // 2. Decrypt Flow Data with AES-128-GCM
  const flowDataBuffer = Buffer.from(body.encrypted_flow_data, 'base64');
  const iv = Buffer.from(body.initial_vector, 'base64');
  
  // Extract 16-byte auth tag from end of ciphertext
  const authTag = flowDataBuffer.subarray(flowDataBuffer.length - 16);
  const cipherText = flowDataBuffer.subarray(0, flowDataBuffer.length - 16);

  const decipher = crypto.createDecipheriv('aes-128-gcm', decryptedAesKey, iv);
  decipher.setAuthTag(authTag);

  const decryptedJson = Buffer.concat([
    decipher.update(cipherText),
    decipher.final(),
  ]).toString('utf8');

  return JSON.parse(decryptedJson);
}

Frequently Asked Questions

Can WhatsApp Flows be linked directly to Facebook & Instagram Ads?

Yes! Inside Meta Ads Manager, select Click-to-WhatsApp as the conversion location, and select "WhatsApp Flow" as the greeting destination. When users tap the ad, the Flow opens instantly inside WhatsApp.

Do WhatsApp Flows require a paid Meta message template?

If initiated outside the 24-hour service window, a Marketing template containing the Flow button is required. Inside the 24-hour window, you can send interactive Flow messages free of template approval.

What is the maximum number of screens allowed in a single Flow?

Meta supports up to 8 distinct screens per Flow, allowing complex multi-step questionnaires, branch logic, and booking workflows.

Interconnected Architecture Guides & Next Reads

Ready to Upgrade Your WhatsApp Sales System?

Launch official Meta Cloud API v25.0, autonomous Gemini 2.5 Flash lead qualification, and CAPI marketing attribution with R&B CRM. Start with a $0 card-backed 7-day trial.