A single failed payment is normal. Cards expire, banks decline, a customer types a digit wrong. Stripe retries, the customer updates the card, and nobody needs to know. The problem is not the failed payment. The problem is the pattern you only see in the monthly report.

There are four common reasons a payment fails. The card is declined by the issuer, usually for insufficient funds or a fraud rule. The card has expired or been replaced. The payment method needs authentication the customer never completed. Or something on your side changed: a checkout deploy, a webhook that stopped answering, a price that no longer maps to a plan.

The first three are a customer problem with a customer fix. The fourth is your problem, and it looks identical to the first three when you read the failures one at a time. That is the trap. Per-event alerts cannot tell you that today's twelve failures share a cause, because each one arrived alone.

The signal that matters is rate against your own normal. If you usually see two failed payments an hour and you have seen eleven since 09:40, something changed at 09:40. What else changed at 09:40? If a deploy went out at 09:31, you have your answer before you have opened a single Stripe record.

This is what correlation means in practice. It is not machine learning. It is joining events on the identifiers they share, inside a time window, and refusing to say more than the evidence supports. A failed deploy, a build error and a payment spike that share a commit are one incident. Three that share nothing are three separate things, and the honest answer is to say so.

So the setup you want is boring. Stripe sends its events to one place. Your deploys send theirs to the same place. A rule says: warn me when failed payments pass a threshold in an hour, and tell me what else happened in that hour. Then the rule is replayed over your last month before it goes live, so you know it would have fired twice, not two hundred times.

Recovery is its own topic, and Stripe's Smart Retries handle more of it than most teams realise. But recovery only helps with the customer-side failures. For the one that was your deploy, the only recovery is finding out fast. That is the alert worth building.

InternalStatus does the joining and the replaying. Paste a Stripe signing secret, write the sentence, and see when it would have fired last month before you arm it.