Account Age Loyalty Bonus
6 min read
The account-age bonus is a small positive contribution to the trust score that rewards customers who’ve been ordering from your store for a long time. It’s not strictly a module signal — it’s computed by the scoring engine itself after module signals are collected — but it appears in the signal breakdown like any other contribution. This guide explains exactly how the bonus works, why it exists, and how it interacts with the rest of the scoring model.
The Three Tiers #
The bonus is stepped, not continuous. There are three tiers, with the boundaries measured from the customer’s first order date:
| Tenure | Bonus | Reason Text Shown on Profile |
|---|---|---|
| 1+ year (365 days or more) | +15 | Long-term customer (1+ year) |
| 6+ months (180–364 days) | +10 | Established customer (6+ months) |
| 3+ months (90–179 days) | +5 | Regular customer (3+ months) |
| < 3 months (under 90 days) | 0 | (no signal recorded) |
Tiers are mutually exclusive — only the highest tier the customer qualifies for is applied. A customer who has been a customer for 18 months gets +15, not +5 + +10 + +15.
How Tenure Is Measured #
The clock starts at the date of the customer’s first completed WooCommerce order, not their WordPress account creation date. This means:
- Guest checkouts count — the first guest order on the email establishes tenure
- WordPress accounts created but never used to place an order do not earn a bonus
- If a customer’s first order was 8 months ago but they only just placed their second order today, they still get the +10 bonus — the bonus reflects relationship tenure, not order frequency
The exact first-order date is stored in the customer’s first_order_date column, populated during Historical Sync or on the customer’s first scored order after activation.
Why It’s Tiered, Not Continuous #
A continuous bonus — say, +0.04 points per day of tenure — would produce smoother score trajectories but introduce noise:
- Scores would change daily for every customer, just from the clock ticking
- The signal breakdown would never be a clean integer, undermining the auditability of the calculation
- Action Scheduler would need to recompute every customer every day, which scales poorly
The tiered design produces three notable “graduation” events per customer over the first year, each of which:
- Is a meaningful behavioral milestone you might want to act on
- Shows up clearly on the score trend chart as a step up
- Fires the
trustlens/segment_changedaction if it crosses a segment boundary
So a customer who’s been quietly Trusted for months can be promoted to VIP automatically when their 1-year anniversary lands — and Pro automation rules can trigger on that event.
When the Bonus Is Applied #
The bonus is recomputed every time the trust score is recalculated. Since recalculations are event-driven (triggered by new orders, refunds, disputes, etc.), the bonus tier graduation doesn’t trigger a recalc on its own — there’s no daily cron checking who just crossed 90 days.
In practice this rarely matters because active customers place orders regularly enough that their score is recalculated and the new tier is picked up. For customers who are completely dormant, the bonus tier may lag behind their actual tenure until they place another order. This is by design — dormant customers don’t need their score updated.
If you do want the bonus tier reflected immediately (e.g. to set up a “5-year anniversary VIP” automation), you can:
- Use the Recalculate button on the customer detail page
- Bulk-recalculate from the Customers list
- Trigger recalculation via REST API:
POST /wp-json/trustlens/v1/customers/{hash}/recalculate
Interaction with the Allowlist #
The allowlist short-circuits scoring entirely — allowlisted customers get exactly 100 and no module signals are computed. The account-age bonus is therefore not applied to allowlisted customers; it doesn’t need to be, since they’re already at the maximum score.
If you remove a customer from the allowlist, the next recalculation includes the age bonus normally.
Interaction with Minimum Orders #
If a customer is below the minimum-orders threshold (default 3), scoring short-circuits to 50 and no module signals are computed. The age bonus is not applied in this case either — even if the customer’s first order was 18 months ago. Once they cross the minimum-orders threshold, the next recalculation includes both module signals and the age bonus.
This means a customer who placed one order 14 months ago and just placed a second order today will still not get the age bonus until they reach 3 orders. The tradeoff: we trust tenure more once the customer has shown they’re a repeat buyer.
Capping Behavior #
The age bonus is a positive contribution and adds directly to the score. If a customer’s score before the bonus is 92 (already VIP), adding +15 would push them to 107, but the final clamp at 100 caps the displayed score. The internal arithmetic still includes the bonus — it’s just that the display can’t exceed 100.
Practically: the bonus is most impactful at the segment boundaries (lifting a 65 to 75 = Normal → Trusted; lifting an 85 to 100 = Trusted → VIP). At the extremes (very low or very high pre-bonus scores), the bonus has less proportional effect.
Worked Examples #
Example 1: New customer reaches 3 months #
- Tenure: 92 days
- Pre-bonus score: 55 (1 refund, +5 from 4 orders)
- Bonus: +5 (3+ months)
- Final score: 60 (Normal)
Example 2: Established customer reaches 6 months #
- Tenure: 182 days
- Pre-bonus score: 68 (8 clean orders, +5 from Orders module, +10 from Returns)
- Bonus: +10 (6+ months)
- Final score: 78 (Trusted)
Example 3: Long-tenured customer reaches 1 year #
- Tenure: 367 days
- Pre-bonus score: 78 (clean record, multiple positive signals)
- Bonus: +15 (1+ year)
- Final score: 93 (VIP) — automatic promotion on the anniversary
Example 4: Bonus offsetting negative signals #
- Tenure: 2 years
- Pre-bonus score: 35 (recent refund spike, -25 from high return rate)
- Bonus: +15 (1+ year)
- Final score: 50 (Normal) — the tenure cushions the recent issue but doesn’t erase it
Example 4 is important. Long tenure does not insulate a customer from negative signals — it raises the floor. A long-tenured customer with a recent abuse pattern still drops segments; they just drop one tier less than an equivalent new customer would.
Customizing the Bonus #
The bonus tiers are hard-coded in the scoring engine and not exposed as settings. If you need to customize them (e.g. add a 2-year tier, or move the 6-month threshold), use the trustlens/score_signals filter to modify the account_age signal after it’s been added:
add_filter( 'trustlens/score_signals', function( $signals, $email_hash ) {
$customer = wstl_get_customer( $email_hash );
if ( ! $customer || empty( $customer->first_order_date ) ) {
return $signals;
}
$days = ( time() - strtotime( $customer->first_order_date ) ) / DAY_IN_SECONDS;
// Remove the built-in account_age signal
$signals = array_values( array_filter( $signals, function( $s ) {
return $s['module'] !== 'account_age';
} ) );
// Add custom tiers
if ( $days >= 730 ) { // 2 years
$signals[] = array(
'module' => 'account_age',
'score' => 20,
'reason' => 'Veteran customer (2+ years)',
);
} elseif ( $days >= 365 ) {
$signals[] = array(
'module' => 'account_age',
'score' => 15,
'reason' => 'Long-term customer (1+ year)',
);
}
// ... etc
return $signals;
}, 20, 2 );
The filter runs after the built-in bonus is computed, so removing the built-in signal first is what gives custom code full control.
Why the Maximum Is +15 #
The cap is deliberate. Positive signals across the entire scoring engine are bounded; only negative signals stack arbitrarily. The maximum theoretical positive sum across all modules and the age bonus is roughly +50:
- Returns clean-history bonus: +10
- Orders 20+ loyalty bonus: +15
- Chargebacks clean-history bonus: +10
- Coupons clean-history bonus: +5
- Account age 1+ year: +15
That puts the ceiling for an organic VIP at 50 (base) + 50 (positives) = 100. Without the age bonus, the ceiling would be 85 — meaning no customer could ever reach VIP organically without allowlisting. The +15 cap is what makes the top tier accessible to long-tenured customers who haven’t been allowlisted.
Raising the cap (say, to +30) would push more customers into VIP and dilute the segment’s meaning. Lowering it would make VIP effectively allowlist-only. +15 is the value that produces a meaningful “earned VIP” tier without flooding it.
Auditing the Bonus on a Customer #
To verify the bonus on any customer:
- Open their customer detail page
- Look at the first order date field
- Calculate days between then and now
- Match against the tier table — you should see the corresponding signal in the breakdown
If the tenure looks right but the bonus signal isn’t showing, the most common causes are:
- Customer hasn’t been recalculated since the tier graduation — click Recalculate
- Customer is allowlisted (short-circuits)
- Customer is below the minimum-orders threshold (short-circuits)
- A custom filter is removing or modifying the signal
The first-order date is set when the customer’s first completed order is recorded. If their first order is in pending or on-hold status, the date won’t be set yet.