---
title: Order Pattern Analysis
description: "The Order Pattern Analysis module is TrustLens's positive-signal workhorse. While most modules look for abuse, the Orders module's primary job is to recognize loyal repeat customers and reward them with score lifts. It also catches the smaller class of order-side…"
url: "https://webstepper.io/docs/trustlens/detection-modules/order-pattern-analysis/"
updated: "2026-10-18"
category: Detection Modules
---

# Order Pattern Analysis

The Order Pattern Analysis module is TrustLens's positive-signal workhorse. While most modules look for abuse, the Orders module's primary job is to recognize loyal repeat customers and reward them with score lifts. It also catches the smaller class of order-side abuse: serial cancellations and order manipulation.

Module ID: `orders`. Default: enabled. Free tier (complete).

---

## What It Observes

The module hooks into WooCommerce order lifecycle events:

1. **Order placed** (classic or block checkout) — creates the customer record if needed, sets `first_order_date` on the first ever order, and logs an `order_created` event
2. **Order counted** — when an order reaches `completed` or `refunded`, or receives a refund, it joins the customer's counted order set exactly once: `total_orders`, `total_order_value` and `last_order_date` update, an `order_counted` event is logged, and a score recalculation is queued
3. **Order cancelled** — increments `cancelled_orders`, logs an `order_cancelled` event, and queues a recalculation

Order data is the foundational layer most other modules build on. Return rate is meaningless without order count; coupon abuse signals need order context; the per-customer dispute rate needs an order denominator. Because this live order counting lives in the Orders module, it runs only while the module is enabled.

---

## What It Signals

The module emits both positive and negative signals, but skews positive.

### Loyalty Bonuses (Positive)

The Orders module uses **clean orders** — counted orders minus refunded orders — as the basis for loyalty bonuses. This naturally discounts customers whose order count is inflated by orders they later refunded.

Mutually exclusive tiers:

| Clean Orders (total − refunds) | Score | Reason Shown on Profile |
| --- | --- | --- |
| 10+ | +15 | "10 orders without issues" |
| 5+ | +10 | "5 orders without issues" |
| 3+ | +5 | (no reason text) |
| < 3 | 0 | (no signal) |

A separate +5 fires when net customer value (total order value minus refund value) is ≥ $1,000, reflected as "High customer value: $X".

These bonuses stack with the Account Age bonus from the scoring engine. A customer with 10+ clean orders, $1,000+ net value, and 1+ year tenure gets +15 (Orders loyalty) + +5 (Orders value) + +15 (Age) = +35 cumulative positive contribution before any other signals.

### Cancellation Penalties (Negative)

Gated by an absolute count of **3+ cancelled orders**, then thresholded on cancellation rate.

| Trigger | Score | Reason Shown on Profile |
| --- | --- | --- |
| 3+ cancellations and rate ≥ 50% | -15 | "High cancellation rate: 60%" |
| 3+ cancellations and rate ≥ 30% | -10 | "Elevated cancellation rate: 35%" |
| fewer cancellations or lower rate | 0 | (no signal) |

The absolute-count gate suppresses false positives — one cancellation on three orders is a 33% rate but isn't a pattern. Cancellation patterns are subtler than refund patterns. A customer placing many orders and cancelling some is sometimes shopping (placing to lock pricing, cancelling after comparison); sometimes manipulating (cancelling after a coupon has been applied to test it, then re-ordering); occasionally abusive (creating cancelled "test" orders to game inventory or loyalty programs).

---

## What Counts as a Completed Order

The Orders module counts orders that reach the WooCommerce `completed` or `refunded` status toward `total_orders` (refunded is included because WooCommerce moves a fully refunded completed order out of `completed`). An order that receives a refund while still `processing` is counted too, so a refunded order is always part of the count. Orders in `processing`, `on-hold`, `pending`, or `cancelled` states otherwise do not count toward the loyalty bonus. Each order is counted only once, even if its status is toggled back and forth.

This means:

- A customer with 10 processing orders and 0 completed orders gets no loyalty bonus — they haven't actually transacted with you yet
- A customer's loyalty bonus can grow over time as `processing` orders move to `completed`
- Cancelled orders do not subtract from the loyalty count, but they do contribute to the cancellation rate, which is cancellations ÷ (counted orders + cancellations)

---

## Settings

| Setting | Default | Description |
| --- | --- | --- |
| **Module enabled** | On | Master toggle |

The Orders module has no tunable thresholds — the loyalty tiers and cancellation rates are calibrated against typical e-commerce data and not exposed as settings. Customization is via the `trustlens/score_signals` filter for sites that need different behavior.

---

## Common Patterns

### The Loyal Customer

**Signature:** 10+ completed orders, near-zero cancellations, low refund rate.

**Signals:** Orders +15 (10+ clean orders), often + Orders +5 (high net value), Chargebacks "No dispute history" +10, Account Age +5 to +15.

**Profile:** Trusted to VIP segment. These are the customers you want to allowlist proactively.

### The High-Volume B2B Customer

**Signature:** 30+ orders, large order values, occasional cancellations from order edits.

**Signals:** Orders +15, possibly mild cancellation signal.

**Profile:** Usually Trusted. If the cancellation rate edges toward 30% (with 3+ cancellations), consider allowlisting to suppress the false positive.

### The Order Manipulator

**Signature:** Many orders, high cancellation rate, often correlated with coupon usage.

**Signals:** Orders cancellation signal -10 or -15, Coupons signals -10 to -25, sometimes Linked Accounts.

**Profile:** Caution to Risk. Pattern: place order with coupon, cancel, place again to test different coupons, etc.

### The Slow-Burner

**Signature:** 3–4 clean orders, no cancellations, low refund rate.

**Signals:** Orders +5 (3+ clean orders tier).

**Profile:** Normal to Trusted depending on Returns and Age. The 3-order tier exists so customers don't need 5 clean orders to start accumulating recognition.

---

## Interaction with Other Modules

The Orders module is the denominator for many other module calculations:

- **Returns module** uses `total_orders` to compute return rate
- **Coupons module** uses order count to detect first-order coupons and the coupon usage rate
- **Chargebacks module** uses order count for the per-customer dispute rate (disputes / orders) and its 10-order clean-history bonus
- **The Full-confidence Order Threshold** is measured in counted orders

This is why disabling the Orders module has knock-on effects — see below.

---

## False-Positive Watch List

- **Restocking B2B customers.** A wholesale buyer placing then cancelling orders to update quantities can trip the cancellation signal. Allowlist them — their behavior is operational, not abusive.
- **Customers who use cart-saver tools.** Some external apps create then immediately cancel orders. If your store integrates such tools, suppress the cancellation signal on those orders via a custom filter.
- **Recent migrators.** A customer migrated from another platform with 10 historical orders may not be marked complete in WooCommerce — they look like 0-order customers until Historical Sync correctly maps statuses.

---

## Disabling the Module

Disabling Orders is unusual but valid for stores that:

- Use the loyalty bonus from an external loyalty program and want to avoid double-counting
- Want only abuse-side signals contributing to scores, with no positive lift from order count

When disabled, no Orders signals fire *and* the module stops counting new orders — `total_orders`, `total_order_value`, `last_order_date` and `cancelled_orders` stop updating, so return rates, coupon usage rates and the Full-confidence Order Threshold all work from stale counts. If you only want to drop the positive lift, prefer removing the `orders` signal with the `trustlens/score_signals` filter and keep the module on. Running Historical Sync rebuilds the counts from your WooCommerce orders.

---

## Reading the Orders Section of a Profile

On the Customer Detail page:

- **Signal breakdown** shows one Orders signal combining the loyalty tier, the net-value bonus and any cancellation penalty
- **Stat tiles** show orders and cancelled orders
- **Event timeline** shows each order placed, order counted and order cancelled event with the order ID and amount

The event timeline is the easiest way to spot patterns — clusters of cancellations, sudden spikes in order velocity, or long quiet periods between orders all show up visually.
