Product returns: what to investigate first
A synthetic CSV and recalculable diagnosis: separate orders, units and open cohorts before treating a return reason as a proven cause.
TL;DR: To investigate returns, compare the same product after the same follow-up period and keep two rates: affected orders and returned units. The reason a customer selects guides an investigation; it does not establish what went wrong.
Contents
To investigate returns, compare the same product after the same follow-up period and keep two rates: affected orders and returned units. The reason a customer selects guides an investigation; it does not establish what went wrong.
Four returned backpacks appear in a report, and someone suggests stopping the campaign. Three facts are still missing: how many backpacks were delivered, how many orders they belonged to, and how long buyers have had to return them. This diagnosis ends with an assigned check, rather than a culprit selected from a column.
Define the event you count
A request, a physically received item and a refund are different events. Here we count units physically received back, linked to their original order line. A refund without returned goods does not enter that numerator. Neither does a pending request, although it needs its own operational queue.
This matters when exporting. Shopify distinguishes Reversed quantity, which can include cancellations and edits, from Returned quantity, specifically for physically returned units. Its documentation also distinguishes sale dates from adjustment dates. Check the exact field before describing every negative number as a return. Shopify’s official definitions.
Our worksheet is an independent working format, not a Frihet export or feature. For its place alongside orders and other records, read the guide to ecommerce data and integrations.
Set the cut-off and cohort first
The example is entirely synthetic. The cut-off is 2026-09-13, with 30 days of analytical follow-up after delivery, including returns received on day 30. This is neither a legal deadline nor a recommended store policy. Choose a horizon that lets you observe your own process and document the reasoning.
We group by SKU and delivery date. The 2026-08-01 cohort has completed follow-up; the 2026-09-06 cohort has only seven days. “Mature” means it has completed our window, not that further returns are impossible. Preserve later cases and analyse them separately if needed.
For partial deliveries, split lines by delivery and retain a key that can reunite the order. If the delivery date is missing, mark the record as unclassifiable; do not turn it into an order without a return. Keep open requests outside the physical-return rate but visible to the person handling them.
A table you can recalculate
The working package (ZIP) contains order-lines.csv, results.csv and recalculate.py. The first holds 30 fictional rows, one per delivered line; the second is the calculated output. The script uses only the Python 3 standard library. Preserve the originals and run python3 recalculate.py in a copy to verify the results.
| SKU and cohort | Orders | Delivered units | Orders with returns | Returned units |
|---|---|---|---|---|
| BAG-A, 2026-08-01, mature | 10 | 20 | 3 | 4 |
| BAG-B, 2026-08-01, mature | 10 | 10 | 1 | 1 |
| BAG-A, 2026-09-06, open | 10 | 20 | 1 | 1 |
For mature BAG-A, 3 / 10 × 100 = 30 % of orders are affected and 4 / 20 × 100 = 20 % of units are returned. For mature BAG-B, both rates are 1 / 10 × 100 = 10 %. There is no contradiction: an order can contain two units and return both, as the first BAG-A line does.
Recent BAG-A shows 10 % by orders and 5 % by units, but remains open. It does not demonstrate that an intervention improved the product. We have simulated no intervention. Nor is there a universal threshold making 20 % acceptable or unacceptable.
Keep a row you can explain
line_id,order_id,sku,cohort,channel,delivered_at,units_delivered,units_returned,return_received_at,reason_codeline_id identifies the line; order_id lets you count distinct orders. Do not add SKU-level order counts to calculate a store total: a real order may contain several products. Each example order contains one SKU to keep the exercise easy to verify.
SIZE means unsuitable size as reported; DAMAGE, reported damage; UNKNOWN, unavailable reason; NONE, no physical return recorded. A code is not a warehouse verification. Preserve original wording separately when available, with restricted access and without unnecessary personal information.
The sheet simplifies each line to one receipt and reason. If units from a line return on different dates or for different reasons, use an events table linked by line_id and sum only events inside the horizon. Do not repeat units_delivered for every event: that inflates the denominator. Investigate a duplicate ID before removing rows.
A reason tells you where to look
In mature BAG-A, three units have SIZE and one has UNKNOWN. Therefore 3 / 4 = 75 % describes the reason distribution among returned units; it is not the product return rate. Removing the unknown reason creates an apparent 100 % size problem from incomplete information.
The next check would compare measurements of those three units, the ordered variant and the product description those buyers saw. If measurements match but the description creates a different expectation, there is an information hypothesis. If a unit differs, investigate that item and its batch. The selected reason cannot choose between those explanations.
BAG-B has one unit with DAMAGE. Check packaging, receipt evidence and batch; the label does not establish that the carrier damaged it. One observation also cannot establish a stable trend.
Do not blame a channel using different groups
The example’s returned cases are in web. That opens a question, not a case for closing the channel. Compare the same SKU, variant and horizon; check promotions, batches and recording quality. Five orders from a channel provide little information. Dividing them into smaller segments does not create precision.
If reports disagree, preserve filters, cut-off and field definitions. Shopify documents discrepancies caused by reporting periods and logic. Before seeking a commercial explanation, rule out comparing different parts of an order. Shopify report discrepancies. The integrations directory helps establish which source you can access; a listing does not guarantee these fields.
Finish with a small, verifiable decision
Copy and assign this note: “BAG-A, 2026-08-01 cohort; 4/20 units, 3/10 orders; three SIZE reasons and one UNKNOWN; check measurements and product description; catalogue owner; evidence pending; review after checking the four returned units from three orders.”
Add which finding would change the action and preserve the previous analysis version. Do not remove the unknown or adjust the cohort to improve a number. When evidence exists, choose a bounded test and later compare equally mature cohorts. To assess economic impact, work through costs separately with the margin calculator: these rates do not measure profit.
Was this article helpful?
FAQ
Can I use a recent cohort to demonstrate an improvement?
A cohort still under observation does not demonstrate an improvement over one that has completed the observation window. Compare the same product with equal observation periods and keep order-based and unit-based rates separate.
Does the most frequent return reason prove the cause?
No: it is a clue to check against the product and available evidence. Its percentage describes the reasons among returned units, not the product's return rate; retain unknown reasons too.