Velocity Thresholds
6 min read
- View as Markdown Open this page as plain Markdown (opens in a new tab)
- Open in ChatGPT Ask questions about this page (opens in a new tab)
- Open in Claude Ask questions about this page (opens in a new tab)
- Open in Google AI Studio Ask questions about this page (Google account required) (opens in a new tab)
Velocity thresholds are the numbers TrustLens uses to decide when a stream of declines from a single device fingerprint has crossed the line from “legitimate customer with bad cards” into “automated card-testing attack.” This page explains how the thresholds work, why the defaults are what they are, how long a device is held once it trips them, and how to tune them for your store.
The Velocity Windows #
The base Card-Testing Defense module counts each device fingerprint’s activity over two rolling windows, with three thresholds:
| Counter | Default | Designed to Catch |
|---|---|---|
| Declines in 60 seconds, per fingerprint | 3 | Bursts of failed authorization attempts — the classic card-testing signature |
| Submissions in 60 seconds, per fingerprint | 10 | High overall checkout-submission volume from one fingerprint, even when many succeed |
| Declines in 1 hour, per fingerprint | 8 | Slow attacks the 60-second rules miss: a bot that paces itself, or one that waits out each lockout and starts over |
Crossing any one threshold locks the offending fingerprint out of checkout (see The Lockout Ladder below). The 60-second counters catch bursts; the hourly count outlives a lockout, so a repeat offender stays caught instead of getting a clean slate every time a lockout expires.
Attack-scale protection — catching attacks that spread across many fingerprints — ships as Pro auto-escalation, which watches for distinct fingerprints tripping detection within a 10-minute window and triggers Panic Freeze. See Auto-Escalation (Pro).
How Counts Are Accumulated #
Counters are keyed by device fingerprint, not by email. Each checkout attempt carries two identities: the browser fingerprint computed by the checkout script, and a server-side fingerprint built from the IP address, User-Agent, and Accept-Language headers. See Fingerprinting.
- Every checkout submission — classic checkout, Blocks / Store API checkout, or the pay-for-order page — is recorded as a submission for both fingerprints. Cart actions such as adding items or applying coupons don’t count.
- Every failed payment is recorded as a decline: from the Stripe and WooPayments failure hooks, and from any gateway’s order moving to Failed.
- On each submission, TrustLens counts the browser fingerprint’s declines and submissions in the last 60 seconds and its declines in the last hour, then does the same for the server fingerprint.
- If either fingerprint has reached a threshold, that fingerprint is held and the submission is rejected with “Too many attempts. Please wait a moment before trying again.”
Counting both fingerprints means an attacker who sends a fresh browser fingerprint on every attempt still accumulates declines against the server fingerprint.
The Lockout Ladder #
Each time a fingerprint newly trips detection it earns a strike, and the lockout grows with the strike count:
| Strike | Lockout |
|---|---|
| 1st | 90 seconds |
| 2nd | 15 minutes |
| 3rd | 1 hour |
| 4th and later | 24 hours |
Strikes are counted over the event retention window (48 hours by default), so a device that trips once and then behaves becomes a first offender again once its history ages out. The first lockout stays short on purpose: a real shopper whose card declines three times in a minute trips the same rule an attacker does. The 24-hour cap means a false positive on a shared office or carrier address heals on its own; you can also release a held fingerprint immediately from the Targeted now list, which also clears its strikes.
The ladder itself isn’t a setting. Developers can change the lockout length with the trustlens/card_testing/lockout_seconds filter, which receives the ladder’s value and the strike number.
Default Threshold Rationale #
The default 3-decline / 60-second threshold was chosen against observed real-world patterns:
- Legitimate customer: 1–2 attempts to enter a card correctly, finishing within 30 seconds. Under the threshold.
- Worst-case slow customer: 2 attempts over a minute (entering wrong card, then correct one). Still under threshold.
- Burst-attack bot: many declines per second. Triggers the threshold within the first second.
- Paced bot: stays under 3 declines a minute but keeps going. Reaches 8 declines within the hour.
The 3-decline default is tight — it catches attacks fast at the cost of occasional false positives on customers who genuinely fumble cards three times. The VIP bypass mitigates this for established customers; the allowlists (Pro) mitigate it for known-good devices.
When to Tighten Thresholds #
Lower the defaults if:
- You’ve observed an attack that slipped through at the default settings
- Your store has a very stable customer base with predictable checkout behavior
- Your payment gateway is reliable (declines are signal, not noise)
Reasonable tightened values:
| Setting | Default | Aggressive |
|---|---|---|
| Declines in 60s | 3 | 2 |
| Submissions in 60s | 10 | 6 |
| Declines in 1 hour | 8 | 5 |
When to Loosen Thresholds #
Raise the defaults if:
- Your gateway is unreliable and produces legitimate decline noise
- You have high-frequency legitimate retry behavior (saved cards, B2B with multiple card attempts)
- You’ve observed false-positive lockouts on real customers
Reasonable loosened values:
| Setting | Default | Loose |
|---|---|---|
| Declines in 60s | 3 | 5 |
| Submissions in 60s | 10 | 15 |
| Declines in 1 hour | 8 | 12 |
Configuring #
Settings live in the Detection Settings card at TrustLens → Card-Testing Defense. Changes take effect on the next checkout submission after you save — no cache to flush, no scheduled job to run.
| Setting | Range | Description |
|---|---|---|
| Declines in 60s | 1–100 (default 3) | Declines per fingerprint within 60 seconds that trigger a lockout |
| Submissions in 60s | 1–200 (default 10) | Checkout submissions per fingerprint within 60 seconds that trigger a lockout |
| Declines in 1 hour | 1–500 (default 8) | Declines per fingerprint within one hour that trigger a lockout |
| Event retention | 24–168 hours (default 48) | How long velocity events are kept; also the window over which strikes count |
The lockout durations aren’t settings — they follow the ladder above. What you tune here is how many declines or submissions it takes to trip a lockout.
Per-Fingerprint Overrides (Pro) #
Pro can apply different thresholds to a specific fingerprint. Useful when you have:
- A specific known device that legitimately produces high velocity (a test rig, an integration partner’s server)
- A device you want to enforce more strictly than the global default
There is no screen for overrides in this version. They are read from the trustlens_card_testing_fp_overrides option — a map of fingerprint hash to threshold values (declines_60s, submissions_60s, declines_1h) — which a developer can set, for example with WP-CLI. To exempt a device entirely, use the fingerprint allowlist on the Card-Testing Defense page instead.
Measuring Effectiveness #
After tuning, monitor:
- Card-Testing Defense page — 24-hour declines, submissions, decline rate, held fingerprints, and the Targeted now list with each device’s strike count
- WordPress Dashboard widget — current state and the last 24 hours’ declined payment attempts
- Customer complaints — false-positive lockouts produce complaints about “Too many attempts” on cards that work elsewhere
- Pro 24-hour intelligence — hourly decline timeline; spikes indicate attacks slipping through; flatlines indicate stable defense
If you tune thresholds, give the change at least a week before re-evaluating — attack patterns aren’t daily.
Updated on October 18, 2026