Shopify order fields you can filter a WhatsApp flow on
Every Shopify order arrives carrying about seventy pieces of data. Here is what each one holds and fourteen ways stores use them to send a different message to a different customer.
The If Shopify Event Data filter is the block that lets one Shopify flow behave differently for different orders — it compares a field from the order Shopify just sent you against a value you type, and stops the flow when they do not match. There are over 70 fields available to it, 14 comparison operators, and 14 of the fields sit ready-made in a dropdown.
This is the vocabulary underneath almost every useful store automation. A flow without it sends the same message to a 500-rupee accessory order and a 40,000-rupee furniture order, to a first-time buyer and to someone on their ninth purchase, to a prepaid order and a cash-on-delivery one. A flow with it stops doing that.
The events themselves — which seven exist and what each one is good for — are covered in WhatsApp automation for Shopify. This page is about the data those events carry.
What the filter actually reads
When something happens in your store, Shopify sends ConvoFly the whole order as one bundle of data — Shopify calls this a webhook, and publishes the full list of events it will send on its webhook topics page. That bundle contains far more than the order total: every address line, the payment gateway, the customer's lifetime spend, the tags on the order, and the tracking number once it exists.
The filter block can look at any of it. You pick a field, pick a comparison, type a value, and the flow continues only if it matches. Put the block right after the Shopify trigger and everything downstream runs for a narrowed slice of orders.
Two things about matching are worth knowing before you build anything. Multiple
conditions on one block are combined with AND — all of them must
pass. And text comparison is case-insensitive, so
USA matches usa and you never need to guess Shopify's
capitalisation.
The seven events decide which fields are filled
Every event carries the order, but not every field is populated at every moment. A tracking number does not exist when the order is placed. A cancel reason does not exist unless the order was cancelled. Filtering on a field that is empty at that moment is the single most common reason a flow silently never runs.
| Trigger event | Fires when | Fields that are reliably filled |
|---|---|---|
| Order placed | A new order is created | Totals, addresses, line items, gateway, customer |
| Payment successful | The order is marked paid | Everything above, plus financial_status = paid |
| Payment failed | A payment attempt fails | Totals, customer, gateway |
| Order shipped / fulfilled | A fulfillment is created | Adds tracking_number and tracking_link |
| Order delivered | Tracking reports delivery | Adds delivery confirmation to the above |
| Order cancelled | The order is cancelled | Adds cancel_reason and cancelled_at |
| Abandoned cart / checkout | A checkout starts and is not completed | checkout_url, totals, whatever contact details were entered |
There is no eighth event. No stock-level trigger, no price-change trigger, no review trigger — if you need one of those, it has to reach you another way.
The 14 operators, and the four that do most of the work
The operator dropdown offers fourteen comparisons. In practice four of them carry almost every real flow.
| Operator | What it does | Typical use |
|---|---|---|
| equals / does not equal | Exact text match, ignoring case | financial_status equals paid |
| contains / does not contain | Looks for text anywhere inside the value, including inside lists | tags contains wholesale |
| starts with / ends with | Value begins or finishes with your text | order_name starts with # |
| is greater than / is less than | Reads the value as a number; commas are ignored | order_total is greater than 5000 |
| is ≥ / is ≤ | The same, inclusive of the number you type | customer.orders_count is ≥ 3 |
| character length is greater / less than | Counts characters in the text | address1 length is less than 15 |
| is empty / is not empty | Checks only whether anything is there — no value box appears | tracking_number is not empty |
The character-length pair is the least obvious and the most quietly valuable. It is how you catch an address that is too short to deliver to before a courier discovers the same thing for you.
How to add a condition
- Open the automation in Builder 2.0 and start it with the Shopify Store Event trigger, choosing which of the seven events fires it.
- Click the + below the trigger and add If Shopify Event Data from the Filter group.
- Press + Add condition. Pick a field from the dropdown — 14 common ones are listed — or choose Type your own field key for anything else in the groups below.
- Pick an operator and type the value. Leave the value box alone for is empty and is not empty; it disappears on purpose.
- Add more conditions to the same block only when you want all of them to be true. For an either/or, build two separate rules instead.
- Save, then test it against a real order before enabling — the safe way to do that is in testing a WhatsApp automation safely.
The field groups, and the dot rule
Fields come in two shapes. Most are typed exactly as they are:
total_price, city, tags. Some live inside a
sub-section of the order and are typed with a dot:
customer.first_name, billing_address.city.
- Totals and money —
total_price(also usable asorder_total),subtotal_price,total_tax,total_discounts,total_line_items_price,total_weightin grams, andcurrencyas an ISO 4217 code such asPKRorUSD. - Status and identity —
financial_status,fulfillment_status,order_number,order_name,cancel_reason,source_name,tags,note,test,buyer_accepts_marketingand the timestamps. - Payment and contact —
gateway,payment_gateway_names,email,phone. - Shipping address —
country,country_code,province,city,address1,address2,zip,first_name,last_name. - Billing address — the same sub-fields, always with the prefix:
billing_address.city,billing_address.zip. - Customer —
customer.orders_count,customer.total_spent,customer.tags,customer.email,customer.phone,customer.created_at. - Shipping and tracking —
tracking_number,tracking_link,order_status_url,checkout_url. - Lists —
line_items,discount_codes,shipping_lines,payment_gateway_names,refunds. Use contains on these, never equals.
One trap: bare name, first_name, last_name
and phone read from the shipping address, which is usually what you
want. For the customer's own saved profile values, use the customer.
versions. And Shopify's tags field holds the tags on the order,
which is a different thing from the contact tags ConvoFly keeps — those are checked
with the separate Check Customer Tags block, described in tagging and
segmenting customers automatically.
Fourteen scenarios stores actually run
1. Hold high-value cash-on-delivery orders for confirmation
The classic. A large COD order that nobody confirmed is the most expensive parcel in the warehouse. Two conditions on one block:
order_total· is greater than ·5000payment_gateway_names· contains ·cash on delivery
Then ask for a yes/no confirmation before the order goes to packing. The reasoning behind the threshold and the wording is in COD order confirmation on WhatsApp.
2. Catch an address too short to deliver to
address1· character length is less than ·15
"House 5" is seven characters and no courier will find it. Route those orders to a human, or ask the customer for a landmark, before dispatch. The full treatment is in delivery address verification on WhatsApp.
3. Treat a first-time buyer differently from a regular
customer.orders_count· equals ·1
First-time buyers get the "here is how our delivery works" message with the tracking explanation in it. Change the operator to is greater than with the same value and you have the repeat-buyer branch instead — shorter, warmer, no explaining.
4. A separate lane for wholesale and bulk buyers
tags· contains ·wholesale
If your team already tags bulk orders in Shopify, the tag travels with the order. Send those to a named account manager instead of the standard confirmation, as in wholesale and bulk enquiries on WhatsApp.
5. A different language per country
- Rule A —
country· equals ·Pakistan - Rule B —
country· equals ·United States
Because conditions are AND-only, this is two separate rules, each pointing at its
own approved template. It is also the reason to prefer country_code
(PK, US) once you sell into many markets — two characters,
no spelling variants to guess.
6. Only message on orders that are genuinely paid
financial_status· equals ·paid
Shopify's payment statuses are a fixed vocabulary — pending, authorized, paid, partially paid, refunded, partially refunded, voided — documented on its order status help page. Type them exactly and nothing else.
7. Send tracking only once tracking exists
tracking_number· is not empty
Fulfillments occasionally get created without a tracking number attached. Without this guard, your customer receives a shipping message with a blank space where the number should be. More on the sequence in shipping and tracking updates on WhatsApp.
8. Chase only the carts worth chasing
order_total· is greater than ·2000checkout_url· is not empty
An abandoned-checkout message sent more than 24 hours after the customer's last message is a marketing template, which costs money and needs opt-in — Meta's rules on that live in its messaging documentation. A value floor keeps that spend pointed at carts big enough to repay it. Timing is argued out in abandoned checkout recovery on WhatsApp.
9. Win back a cancellation, but only the right kind
cancel_reason· equals ·customer
Shopify records why an order was cancelled: customer, fraud, inventory, declined or other. Only the first is worth a follow-up message. Sending a friendly "we noticed you cancelled" to an order your own fraud filter killed is a bad look.
10. Never message a test order
test· equals ·false
One condition, and your own test orders stop triggering live customer messages. Worth adding to every store flow before it goes live.
11. Respect the marketing checkbox
buyer_accepts_marketing· equals ·true
For anything promotional — a review request, a reorder nudge, a cross-sell — this gate keeps you on the right side of both Shopify's own opt-in record and Meta's template rules. Order confirmations and shipping updates do not need it; those are utility messages.
12. Heavy orders get different delivery instructions
total_weight· is greater than ·10000
Weight arrives in grams, so 10,000 is 10 kg. Furniture, appliance and bulk-grocery stores use this to ask "will someone be home to receive a heavy parcel?" instead of sending the standard confirmation.
13. Follow up on one campaign's discount code
discount_codes· contains ·EID50
Discount codes arrive as a list, so contains is the operator. This is how you watch a campaign in chat: only orders carrying that code get the follow-up, and the replies tell you what the campaign actually attracted. The attribution caveats are in measuring WhatsApp revenue in Shopify.
14. Separate in-store and phone orders from web orders
source_name· equals ·web
Shopify records where an order came from — web, pos,
shopify_draft_order, iphone, android. A
point-of-sale order does not need a "thanks for shopping online" message, and a draft
order your team keyed in by hand usually should not trigger anything at all.
Five reasons a condition silently never matches
- The gateway field is empty. Newer Shopify stores often leave
gatewayblank. Matchpayment_gateway_namescontainscash on deliveryinstead, or combine afinancial_statusof pending with a highorder_total. - The field is not filled at that event. Filtering an Order-placed
flow on
tracking_numbermatches nothing, ever, because tracking does not exist yet. - Two conditions that cannot both be true. Everything on one block
is AND.
countryequals Pakistan andcountryequals United States is a flow that never runs. - A timestamp compared as a number. Dates arrive as text like
2026-06-05T10:22:00Z. Use starts with2026-06to match a month; greater-than will not work on them. - A bare name field reading the wrong place. Write
shipping_address.nameandshipping_address.companywith the prefix — without it they read the order-level value instead.
What this filter cannot do
Being clear about the edges saves an afternoon. The block has no OR — build two
rules. It does no arithmetic, and it cannot compare one field against another, only
against a value you type. And it cannot reach inside a list to compare a single item:
checking whether one specific product's quantity is above two is not something
line_items supports, because list contents differ from order to order.
For that, an AI Check block reads the order in plain language and picks a
path — the trade-offs are in when to use AI and
when to use buttons.
Where the full list lives
Inside your account, the builder links to a complete reference at Automations → Shopify Fields & Events — every field key, its meaning and a real example value, laid out in eight tables. Keep it open in a second tab while you build. When a condition will not fire, the fastest fix is almost always to open a real order and check what Shopify actually sent, rather than what you assumed it sent.
Frequently asked questions
How do I detect a cash-on-delivery order in Shopify?
Match payment_gateway_names contains “cash on delivery”. The plain gateway field is left empty by many newer Shopify stores, so a condition on it matches nothing.
Can I use OR between two Shopify conditions?
No. Conditions on one If Shopify Event Data block are combined with AND, so all of them must pass. For an either/or, build two separate rules with one condition each.
How do I tell a first-time buyer from a repeat customer?
customer.orders_count equals 1 is a first-time buyer; is greater than 1 is a repeat customer. The value comes from the customer's Shopify profile, not from the order itself.
Why does my condition on the order date never match?
Timestamps arrive as text such as 2026-06-05T10:22:00Z, so number comparisons fail on them. Use starts with 2026-06 to match a month.