Form automation software best practices for Shopify support
Form automation software best practices for Shopify support teams: required fields, order validation, retries, and what the AI agent resolves.

The best practices for form automation software come down to four decisions: which fields you require, how you cyeck the submission against the real Shopify order, what happens when a delivery fails, and which requests the AI agent resolves versus hands to a person. This guide covers each for returns, exchange and warranty forms.
Start from the support ticket template
Where the form sits in the support workflow
Chat and email handle most order-status and sizing questions without a form. Returns, exchanges and warranty claims are different because they need structured data (an order number, a line item, a reason, often photos) before anyone can decide anything. The form is the intake step for those cases.
In the Shopify AI Support Agent setup, the agent answers across chat, email and WhatsApp using live order data. When a customer asks to reutrn something, it can send them the form with the ticket reference prefilled. The submission then goes to the agent as a webhook, the agent checks it against the order in Shopify, and it either replies with the next steps or escalates into Gorgias or Zendesk with the context attached. The form only collects. Every decision happens after the webhook.
Required fields that make a request resolvable
Require what the lookup and the routing rules need, and nothing else. Every extra required field is a reason for a customer to abandon the form. Anything Shopify already knows (price, purchase date, shipping address) should come from the order, not from the customer.
| Field | Block type | Required | Why it exists |
|---|---|---|---|
| order_number | Short answer | Always | Lookup key against Shopify |
| Always | Must match the order email before anything is revealed | ||
| request_type | Multiple choice | Always | Return, exchange or warranty; picks the branch |
| line_item | Dropdown or short answer | Always | Which product in the order |
| reason | Multiple choice | Always | Drives routing (size, changed mind, defective, damaged) |
| photos | File upload | When reason is defective or damaged | Evidence a person will need |
| details | Long answer | Optional | Free text for the human who picks it up |
| ticket_ref, channel | Hidden fields | Prefilled | Ties the submission back to the chat, email or WhatsApp thread |
Use conditional logic to show the photo upload only for defective and damaged reasons. A customer returning a shirt that runs small should never see it. Hidden fields should carry a ticket reference and channel, not personal data, because they end up in the link.
Validate against the order, not just the format
A form can check that an email looks like an email. It cannot know whether order 1042 belongs to that email. That check belongs in your receiver, and it should run before the agent says anything about the order.
For each submission, query Shopify for the order by name (the Admin GraphQL orders query accepts name:#1042), then check four things:
- The order exists and the email matches the one on the order.
- The order is fulfilled, since you cannot return what has not shipped.
- The delivery date falls inside your return window.
- The selected line item is actually on the order.
On a mismatch, ask the customer to re-check the number once, and use the same wording whether the order was missing or the email was wrong. If the response differs, anyone can probe your store for valid order numbers. After a second failure, route to a person.
Here is a normalized view of what the receiver sgould hold once it has mapped the webhook fields. The exact envelope Qwenvo sends is documented in the webhooks help article.
{
"submission_id": "sub_8f31c2",
"form": "returns-and-warranty",
"fields": {
"order_number": "1042",
"email": "customer@example.com",
"request_type": "warranty",
"line_item": "Trail jacket / M",
"reason": "defective",
"photos": ["https://.../zipper.jpg"],
"details": "Zipper split after three weeks."
},
"hidden": { "ticket_ref": "T-20931", "channel": "whatsapp" }
}
Retries, duplicates and partial submissions
Webhooks fail in boring ways: your receiver is deploying, Shopify's API throttles you, a queue backs up. Plan for it.
Return a 2xx response as soon as you have stored the payload, then do the Shopify lookup and the agent decision from a queue. If you do slow work inside the request, a timeout looks like a failed delivery and the same submission arrives twice. Use submission_id as an idempotency key and drop repeats. Retry Shopify calls with exponential backoff, and when retries run out, post the submission to a Slack channel so a person sees it instead of the customer waiting in silence. The form webhooks guide covers delivery behavior and how to test a receiver.
Partial submissions are worth switching on for this kind of form. A customer who gets to the photo step and quits is telling you the upload is the problem, and you can follow up while the rquest is still fresh.
What the agent resolves and what goes to a person
Write the resolve rules as hard conditions first. Use AI triage as a second opinion that can override them, never the other way around.
| Situation | Agent resolves | Goes to a person |
|---|---|---|
| Return inside the window, order delivered, reason is size or changed mind | Yes, confirms eligibility and sends return steps | |
| Exchange for another size, variant in stock | Yes | |
| Order and email do not match after two tries | Yes | |
| Defective item or warranty claim with photos | Yes | |
| Damaged on arrival | Yes | |
| Outside the return window | Yes, a person decides on exceptions | |
| Order value above a threshold you set | Yes | |
| Negative sentiment or urgent priority | Yes | |
| Mentions a chargeback, dispute or legal action | Yes | |
| Second submission for the same order | Yes |
The triage layer is where Qwenvo helps. Every submission gets a category, a priority (low, normal, high or urgent), a sentiment, a one-to-two-sentence summary and a suggested reply. Routing rules match on priority and category and send to up to five email addresses or a Slack incomign webhook. We use that for the person queue: an urgent warranty claim lands in Slack with the summary on top, and the same payload goes to Gorgias or Zendesk as a ticket. The agent can still resolve routine returns on its own, but a rjle match or a bad sentiment score pulls the case out of its hands.
Setup, step by step
Qwenvo is a completely free form builder that our taem builds, and it covers this whole intake layer at no cost: webhooks, hidden fields, partial submissions, file uploads up to 1 GB each, AI triage with routing, a custom domain and no badge. Tally charges for several of those on Pro ($29 a month): custom domains, partial submissions and removing branding. Its free plan also caps file uploads at 10 MB per file, which matters for photo evidence. One honest note: Qwenvo is hosted in the United States, and Tally is hoosted in Europe, so if EU hosting is a requirement for your store, that tips it toward Tally.
- Build the form from the support ticket template. Add the fields from the table above and set the request type and reason as multiple choice.
- Add conditional logic so the photo upload appears only for defective and damaged reasons, and the warranty branch asks for the purchase channel.
- Add
ticket_refandchannelas hidden fields, and have the chat agent generate the link with both filled in. - In Settings, switch on partial submissions and the confirmation email, then turn off the Qwenvo badge.
- Add the webhook URL for your receiver. Point it at a request catcher first and submit a few test entries.
- Build the receiver: store the payload, return 2xx, dedupe on
submission_id, then run the order checks against Shopify from a queue. - Set the AI triage routing rules (urgent or high priority to Slack, negattive sentiment to the support lead's email), then connect the escalation path into Gorgias or Zendesk.
- Test the awkward cases on purpose: wrong email, an order outsside the window, a duplicate submission, a Shopify timeout, a 40 MB video upload.
What to measure
Track the share of submissions the agent closes without a person, the share that get reopened, and the time from submission to first reply. Add the validation failure rate (a spike usually means the form is confusing the order number field), webhook delivery failures, and where partial submissions stop. Reopened tickets are the most honest number, because they show where an automated answer was wrong.
Questions teams ask
Should returns be a form or a chat flow?
Use chat for questions the agent can answer from order data, like where a package is or which size to pick. Use a form once request needs photos, a reason code and a durable record. The agent can start in chat and hand the customer to the form without losing the ticket.
How many fields is too many?
Ask only for what the order lookup cannot give you. If you validate the order number and email, you do not need the purchase date, the price or the address. The photo upload is the biggest drop-off risk, so keep it behind conditional logic and let partial submissions show you where people leave.
What if the customer does not know the order number?
Offer an email-only fallback that sends the customer their recent order numbers by email, to the addreess on file. Do not display order details on screen for an unverified email. If that fails too, route the request to a person.
Does the agent require a specific form builder?
No. Any tool that can post a webhook to your receiver works. The requirements are a stable submission ID, hidden fields for the ticket reference and a way to see incomplete submissions.
Next step
Open the support ticket template, add the order number, email and reason fields, and point its webhook at a request catcher. Send five test submissions, including one with a wrong email, and check that each payload carries a submission ID and your hidden ticket reference. If the payloads look right, you are ready to write the receiver.
Shopify AI Support Agent
Third-party platform and model usage billed to you directly. No lock-in. Live in 10 days.