Checkout Flows

WhatsApp Flows collect shipping address and payment details after a cart order. This is the native checkout path — distinct from carousel Buy-button orders, which create orders with order_source carousel_campaign or carousel_inquiry without using the native cart UI.

Portal Flow Design (recommended)

Non-technical users should design Flows in the ChatYug portal — not by editing JSON by hand.

  1. Open WhatsApp Messaging → Flow Design (or Commerce → Flow Design).
  2. Create a flow from a template (Checkout, Lead Generation, Survey, Appointment, Support, or Blank).
  3. Use the drag-and-drop designer: screens on the canvas, components in the left palette, connections by dragging the purple port between screens.
  4. Click Save, then Approve (publishes the flow on Meta — DRAFT → PUBLISHED).
  5. Use Test Send to send the published flow to any WhatsApp number (digits with country code, e.g. 919876543210).

Advanced users can still open the JSON escape hatch in the designer. Canvas layout is stored for round-trip and is stripped automatically before Meta upload.

For checkout, copy the Meta Flow ID into Commerce Settings → Checkout Flow ID after publish.

Full operator guide (every component, properties, templates, and Meta rejection fixes): Flow Design Guide.

List flows

GET /api/external/commerce/flows

Auth: Authorization: Bearer ck_<api_key> (required)

Response example

{
  "success": true,
  "flows": [
    {
      "id": 1,
      "meta_flow_id": "700000000000001",
      "name": "Demo Checkout Flow",
      "category": "SHOPPING",
      "status": "PUBLISHED"
    }
  ]
}

Create flow

POST /api/external/commerce/flows

Auth: Authorization: Bearer ck_<api_key> (required)

Request parameters

FieldRequiredTypeDescription
nameYesstringFlow display name
categoryNostringMeta flow category (default SHOPPING)
flowJsonNoobjectWhatsApp Flow JSON definition (screens, fields, routing)

Response example

{
  "success": true,
  "message": "Flow created",
  "flow": {
    "id": 1,
    "meta_flow_id": "700000000000001",
    "name": "Demo Checkout Flow",
    "category": "SHOPPING",
    "status": "DRAFT"
  }
}

Publish flow

POST /api/external/commerce/flows/:flowId/publish

Auth: Authorization: Bearer ck_<api_key> (required)

:flowId is the internal ChatYug flow ID (not the Meta flow ID).

Response example

{
  "success": true,
  "message": "Flow published successfully"
}

Send flow message

POST /api/external/messages/flow

Auth: Authorization: Bearer ck_<api_key> (required)

Send an interactive Flow message to a customer. Use after a cart order if auto-send is disabled in portal settings, passing the flow_token from GET /orders/:orderId.

Request parameters

FieldRequiredTypeDescription
phoneNumberIdYesstringWhatsApp phone number ID to send from
toYesstringRecipient phone in digits (e.g. 919876543210)
flowIdNostringMeta Flow ID. Falls back to the default checkout flow configured in portal Commerce Settings.
flowTokenNostringBind flow response to an order. Auto-generated if omitted.
headerTextNostringDefaults by flow category (shopping keeps checkout copy; lead/survey/support use neutral copy)
bodyTextNostringDefaults by flow category
footerTextNostringDefault Powered by ChatYug
ctaTextNostringFlow CTA button label (defaults by category, often Open)
initialScreenIdNostringFirst screen to open (auto-resolved from stored flow JSON if omitted)
initialScreenDataNoobjectPre-fill data for the first screen (e.g. order_id, product_name, order_total)

Response example

{
  "success": true,
  "message": "Flow message sent",
  "flowToken": "flow_1720856400000_abc123",
  "messageId": "wamid.HBgMOTE5ODc2NTQzMjEwFQIAERgSQjAwMDAwMDAwMDAwMDAwAA=="
}

Receive checkout answers

After the customer submits the flow, Meta posts interactive.type = nfm_reply. Parse response_json and match flow_token to the order (same token from send / GET /orders/:orderId). Field keys match designer input Names.

End-to-end examples (curl + Node): Commerce Flows — receive filled data. Operator guide: Flow Design Guide — send & receive.

Code samples — send flow

curl -X POST https://chatyug.com/api/external/messages/flow \
  -H "Authorization: Bearer ck_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumberId": "100000000000001",
    "to": "919876543210",
    "flowId": "700000000000001",
    "flowToken": "order_1720856400000_abc123",
    "initialScreenData": {
      "order_id": "1001",
      "product_name": "Demo Cotton T-Shirt",
      "order_total": "INR 998.00"
    }
  }'
const axios = require('axios');

await axios.post('https://chatyug.com/api/external/messages/flow', {
  phoneNumberId: '100000000000001',
  to: '919876543210',
  flowId: '700000000000001',
  flowToken: 'order_1720856400000_abc123',
  initialScreenData: {
    order_id: '1001',
    product_name: 'Demo Cotton T-Shirt',
    order_total: 'INR 998.00'
  }
}, { headers: { Authorization: 'Bearer ck_your_api_key_here' } });
import requests

requests.post('https://chatyug.com/api/external/messages/flow', json={
    'phoneNumberId': '100000000000001',
    'to': '919876543210',
    'flowId': '700000000000001',
    'flowToken': 'order_1720856400000_abc123',
    'initialScreenData': {
        'order_id': '1001',
        'product_name': 'Demo Cotton T-Shirt',
        'order_total': 'INR 998.00'
    }
}, headers={'Authorization': 'Bearer ck_your_api_key_here'})
$client = new GuzzleHttp\Client();
$client->post('https://chatyug.com/api/external/messages/flow', [
    'headers' => ['Authorization' => 'Bearer ck_your_api_key_here'],
    'json' => [
        'phoneNumberId' => '100000000000001',
        'to' => '919876543210',
        'flowId' => '700000000000001',
        'flowToken' => 'order_1720856400000_abc123',
        'initialScreenData' => [
            'order_id' => '1001',
            'product_name' => 'Demo Cotton T-Shirt',
            'order_total' => 'INR 998.00'
        ]
    ]
]);
Related: Flow Design Guide (components, analytics, Meta rejections) · Commerce Flows API & MCP (manage, send, analytics) · WhatsApp Flows