Technical
13 min read

Returns Analysis and Return-Fraud Detection Without a Data Team

Returns quietly eat ecommerce margin, and a slice of them are fraud. Here's how to analyze returns by SKU, reason, and cost, and how to spot wardrobing, serial returners, and refund-not-returned abuse, without hiring a data team.

Kateryna Kozachenko

Marketing & Growth

TL;DR: returns are one of the largest and least-analyzed costs in ecommerce, and a meaningful slice of them are fraud (wardrobing, serial returners, refund-not-returned, empty-box). The hard part isn't the analysis, it's that the data lives in four places (Shopify, your 3PL or warehouse, your payment processor, and support tickets) that were never joined. Once they're joined, the useful work is straightforward: return rate by SKU and reason, true cost per return, and a set of fraud signals you can run on a schedule. You do not need a data team to do this. You need your sources connected and a way to ask questions across them. That's the case an AI data analyst like Bruin is built for.

Every ecommerce operator knows returns are expensive. Very few can tell you how expensive, which products drive it, or how much of it is fraud, because answering those questions means joining data that lives in systems that don't talk to each other.

Returns in apparel routinely run 20 to 30 percent. Even outside apparel, the reverse-logistics cost (return shipping, inspection, restocking or write-off, refund processing) can erase the margin on the sale entirely. And on top of the honest returns sits a layer of abuse that the retail industry now estimates in the tens of billions of dollars a year. Most of it is invisible until you go looking.

Here's how to go looking, without hiring anyone.

Why returns are hard to analyze

The problem is not the math. It's the plumbing. A single return touches at least four systems:

  • Shopify (or your storefront) knows the order, the refund, the reason code the customer picked, and the timing.
  • Your 3PL or warehouse (WMS) knows what actually came back: was it scanned in, what condition, was it restocked or scrapped, and when.
  • Your payment processor (Stripe, PayPal, Klarna) knows the money movement, chargebacks, and disputes.
  • Support (Gorgias, Zendesk, email) knows the story: the "it arrived damaged" that may or may not be true, the customer who returns something every month.

None of these systems shares a common key out of the box. Shopify's reason codes are a dropdown the customer chose, not the truth. Your WMS keyed everything on its own SKU scheme. Your processor knows a refund happened but not why. To analyze returns properly you have to stitch these together, and that stitching is exactly the job people assume requires a data team.

It doesn't anymore. But you do have to connect the sources once.

The returns analysis every store should run

Once orders, refunds, warehouse receipts, and payments sit in one place, here are the analyses that pay for themselves. None of them is exotic. They're just usually impossible because the data was never joined.

Return rate by SKU and variant. Not store-wide, per variant. A single size or color is often responsible for a wildly disproportionate share of returns. Find it and you can fix the sizing description, the photography, or drop the variant.

Return reason, weighted by cost. "Wrong size" and "damaged" are very different problems: one is a merchandising fix, the other is a packaging or supplier fix. Weight each reason by what it actually costs you, not by count. Ten cheap "changed my mind" returns can matter less than two high-value "damaged in transit" returns.

True cost per return. Add it up honestly: outbound shipping you already ate, return shipping, inspection labor, restocking or write-off, refunded payment fees that don't always come back, and the discount if the item can only be resold as open-box. This number shocks people. It's often 20 to 60 percent of the item price.

Time-to-return distribution. When do returns happen relative to delivery? A spike right before the return window closes is a classic wardrobing signal (buy, use once, return). A cluster right after delivery usually means a real product or sizing problem.

Repeat-return behavior. What share of returns comes from customers who return on most of their orders? These customers frequently have negative lifetime value once returns are counted, and you may be actively acquiring more of them.

The fraud layer, and the signals that expose it

Return fraud isn't one thing. It's a family of behaviors, and each leaves a different fingerprint in the joined data:

  • Wardrobing: buying to use once (an outfit for an event, a TV for the big game) and returning it. Fingerprint: returns clustered near the end of the window, high-value or occasion items, condition notes from the warehouse that say "used".
  • Serial returners: customers whose return rate is far above normal, sometimes across multiple accounts that share a payment method or shipping address. Fingerprint: high per-customer return rate, plus address or card matches across "different" accounts.
  • Refund-not-returned: the refund was issued but the item never actually came back to the warehouse. Fingerprint: a refund in Shopify or your processor with no matching receipt scan in the WMS after a reasonable window. This is the single highest-value check you can run, and it's only possible when refund data and warehouse-receipt data are joined.
  • Empty-box and item-swap: the box comes back but it's empty, or contains a cheaper item. Fingerprint: warehouse condition notes plus weight mismatches, tied to specific customers or return routes.
  • Friendly fraud / chargeback abuse: the customer disputes the charge with their bank instead of requesting a return. Fingerprint: processor chargebacks with a delivered-and-not-returned order.

The pattern across all of these: no single system can see the fraud. Shopify sees a refund. The warehouse sees (or doesn't see) a package. The processor sees a dispute. The fraud only becomes visible when you put the refund next to the receipt next to the payment. That join is the whole game.

You don't need a data team, you need the join and a way to ask

Historically, this kind of cross-system analysis was a data-engineering project: build pipelines from Shopify, the WMS, and Stripe into a warehouse, model the joins, then have an analyst write the queries. Months, and a headcount.

The reason it's now doable without that team is that two things got cheap. Connecting the sources got cheap, and asking questions across them in plain English got cheap.

An AI data analyst is a good fit here specifically because returns questions are endless and ad-hoc. You'll never build a dashboard for every one of "which SKUs drive damaged-in-transit returns from the East Coast 3PL", "which customers were refunded but never sent the item back last quarter", and "did our new packaging reduce damage returns". You just want to ask, get an answer with the query behind it, and move on.

The two properties that matter for returns work:

  1. It can join across sources. The analysis is worthless if the tool can only see Shopify. It has to reach the warehouse receipts and the payment data too.
  2. It can run on a schedule and flag anomalies. The refund-not-returned check should run every week and tell you, not wait for you to remember to ask. Return fraud is caught by monitoring, not by one heroic analysis.

How Bruin fits returns and fraud work

We built Bruin as one platform that connects your sources, joins them, and answers questions on top, which lines up with exactly what returns analysis needs.

You connect Shopify, your 3PL or WMS, and your payment processor once, through direct integrations plus thousands more sources via APIs, webhooks, and scraping. From then on you can ask, in Slack or wherever your team works, "which customers were refunded last quarter with no matching warehouse scan?", and get the list with the query that produced it. Because Bruin ingested and joined the data, the refund-not-returned check is just a question, not a project.

And because the same platform can run things on a schedule, the high-value fraud checks (refund-not-returned, serial returners, chargeback-plus-delivered) can run weekly and post the flagged cases straight into the channel your team already uses: Slack, Microsoft Teams, Google Chat, WhatsApp, Discord, Telegram, email, or the browser. Fraud detection becomes something that watches your back, instead of something you have to remember to look for.

A starter set of questions to ask on day one

Once your order, refund, warehouse, and payment data are connected, these are worth running immediately:

  • Return rate by SKU and variant, ranked, for the last 90 days.
  • True cost per return by product category, including reverse shipping and write-offs.
  • Refunds issued with no matching warehouse receipt after 21 days (the refund-not-returned list).
  • Customers with a return rate above 40 percent and more than three orders.
  • Accounts sharing a payment method or shipping address with more than one "customer".
  • Returns arriving in the last 48 hours of the return window, by product value.
  • Chargebacks on orders marked delivered with no return initiated.

Each of these is a number you can act on: a SKU to fix, a customer to flag, a policy to tighten, a packaging supplier to call.

FAQ

How much of ecommerce returns is actually fraud?

Industry estimates put return fraud and abuse at a meaningful percentage of total returns, and total returns are large, so the dollar figure runs into the tens of billions annually across US retail. For an individual store the rate varies by category and price point, but almost every operator who runs the refund-not-returned check for the first time finds cases they didn't know about.

What's the single most valuable fraud check to start with?

Refund-not-returned: refunds that were issued with no matching warehouse receipt after a reasonable window. It's high-value, unambiguous, and only possible once refund data and warehouse-receipt data are joined. Start there.

Can I do this on Shopify data alone?

Partially. Shopify alone gives you return rates and reasons, which is useful. But the fraud layer and the true-cost analysis need your warehouse and payment data too, because Shopify can't tell you whether the item physically came back or what the reverse logistics cost. The value is in the join.

Do I need to replace my current tools?

No. This is about connecting the systems you already run (Shopify, your 3PL, your processor) so their data can be analyzed together. An AI data analyst reads from those sources; it doesn't replace your storefront or your warehouse.

How does an AI data analyst avoid making up fraud accusations?

By showing its work. A good tool returns the query and the underlying rows for every flag, so a flagged case is a list of specific orders you can inspect, not a black-box verdict. You review before you act. The tool surfaces candidates; a human confirms.

How does Bruin handle the recurring checks?

Bruin can run analyses on a schedule and post results into the channel your team already uses. So the refund-not-returned and serial-returner checks run automatically and flag cases as they appear, rather than depending on someone remembering to look. You can read more or get started at github.com/bruin-data.

Sign up to our newsletter

Practical updates on open-source data pipelines, AI analysts, governance, and what we are shipping at Bruin.