About this return & refund request flow
A return request that starts with "I want to send this back" usually takes a dozen messages before an agent can act: which order, which item, what is wrong with it, has it been worn, and does the customer want their money or a different size. This flow asks all of that in two screens, so the first thing your team sees is a complete return case rather than the start of an interview.
Screen one is the case itself: order number, the items, a reason list, the item condition and the preferred resolution, plus the purchase date so an agent can check the return window at a glance. Screen two collects the customer's own description, an email for the return label or refund receipt, and an explicit agreement to your returns policy, with a link to the full policy right above the checkbox.
Because this is a static flow, it cannot look the order up or decide eligibility on the spot. It records the request exactly as the customer describes it and your team approves, declines or asks for photos in the same chat. Photo upload needs the PhotoPicker component, which this builder does not cover, so the simplest pattern is to ask for pictures as a normal WhatsApp reply after the form is submitted.
Fields this flow returns
When the customer taps the final button, the complete action sends these keys back in response_json. Fields from earlier screens are pulled in with global references (${screen.SCREEN_ID.form.field}), so nothing is lost between screens.
| Key | Component | Screen | Required | Returns | Example |
|---|---|---|---|---|---|
order_number |
TextInput | RETURN_REQUEST | Yes | string | "#10482" |
returned_items |
TextArea | RETURN_REQUEST | Yes | string | "Linen shirt, navy, size M (1 of 2 in the order)" |
return_reasonwrong_size, damaged, wrong_item, not_as_described, arrived_late, changed_mind, other_reason |
RadioButtonsGroup | RETURN_REQUEST | Yes | item id | "wrong_size" |
item_conditionunopened, opened_unused, used, damaged_on_arrival |
RadioButtonsGroup | RETURN_REQUEST | Yes | item id | "opened_unused" |
preferred_resolutionrefund, exchange, store_credit |
RadioButtonsGroup | RETURN_REQUEST | Yes | item id | "exchange" |
purchase_date |
DatePicker | RETURN_REQUEST | Yes | YYYY-MM-DD | "2026-10-03" |
issue_description |
TextArea | RETURN_CONFIRM | Yes | string | "Fits tight across the shoulders. Tags still attached, I would like the same shirt in size L." |
contact_email |
TextInput (email) | RETURN_CONFIRM | Yes | string | "[email protected]" |
policy_agreement |
OptIn | RETURN_CONFIRM | Yes | boolean | true |
Optional fields the customer leaves empty may be missing from response_json or arrive empty. Treat every optional key as nullable in your handler.
Send the Return & Refund Request flow without touching code
You do not need to be technical to use WhatsApp Flows. Connect your WhatsApp number, set the flow up in our drag-and-drop editor and send it to customers in a few clicks. No JSON, no API calls, no WhatsApp Manager.
Connect your number
Log in with Facebook and connect your WhatsApp number in a few minutes. No API keys or servers to set up.
Set up the flow
Start from a ready-made form or import this one, then drag fields in, change the wording and try it on a live phone preview. Click Publish when it looks right.
Send it anywhere
Send it from any chat in the Team Inbox, on web or mobile, send it automatically from an automation, or broadcast it to a list.
Get the answers
Every answer is saved on the customer's profile and chat, and your team can be notified the moment a form comes in.
Sample webhook payload (nfm_reply)
This is what your webhook receives when a customer submits the flow. response_json is a JSON string: parse it, then match flow_token to the record you created when you sent the message. The customer's WhatsApp number is in messages[0].from.
{
"flow_token": "bk_8f2c41",
"order_number": "#10482",
"returned_items": "Linen shirt, navy, size M (1 of 2 in the order)",
"return_reason": "wrong_size",
"item_condition": "opened_unused",
"preferred_resolution": "exchange",
"purchase_date": "2026-10-03",
"issue_description": "Fits tight across the shoulders. Tags still attached, I would like the same shirt in size L.",
"contact_email": "[email protected]",
"policy_agreement": true
}
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "WHATSAPP_BUSINESS_ACCOUNT_ID",
"changes": [
{
"field": "messages",
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "15550001234",
"phone_number_id": "PHONE_NUMBER_ID"
},
"contacts": [
{
"profile": {
"name": "Alex Morgan"
},
"wa_id": "14155550123"
}
],
"messages": [
{
"context": {
"from": "15550001234",
"id": "wamid.SENT_FLOW_MESSAGE_ID"
},
"from": "14155550123",
"id": "wamid.INCOMING_MESSAGE_ID",
"timestamp": "1760000000",
"type": "interactive",
"interactive": {
"type": "nfm_reply",
"nfm_reply": {
"name": "flow",
"body": "Sent",
"response_json": "{\"flow_token\":\"bk_8f2c41\",\"order_number\":\"#10482\",\"returned_items\":\"Linen shirt, navy, size M (1 of 2 in the order)\",\"return_reason\":\"wrong_size\",\"item_condition\":\"opened_unused\",\"preferred_resolution\":\"exchange\",\"purchase_date\":\"2026-10-03\",\"issue_description\":\"Fits tight across the shoulders. Tags still attached, I would like the same shirt in size L.\",\"contact_email\":\"[email protected]\",\"policy_agreement\":true}"
}
}
}
]
}
}
]
}
]
}
Deploy with the WhatsApp Cloud API
Prefer code over WhatsApp Manager? Save the template as return-refund-request.json and run these calls with a system user token that has whatsapp_business_management and whatsapp_business_messaging permissions.
1. Create the flow
curl -X POST 'https://graph.facebook.com/v23.0/{WABA_ID}/flows' \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json' \
-d '{"name": "return_refund_request", "categories": ["CUSTOMER_SUPPORT"]}'
# => {"id": "{FLOW_ID}"}2. Upload the Flow JSON
curl -X POST 'https://graph.facebook.com/v23.0/{FLOW_ID}/assets' \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-F '[email protected];type=application/json' \
-F 'name=flow.json' \
-F 'asset_type=FLOW_JSON'
# => {"success": true, "validation_errors": []}3. Publish it
curl -X POST 'https://graph.facebook.com/v23.0/{FLOW_ID}/publish' \
-H 'Authorization: Bearer {ACCESS_TOKEN}'Publishing is permanent: a published flow cannot be edited. To change it later, create a new flow (or clone it with clone_flow_id) and publish the new version.
4. Send it to a customer
Inside the 24-hour customer service window, send an interactive flow message. Outside it, create a message template with a Flow button that points to this flow, and send the template instead.
{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "14155550123",
"type": "interactive",
"interactive": {
"type": "flow",
"header": {
"type": "text",
"text": "Returns and refunds"
},
"body": {
"text": "Sorry the order was not right. Tell us what you are sending back and how you would like it resolved, and we will reply with the next steps."
},
"footer": {
"text": "Returns are reviewed within 2 business days"
},
"action": {
"name": "flow",
"parameters": {
"flow_message_version": "3",
"flow_token": "bk_8f2c41",
"flow_id": "YOUR_FLOW_ID",
"flow_cta": "Start a return",
"flow_action": "navigate",
"flow_action_payload": {
"screen": "RETURN_REQUEST"
}
}
}
}
}curl -X POST 'https://graph.facebook.com/v23.0/{PHONE_NUMBER_ID}/messages' \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json' \
-d @send-return-refund-request.jsonWhen to send it
Customer says "return" or "refund"
Trigger the flow from a keyword so a customer typing "return", "refund", "exchange" or "wrong size" gets the form immediately instead of a queue.
After delivery confirmation
A few days after an order is marked fulfilled, a delivery follow-up template can carry a "Start a return" Flow button for customers who need it, alongside the usual "enjoy your order" message.
Damaged or wrong item reports
When a customer sends a photo of a broken or incorrect item, reply with the flow so the order number and resolution choice are captured in a format your warehouse can process.
Seasonal return peaks
After holiday sales, route every returns conversation through the flow so agents spend their time approving cases rather than collecting details.
How to customise this template
- Rewrite the return reasons to match what your returns data actually shows. A clothing store needs "Too small" and "Too big" as separate ids; an electronics store needs "Stopped working" and "Missing parts".
- If you do not offer store credit, remove that option rather than leaving it in: customers who pick an option you cannot honour will be disappointed twice.
- Point the EmbeddedLink at your live returns policy page and keep the OptIn wording in step with it. If your window is 30 days, say so in the TextBody on screen one as well.
- Pass your order id as the flow_token when you send the flow from an order notification. The submission then maps to the order without relying on what the customer typed in the order number field.
- For marketplaces or multi-brand shops, add a Dropdown for the seller or brand on screen one so the case can be routed before anyone opens it.
Open this template in the Flow Builder to make these changes visually. The builder keeps field names unique and regenerates the completion payload for you.
Common mistakes to avoid
- Do not phrase the final button or caption as "Refund approved". Submitting the form is a request; approval happens after your team checks the order, the window and the item condition.
- The order number is free text, so expect "#1042", "1042" and "order 1042". Normalise it in your webhook handler before matching, or send the order id in the flow_token instead.
- Keep item condition options honest and neutral. A list that only offers "Unused" pushes customers to pick it, and you lose the information you need to grade the return.
- Ask for photos after the flow, not before. Customers who are asked to take photos first often drop off, while a quick "please send a photo of the item" reply after submission gets a much better response.
Take real orders inside WhatsApp
Whautomate includes a built-in store checkout flow: products, customer details, address and shipping, coupon codes and the order itself, with an optional payment request sent right after. It is created and published for you and runs on an endpoint Whautomate hosts.
- Live products and coupon checks
- Order created on submit
- Optional payment request after checkout
7-day free trial, no credit card required.