Use Tab, then Enter to open a result.
Customer onboarding remains a friction point for financial services and regulated industries. Standard external web links for Know Your Customer (KYC) verification often lead to high drop-off rates because they force users out of the WhatsApp interface. WhatsApp Flows solve this by providing a native, interactive UI. However, implementing a multi-page KYC process requires sophisticated state management and dynamic routing via external webhooks.
This guide details the architecture of a dynamic KYC flow. You will learn to manage transitions between personal data entry, document selection, and confirmation screens while maintaining data integrity.
The Architecture of Multi-Page KYC Flows
Unlike static forms, a multi-page KYC flow treats the WhatsApp interface as a frontend that communicates with your backend in real-time. The core of this system is the data_exchange action. This action triggers a POST request to your endpoint every time a user interacts with a button or finishes a screen.
In a KYC context, your backend acts as the state machine. Since WhatsApp Flows are stateless, you must use the flow_token to track where the user resides in the verification sequence. If a user submits their national ID number on screen one, your server validates that data and returns a response that instructs the Flow to render screen two.
The Role of the Flow Token
The flow_token is a unique identifier you generate when sending the initial message. It serves as the primary key in your session database. You use this token to retrieve the current progress of the user. Without a robust token strategy, your backend loses context when a user moves from the identity screen to the address verification screen.
Prerequisites for Dynamic Implementation
Before building the logic, ensure your environment meets these requirements:
- A Meta Business Account with an approved WhatsApp Business API setup.
- An endpoint reachable via HTTPS with a valid SSL certificate.
- A backend capable of handling JSON payloads and asymmetric decryption.
- A database (Redis or PostgreSQL) to store temporary KYC session data.
If the official Meta onboarding process is too slow for your prototyping phase, some developers use WASenderApi as an alternative. It connects via a QR session to a standard WhatsApp account and supports webhooks for incoming messages. While it bypasses some official constraints, it requires careful management of account rate limits during high-volume KYC bursts.
Step 1: Designing the Multi-Page Flow JSON
The Flow JSON defines the screens. For KYC, you need at least three screens: START, ID_UPLOAD, and SUCCESS. Each screen must specify which action triggers the next step.
{
"version": "3.1",
"screens": [
{
"id": "START",
"title": "Identity Verification",
"terminal": false,
"data": {
"first_name": { "type": "string" }
},
"layout": {
"children": [
{
"type": "TextHeading",
"text": "Enter Your Details"
},
{
"type": "TextInput",
"label": "Full Name",
"name": "full_name",
"required": true
},
{
"type": "Button",
"label": "Next",
"on-click-action": {
"name": "data_exchange",
"payload": {
"current_screen": "START",
"full_name": "${form.full_name}"
}
}
}
]
}
},
{
"id": "ID_SELECTION",
"title": "Select ID Type",
"terminal": false,
"layout": {
"children": [
{
"type": "RadioButtons",
"name": "id_type",
"options": [
{ "id": "passport", "title": "Passport" },
{ "id": "license", "title": "Driver License" }
]
},
{
"type": "Button",
"label": "Continue",
"on-click-action": {
"name": "data_exchange",
"payload": {
"current_screen": "ID_SELECTION",
"id_type": "${form.id_type}"
}
}
}
]
}
}
]
}
Step 2: Handling the Webhook Data Exchange
When the user clicks "Next" on the START screen, WhatsApp sends a POST request to your webhook. Your server must decrypt the payload, process the data, and return the next screen name. The response body determines what the user sees next.
Webhook Implementation Example (Node.js)
This logic handles the transition between screens by checking the current_screen property in the incoming payload.
app.post('/whatsapp-flow-webhook', (req, res) => {
const { action, screen, data, flow_token } = decryptPayload(req.body);
if (action === 'data_exchange') {
switch (screen) {
case 'START':
// Save user name to database using flow_token
saveUserData(flow_token, { name: data.full_name });
// Direct the flow to the selection screen
return res.json({
version: '3.0',
screen: 'ID_SELECTION',
data: {
user_name: data.full_name
}
});
case 'ID_SELECTION':
// Update session with selected ID type
updateUserSession(flow_token, { id_type: data.id_type });
// Complete the flow or move to document upload reference
return res.json({
version: '3.0',
screen: 'SUCCESS',
data: {
message: 'Information received.'
}
});
default:
return res.status(400).send('Unknown Screen');
}
}
});
Step 3: Implementing Dynamic Validation Logic
KYC requires strict data validation. If a user enters an invalid ID format, do not advance the screen. Instead, return the same screen with an error message.
You achieve this by including an error_message or specific validation flags in the JSON data object returned by the webhook. The Flow UI uses these flags to show conditional text components. This prevents the user from progressing until the data meets your backend requirements.
Step 4: Security and Payload Decryption
WhatsApp Flow payloads are encrypted using your Business Solution Provider (BSP) or Meta public keys. Your backend must use your private key to decrypt the request. This ensures that the KYC data remains secure during transit.
Verify the signature of every request. High-concurrency environments often face issues where decryption fails due to key mismatch or malformed payloads. Centralize your decryption logic in a dedicated middleware to ensure consistency across all screens.
Handling Edge Cases in Production
Flow Expiration
Flow sessions have a limited lifespan. If a user starts the KYC process but waits hours to find their passport, the flow_token might become invalid depending on your backend TTL (Time to Live) settings. Implement a cleanup job for your session database to remove incomplete KYC records and notify the user to restart the process.
Latency and Timeouts
WhatsApp expects a response from your webhook within 10 seconds. If your backend performs a heavy task like calling a third-party credit bureau or an AI-based document verification service, the flow will time out.
To avoid this, use the webhook only for screen navigation and lightweight validation. Perform heavy document processing asynchronously. Show a "Processing" screen in the Flow and send a follow-up WhatsApp message once the verification completes.
Network Inversion
In distributed systems, webhooks might arrive out of order. While less common in Flow data_exchange because the UI waits for a response, always use the flow_token and a timestamp to verify that the incoming data represents the most recent state.
Troubleshooting Common KYC Flow Failures
- Screen Mismatch Error: This occurs when your webhook returns a screen ID that does not exist in the Flow JSON. Ensure the strings match exactly.
- Invalid Signature: Frequently caused by incorrect buffer handling in Node.js or Python. Ensure you read the raw request body before any parsing middleware modifies it.
- Data Property Missing: If a screen expects a variable like
user_namebut your webhook response omits it, the Flow will fail to render. Always provide default values in your response data object.
FAQ
How many screens can a single KYC WhatsApp Flow contain? While Meta does not strictly limit the count, performance degrades as the JSON size increases. Aim for 3 to 5 screens. If you need more, split the process into multiple separate Flows.
Can I upload images directly inside a WhatsApp Flow? Currently, Flows do not support a native file picker or camera interface for direct uploads. You must provide a link to a separate secure upload page or instruct the user to send the document as a standard media message after the Flow ends.
What happens if the user closes the app mid-flow?
Progress is lost unless your backend saved the data from the previous data_exchange steps. When the user re-opens the Flow, you can use the INIT action to resume them from the last completed screen by checking your database for that flow_token.
Is the flow_token enough to prevent session hijacking?
No. You must also verify the request signature from Meta. The flow_token identifies the session, but the signature proves the request came from a trusted source.
Does this work with unofficial APIs like WASenderApi? WASenderApi primarily handles standard messaging webhooks. To run a native WhatsApp Flow, you generally need the official Meta Cloud API. You can use WASenderApi to send the initial message containing the Flow, but the interactive components rely on Meta's rendering engine.
Conclusion
Building dynamic multi-page WhatsApp Flows for KYC verification requires a shift in how you handle state. By treating your webhook as a navigation controller and using the flow_token as a session anchor, you create a seamless experience for your users. Focus on keeping your webhook responses fast and your validation logic centralized. Once your multi-page logic is stable, consider implementing real-time progress tracking to identify where users drop off in your verification funnel.