At a glance
Triggers when the trailing 1-hour decline rate exceeds the 24-hour rolling baseline by more than 2 standard deviations. The fastest detection of a payment integration regression, an issuer-side outage, or a fraud-attack burst. Pause if it’s an integration-side issue; tune Radar if it’s a fraud-attack spike; do nothing if it’s an issuer-side blip that resolves on its own.
Calculation
Calculated automatically from your Stripe data. See the At a glance summary above for what the metric tracks and the worked example below for a typical reading.Worked example
A US DTC subscription brand on Shopify + Stripe, monthly volume ~$840,000 across ~6,800 charges. Average decline rate is 4.8%; baseline 24-hour standard deviation is 1.2%. Hour-by-hour decline rate during a Sunday-evening incident on 11 Apr 26:
Decline-reason breakdown during the spike (hour 20:00 to 21:00):
What’s interesting:
- The alert fired at 20:00 on a 3.3σ deviation, escalated at 21:00 to 6.3σ. Two-hour total: 64 declined charges, ~$3,200 of declined revenue.
- The cause was a card-testing fraud attack. The
card_velocity_exceededdeclines are the smoking gun, the same card being tried multiple times in rapid succession is a classic card-testing pattern (a fraudster testing stolen card numbers against a low-value endpoint to verify which are still valid). Stripe’s velocity rules caught most of them; the spike represents what got close to (or through) Radar’s first line. - The right response was Radar tuning, not pausing payments. The merchant on-call: (a) confirmed via Stripe Dashboard that legitimate charges were still succeeding (4.8% baseline meant 95% of charges still worked normally), (b) added a Radar rule blocking small-value charges (<$5) from new customers, (c) added a 5-minute IP-throttle rule for repeat-card attempts. Total response time: 12 minutes. The spike resolved itself by hour 22:00 as the attacker moved on.
- The 1.1σ reading at hour 22:00 didn’t trigger. This is the right behaviour, the alert is meant to surface real anomalies, not chase noise. The spike was over by then.
- A worse outcome would have been pausing payments unnecessarily. If the on-call had assumed it was an integration regression and paused legitimate charges for the 90 minutes until the alert cleared, the merchant would have lost an estimated $14,400 of legitimate revenue while attempting to “fix” something that was already self-resolving. The card pairs with Decline Reasons precisely so the on-call can identify the spike type before acting.
Sibling cards merchants should reference together
Reconciling against the vendor’s own dashboard
Where to look in Stripe Dashboard: Payments → Overview for the live decline rate. The default view shows the trailing 24 hours; toggle to “Last hour” for the matching window. Reports → Decline analysis for per-reason decompositions. Useful for diagnosing what drove the spike after it has fired. Radar → Reviews for live fraud-blocking decisions; useful for confirming a spike was Radar-driven (fraud attack) vs issuer-driven. For real-time monitoring, set up Stripe Workbench → Custom dashboards with a 1-hour decline-rate view; this matches the alert’s input. Why our number may legitimately differ from Stripe Dashboard:
Cross-connector reconciliation:
The most useful diagnostic question after a spike: “is this issuer-side, integration-side, or fraud-side?” Top Declining Issuers (issuer-side), Decline Reasons (integration-side: 100% generic_decline = your code; mix = elsewhere), and
card_velocity_exceeded count (fraud-side) answer it in 2 to 3 minutes.
Known limitations / merchant FAQs
The alert fired. What’s the playbook? Three steps in order, total time 5 to 10 minutes. (1) Identify the spike type by checking Decline Reasons. 100%generic_decline or 100% one reason from one issuer = integration regression or issuer outage; mixed reasons with card_velocity_exceeded = fraud attack; mixed reasons with no clear pattern = noise / false positive. (2) Match the response to the type. Integration regression: pause and rollback. Issuer outage: do nothing, wait. Fraud attack: tune Radar with a velocity rule. Noise: do nothing. (3) Verify legitimate charges are still succeeding by checking Auth Rate; if the auth rate is still close to baseline, you’re not in a global outage.
False positives, what causes them?
Three common patterns. (a) Low-volume hour bucket, an hour with only 30 charges and 4 declines is statistically a 13% rate, which trips the alert against a 5% baseline despite being only 4 absolute declines. (b) Batch retry timing, subscription renewal batches that fire at the same time each day produce predictable decline-rate spikes; the baseline should adapt within 24 to 48 hours but the first time a new batch runs it can fire. (c) Promotional spike, a viral campaign brings new shoppers with higher decline rates (new customers fail more often than repeat); the spike is real but isn’t an issue.
Should I auto-pause Stripe when this fires?
Almost never. Pausing Stripe means refusing legitimate charges, which is far more expensive than absorbing the few minutes of additional declines until the spike type is identified. The right pattern is: alert → human triage → action. Auto-pause logic should consider absolute decline count AND multiple confirming signals (decline rate spike + auth rate drop + checkout abandon spike); pause only when all three fire simultaneously.
The alert keeps firing on the same overnight hour. Is it broken?
Probably not, but it’s noise. Subscription-heavy merchants often have predictable overnight retry batches that produce decline-rate spikes; the baseline should adapt but if the pattern is sharp and recurring it can fire repeatedly. Two fixes: (a) tune the alert window to exclude the known-noisy hour from baseline calculation, or (b) raise the threshold to >3σ to reduce false fires. The pattern is real; the alert just isn’t actionable.
My alert fired but Stripe Dashboard shows the spike already resolved by the time I logged in. Did I miss anything?
No. The alert is meant to surface anomalies fast; many anomalies self-resolve within 30 to 60 minutes (issuer-side blips, ephemeral fraud attacks, batch processing waves). The right response is acknowledgement and review, not always action. The card alongside the alert lets you confirm what happened post-mortem.
Why is this rate-based and not absolute-count-based?
Different merchants have different volumes; an absolute-count alert (e.g. “10 declines in an hour”) fails for high-volume merchants (10 declines is a rounding error) and over-fires for low-volume merchants (10 declines is a real signal). A rate threshold normalises across volumes; a sigma-based threshold further normalises across each merchant’s baseline noise. The alert is meant to find genuine anomalies, not arbitrary thresholds.
Stripe Radar already blocks high-risk transactions. Why am I getting decline spikes from fraud attacks?
Radar’s blocking decisions are pre-charge (the charge never reaches the issuer); these don’t show up as declines in this card. The card surfaces post-charge declines, the issuer rejected the charge for fraud / velocity reasons. A fraud-attack-driven decline spike means the attacker’s cards are reaching Stripe but failing at the issuer side. The fix is tuning Radar to block earlier (raise the block threshold from “high” to “elevated” risk), at the cost of slightly higher false-positive rate on legitimate transactions.
My subscription billing batch fires at midnight UTC. The alert always fires at 00:30. What do I do?
This is the canonical “predictable noise” case. Two fixes. (a) Configure the alert to exclude the 00:00 to 01:00 window from the baseline (so the baseline reflects normal hours only); the spike will still be visible in the dashboard but won’t trip the alert. (b) Run the subscription batch with built-in retry-spread (e.g. randomly distribute over 4 hours) which smooths the decline-rate spike. Stripe Smart Retries does this automatically if enabled.
Why does the alert use a 24-hour baseline and not a longer one?
Decline rate has strong time-of-day patterns (lower during business hours, higher at night when batch retries fire). A 24-hour rolling baseline naturally adapts to these patterns; longer baselines (7 days, 30 days) average out the time-of-day signal and produce more false-positives at predictable peak hours. The 24-hour window is a balance between adaptiveness and stability.