How to filter orders by status in a csv
- Step 1Export the full orders CSV — Shopify: Orders → Export → plain CSV for Excel/Numbers. WooCommerce: Orders → Export (or a CSV-export plugin). BigCommerce / Magento / a 3PL OMS: the standard orders export. The file will contain both a financial-status and a fulfilment-status column — note which one you want before filtering.
- Step 2Drop the file onto the filter above — PapaParse parses it in your browser and auto-detects the delimiter. The header row is read so the status columns appear by name in the Filter column dropdown — pick
Financial Status,Fulfillment Status,Status, or whatever your platform calls it. - Step 3Pick the column, then the condition — Select the status column, then a Condition. Use
equalsfor one exact status (pending),containsfor a family of statuses that share a substring (refund→refunded+partially_refunded), ornot_equalsto drop a single status and keep the rest. - Step 4Enter the status value — Type the status exactly as it appears in the cells —
pending,unfulfilled,partially_refunded. Matching is case-insensitive by default, so casing doesn't have to match.is_empty/is_not_emptyneed no value (useful for orders with a blank fulfilment status). - Step 5Click Filter rows and review the counts — The result panel shows Rows matched and Rows filtered out, plus a preview of the first 10 matching rows. Cross-check Rows matched against the count your platform shows for that status before downloading.
- Step 6Download or chain for multiple statuses — Download gives
<name>.filtered.csv. To keep two unrelated statuses (e.g.pendingandon_hold), filter once for the first, then run the output through the filter again — or use CSV Column Value Splitter to produce one file per status at once.
Operators mapped to order-status filtering
All 10 operators are available in the Condition dropdown. Matching is case-insensitive unless you tick Case-sensitive. value is matched literally — never as a regex.
| Operator | Order-status use | Needs a value? |
|---|---|---|
equals | Exact single status — equals pending keeps only pending (and Pending, PENDING) rows | Yes |
not_equals | Everything except one status — not_equals cancelled keeps every order that isn't cancelled | Yes |
contains | A family of statuses sharing a substring — contains refund matches refunded + partially_refunded (default operator) | Yes |
not_contains | Drop a family — not_contains cancel removes cancelled and canceled spelling variants | Yes |
starts_with | Prefix match — starts_with partial for partial, partially_paid, partially_refunded | Yes |
ends_with | Suffix match — ends_with _paid for paid / partially_paid financial states | Yes |
greater_than / less_than | Numeric only (uses parseFloat) — use on Total or Quantity, not on text statuses | Yes |
is_empty | Keeps rows where the status cell is literally blank — orders with no fulfilment status set | No |
is_not_empty | Keeps rows that have any value in the status column | No |
Common order-status columns by platform
Platforms split status across two columns. Pick the one matching the question you're answering. Values shown are the lowercase machine values most exports use.
| Platform | Financial-status column / values | Fulfilment-status column / values |
|---|---|---|
| Shopify | Financial Status: pending, authorized, paid, partially_paid, refunded, partially_refunded, voided | Fulfillment Status: fulfilled, unfulfilled, partial, (blank for unfulfilled in some exports) |
| WooCommerce | Status: wc-pending, wc-processing, wc-on-hold, wc-completed, wc-cancelled, wc-refunded, wc-failed | (single Status column — no separate fulfilment column) |
| BigCommerce | Order Status: Pending, Awaiting Payment, Awaiting Fulfillment, Shipped, Completed, Cancelled, Refunded | (combined into the Order Status column) |
| Generic OMS / 3PL | payment_status: paid, unpaid, partial, refunded | fulfillment_status: open, picking, shipped, delivered, backorder |
Cookbook
Real before/after slices from order exports. Customer fields anonymised. value is matched literally and case-insensitively unless noted.
Keep only unfulfilled Shopify orders for the picking team
ExampleThe picking team only wants orders still to ship. Filter the Fulfillment Status column with equals unfulfilled. Note Shopify sometimes leaves this column blank rather than writing unfulfilled — if equals unfulfilled returns fewer rows than expected, try is_empty instead (see edge cases).
Input (Shopify orders export): Name,Financial Status,Fulfillment Status,Total #1001,paid,fulfilled,42.00 #1002,paid,unfulfilled,18.50 #1003,pending,unfulfilled,99.00 #1004,paid,fulfilled,12.00 Config: column = Fulfillment Status, operator = equals, value = unfulfilled Output (.filtered.csv): Name,Financial Status,Fulfillment Status,Total #1002,paid,unfulfilled,18.50 #1003,pending,unfulfilled,99.00 Rows matched: 2 · Rows filtered out: 2
Catch all refund-related orders in one pass with contains
ExampleYou want both fully and partially refunded orders for a finance audit. Rather than two passes, contains refund on Financial Status catches refunded and partially_refunded together, because both share the refund substring.
Input: Name,Financial Status,Total #2001,paid,30.00 #2002,refunded,45.00 #2003,partially_refunded,80.00 #2004,voided,0.00 Config: column = Financial Status, operator = contains, value = refund Output: Name,Financial Status,Total #2002,refunded,45.00 #2003,partially_refunded,80.00 Rows matched: 2
Keep everything except cancelled orders
ExampleFor an active-orders report you want the whole file minus cancellations. not_equals cancelled inverts the match — no need to enumerate every status you do want. WooCommerce prefixes statuses with wc-, so use the exact stored value.
Input (WooCommerce export): order_id,status,total 5001,wc-processing,60.00 5002,wc-cancelled,25.00 5003,wc-completed,140.00 5004,wc-cancelled,12.00 Config: column = status, operator = not_equals, value = wc-cancelled Output: order_id,status,total 5001,wc-processing,60.00 5003,wc-completed,140.00 Rows matched: 2 · Rows filtered out: 2
Two unrelated statuses — chain the filter twice
ExampleThere's no comma-separated multi-value box. To keep pending AND on_hold (which share no useful substring), filter for one, download, then re-drop the output and filter for the other — but that gives an OR only if you combine results. The cleaner route for OR across many values is one file per value via Column Value Splitter; for two values, run not_equals against every status you DON'T want.
Goal: keep status in {pending, on_hold} only.
Approach A (two not_equals passes, removing the unwanted):
Pass 1: not_equals paid → drops paid rows
Pass 2: not_equals shipped → drops shipped rows on the result
...repeat for each unwanted status
Approach B (cleaner): use /tool/csv-column-value-splitter to
produce one CSV per status value, then keep the two files
you want (orders.pending.csv, orders.on_hold.csv).
Why not 'pending,on_hold' in the value box?
contains 'pending,on_hold' matches the LITERAL substring
'pending,on_hold' inside a cell — which never occurs.Orders with a blank fulfilment status
ExampleSome Shopify exports leave Fulfillment Status empty for unfulfilled orders rather than writing the word unfulfilled. is_empty keeps exactly those rows. It checks for a literally empty cell, so a cell with a stray space would NOT match (it isn't trimmed first).
Input: Name,Fulfillment Status #3001,fulfilled #3002, #3003,partial #3004, Config: column = Fulfillment Status, operator = is_empty (no value) Output: Name,Fulfillment Status #3002, #3004, Rows matched: 2
Errors and edge cases
Real errors and silent failures sourced from each platform's own documentation. Match the wording to the row, fix what the row says to fix.
Comma-separated value box to keep multiple statuses
Not supportedThere is no multi-value input. Typing pending, unfulfilled into the value box with contains matches the literal substring pending, unfulfilled inside a single cell, which never occurs — you'll get zero rows. Keep multiple statuses by using not_equals/not_contains to drop the ones you don't want, picking a shared contains substring, or splitting one-file-per-value with CSV Column Value Splitter.
Exclude mode toggle
By design — use not_equalsThere is no separate keep/exclude switch. Exclusion is done with the not_equals and not_contains operators. not_equals cancelled is the exclude-this-status filter; not_contains cancel drops both cancelled and canceled spelling variants in one pass.
greater_than on a text status column
Returns nothinggreater_than and less_than run parseFloat() on the cell. A text status like pending parses to NaN, and every comparison with NaN is false — so the row never matches. Use the numeric operators only on numeric columns like Total or Quantity, and the text operators (equals, contains) on status columns.
is_empty doesn't catch a cell with a space
Whitespace preservedis_empty checks whether the cell is literally "" — it does NOT trim first. A fulfilment-status cell containing a single space passes is_not_empty, not is_empty. If your export pads blanks with spaces, run CSV Whitespace Trimmer first, then filter.
Status casing varies across the file
Handled by defaultFiltering is case-insensitive unless you tick Case-sensitive. equals pending matches Pending, pending, and PENDING. Only tick Case-sensitive if two statuses differ only by case and must be treated as distinct — rare for order data.
Free tier 500-row / 2 MB limit on a big orders file
Upgrade requiredFree accounts cap at 2 MB and 500 data rows. A year of orders easily exceeds both. Pro raises the file limit to 100 MB and the row limit to 100,000. To work within free limits, first slice with CSV Row Limiter, or upgrade for the full file.
Two columns share the same header name
Index-resolvedThe Filter column dropdown lists every header in order. If two columns are both named Status, both appear — pick by position. The browser tool resolves your choice by index, so you always filter the column you actually selected, even with duplicate header text.
Combining a status filter with an amount filter
Chain two passesA single pass applies one condition to one column. To keep unfulfilled orders over £100, filter Fulfillment Status equals unfulfilled first, download, re-drop the result, then filter Total greater_than 100. The header survives both passes, so the chain is lossless.
Partial-status prefix matches more than intended
Check with starts_withcontains partial matches partial, partially_paid, AND partially_refunded. If you only want fulfilment partial, use equals partial on the fulfilment column, or starts_with to scope to a known prefix. Always sanity-check Rows matched against the platform's per-status count.
Frequently asked questions
How do I keep just the pending orders?
Select your status column, choose equals as the condition, and type pending as the value. Matching is case-insensitive by default, so Pending and PENDING are caught too. Download gives <name>.filtered.csv with the header plus only the pending rows. The result panel shows Rows matched and Rows filtered out so you can reconcile against your platform's pending count.
Can I filter to keep multiple statuses at once?
Not in a single pass — there is no comma-separated value box. If the statuses share a substring, use contains (e.g. contains refund keeps refunded and partially_refunded). Otherwise, either use not_equals/not_contains to drop the statuses you don't want, or use CSV Column Value Splitter to produce one file per status value and keep the files you need.
Can I exclude a status rather than keep it?
Yes — that's what not_equals and not_contains are for. not_equals cancelled keeps every order except cancelled ones. not_contains cancel drops both cancelled and canceled spelling variants. There's no separate exclude toggle; the negative operators do the job.
Why did my numeric filter on a total column return nothing?
greater_than / less_than use parseFloat(). If the total cells contain a currency symbol (£42.00) or thousands separators, parseFloat('£42.00') is NaN and the comparison fails. Strip the symbol first with CSV Find & Replace (£ → empty), then filter, or sort the column with CSV Sorter which strips currency symbols for numeric sort.
Is the status match case-sensitive?
No, not by default. equals pending matches Pending, pending, and PENDING. Tick the Case-sensitive checkbox only if you need to distinguish statuses that differ solely by case — uncommon in order data, but available.
Does the filter treat my value as a regular expression?
No. The value is matched literally. A status like on-hold or payment_pending is matched character-for-character, and special characters such as . or * are literal, not wildcards. If you typed .* it would only match cells literally containing .*.
Is the header row included in the row count?
No. The header is always preserved separately and is never counted as a data row. If the result says Rows matched: 12, the downloaded file has 13 lines — the header plus 12 matching order rows.
Some unfulfilled orders have a blank status cell — how do I catch those?
Use is_empty (it needs no value). Some Shopify exports leave Fulfillment Status blank instead of writing unfulfilled. Note is_empty checks for a literally empty cell — a cell with a stray space won't match, so trim the column first with CSV Whitespace Trimmer if your export pads blanks.
Can I combine a status filter with an order-total filter?
Yes, by chaining. One pass applies one condition to one column, so filter by status first, download, re-drop the result, then filter by Total greater_than your threshold. The header survives each pass, so the chain is lossless. The orchestrator can also run the two filter steps back to back.
How big an orders file can I filter?
Free tier caps at 2 MB and 500 data rows — fine for a recent slice but not a full year. Pro raises this to 100 MB and 100,000 rows. For very large exports, slice first with CSV Row Limiter or upgrade. Processing is in-browser, so it's bounded by your machine's memory, not a server.
Is my order data uploaded anywhere?
No. Parsing and filtering run entirely in your browser via PapaParse. Customer names, shipping addresses, and order totals never reach a JAD Apps server. Only an anonymous run counter is recorded for signed-in dashboard stats — no file content.
Can I run this in an automated reconciliation pipeline?
Yes. GET /api/v1/tools/csv-column-filter returns the option schema (column, operator, value, caseSensitive). Pair the @jadapps/runner once, then POST the file to 127.0.0.1:9789/v1/tools/csv-column-filter/run. A common pipeline: nightly orders export → filter to unfulfilled → hand to the warehouse system. The runner is on-device, so order data never leaves your machine.
Privacy first
Processing runs locally in your browser with PapaParse. No file is uploaded — only metadata counters are saved for signed-in dashboard stats.