Return Abuse Detection
5 min read
The Return Abuse Detection module is the heart of TrustLens for most stores. Returns are the single largest source of preventable margin loss in WooCommerce — serial returners, wardrobing customers, and refund-fraud rings often hide in plain sight across hundreds of orders. The Returns module turns refund data your store already generates into a clear, sortable customer-level view of who’s costing you money.
Module ID: returns. Default: enabled. Free tier (complete).
What It Observes #
The module hooks into WooCommerce refund events. When an order is refunded — full or partial, admin-initiated or customer-initiated — the module:
- Reads the refund amount, the order total, and the reason text
- Increments the customer’s
total_refundscount - Increments either
full_refundsorpartial_refundsbased on the refund-to-order-total ratio - Adds the refund amount to
total_refund_value - Recalculates
return_rateastotal_refunds / total_orders - Updates
last_refund_date - Logs a
refundevent to the timeline - Queues an asynchronous score recalculation
The module classifies a refund as “full” when the refund amount equals (or is within $0.01 of) the order total. Anything less is “partial.” This distinction matters for the wardrobing signal.
What It Signals #
The module emits up to three concurrent signals.
Return Rate Tier (Primary) #
Mutually exclusive. Only one tier fires per customer based on the current return_rate.
| Return Rate | Score | Reason Shown on Profile |
|---|---|---|
| ≥ 60% (critical threshold) | -40 | “Very high return rate: 67%” |
| ≥ 40% (high threshold) | -25 | “High return rate: 48%” |
| ≥ 25% (elevated) | -10 | “Elevated return rate: 31%” |
| ≤ 5% with 5+ orders | +10 | “Excellent return history” |
| 5%–25% | 0 | (no signal) |
The critical and high thresholds (60% and 40%) are configurable in Settings → Modules → Returns. The 25% boundary is fixed in code; it represents the point where a return rate becomes statistically uncommon for typical e-commerce.
Wardrobing Pattern (Secondary) #
Fires alongside the rate tier when applicable. Detects the pattern of repeatedly returning items for full refunds — the classic “buy, wear, return” cycle.
| Trigger | Score | Reason Shown on Profile |
|---|---|---|
| 3+ refunds total and ≥90% are full refunds | -10 | “90%+ full refunds (wardrobing risk)” |
The 3-refund minimum exists to suppress this signal on customers with one or two returns — a single full refund is normal; a pattern of them is not. The 90% threshold is calibrated against typical e-commerce data where partial refunds (shipping refunds, partial credits) usually outnumber full refunds in legitimate cases.
High Refund Value (Tertiary) #
Catches customers whose absolute refund value is unusual regardless of rate.
| Trigger | Score | Reason Shown on Profile |
|---|---|---|
| Total refund value ≥ $2,000 | -10 | “High refund value: $2,340” |
| Total refund value ≥ $1,000 | -5 | (reason text omitted) |
These are stackable with the rate tier. A customer with a 65% rate, 90%+ full refunds, and over $2,000 in lifetime refund value will see all three negative signals on their profile, contributing -40, -10, and -10 respectively, for a total Returns penalty of -60 before any other module contributes.
What “Insufficient Data” Means #
The Returns module returns a zero score with no reason text if the customer has fewer than 3 orders. This is independent of the minimum-orders threshold for scoring overall — even if you lower the global minimum to 2, the Returns module specifically waits for 3 orders before drawing conclusions. The reason: with only 1 or 2 orders, return rate is too volatile to be meaningful (a single refund on 1 order = 100% rate).
Settings #
| Setting | Default | Description |
|---|---|---|
| Critical return rate threshold | 60% | Return rate above this triggers the -40 signal |
| High return rate threshold | 40% | Return rate above this triggers the -25 signal |
| Module enabled | On | Master toggle for the module |
To adjust, go to TrustLens → Settings → Modules → Returns.
Tuning for Your Industry #
Default thresholds are sensible for general retail. Industries with naturally higher return rates need adjustment:
| Industry | Typical Baseline Return Rate | Suggested Thresholds |
|---|---|---|
| General retail | 5–12% | Defaults: 60 / 40 |
| Electronics | 3–8% | Tighter: 50 / 30 |
| Apparel (general) | 15–25% | Looser: 70 / 50 |
| Apparel (fashion / fit-critical) | 20–40% | Much looser: 80 / 60 |
| Shoes | 20–35% | Looser: 75 / 55 |
| Beauty / cosmetics | 3–8% | Tighter: 50 / 30 |
| Home goods | 8–15% | Defaults work; consider 65 / 45 |
| Digital / subscription | 1–5% | Tighter: 40 / 20 |
The principle: thresholds should be set so that the bottom 5–10% of your customers (by return rate) trigger the elevated signal, not the median customer. If you’re seeing 30% of your customer base in Caution or Risk, your thresholds are too tight.
Common Patterns #
The Serial Returner #
Signature: 30+ orders, 50%+ return rate, refunds spread across many small orders.
Signals: -40 (very high rate) or -25 (high rate), often + frequency signal at -5.
Profile: Lands in Risk or Critical, typical Returns penalty -30 to -45.
The Wardrobing Customer #
Signature: Moderate order count, 40–60% return rate, near-100% full-refund ratio. Buys expensive items, returns shortly after.
Signals: -25 (high rate) + -10 (wardrobing) = -35 from Returns.
Profile: Lands in Risk. Particularly common in apparel and electronics.
The Defective-Item Cluster #
Signature: Multiple customers with elevated return rates concentrated in a specific product or category.
Signals: Per-customer Returns signals + Category-Aware Risk signals on the same customers.
Profile: Look at the Category Abuse Stats dashboard card — if a category shows store-wide elevated returns, the issue is the product, not the customers. Don’t punish customers for legitimate defective-item returns; investigate the SKU.
The Refund-Fraud Ring #
Signature: Multiple linked accounts (same address/IP/payment), each with high return rates, coordinated refund timing.
Signals: Returns -25 to -40 per account, Linked Accounts -25 to -30, Coupons signals often present too.
Profile: Multiple Critical-tier accounts linked together. Investigate as a ring, not individuals.
False-Positive Watch List #
The Returns module is generally high-signal, but certain patterns can produce misleading scores. Watch for:
- Customers with one large refund and few orders. A single $5,000 refund on 4 orders shows a 25% rate. Check whether this is a legitimate large transaction (B2B order, custom build) before flagging.
- Customers buying in bulk to choose-and-return. Apparel customers ordering 5 sizes intending to keep one is a sales channel choice, not abuse. If your store allows this explicitly, raise the thresholds.
- Recently-recovered customers. A customer with a spike that’s normalized over later orders may still be carrying penalties — the rate is a lifetime rate. Consider manual review for borderline cases.
- Customers stuck just above 25%. The boundary is sharp. A 25.1% return rate triggers -10; 24.9% triggers 0. If borderline customers feel unfair, raise the 25% boundary via the
trustlens/score_signalsfilter.
Disabling the Module #
Disabling Returns is almost never recommended — it’s the highest-signal module. The only realistic use case is: you’ve completely rebuilt scoring around external data (CRM, dedicated fraud platform) and Returns signals are interfering with your custom logic. Even then, consider disabling only the Returns signals in your custom code via trustlens/score_signals rather than turning off the module — keeping the module on preserves the aggregate stats on the customer record, which are useful for the Dashboard and Customer Detail views regardless of scoring.
What Happens When You Disable It #
- No new refund events are recorded — aggregate counts stop updating
- No Returns signals contribute to scores
- The Returns settings sub-section is hidden
- Existing
return_rate,total_refunds, and related columns are preserved - The Dashboard’s Refund Activity chart and Top Returners list go stale (no new data)
Re-enabling resumes observation from that point — existing customers don’t get retroactive credit or penalty for refunds during the off period.
Reading the Returns Section of a Profile #
On the Customer Detail page, the Returns module’s contribution shows up in two places:
- The signal breakdown — one to three rows tagged with the
returnsmodule ID, each with its score and reason - The Return Rate trend chart — a 30-day or 90-day view of how the customer’s return rate has moved
The stats panel also shows the underlying counts (total refunds, full vs partial, total refund value) so you can verify the signal calculation by hand.
API Access #
The Returns module’s data is part of the customer record and is accessible via REST:
GET /wp-json/trustlens/v1/customers/{email_hash}
Response includes total_refunds, full_refunds, partial_refunds, total_refund_value, return_rate, and last_refund_date. See REST API Reference.