FlowAlert
All posts
Stripe Push Notifications: Know the Moment You Get Paid
stripepaymentspush-notificationswebhooks

Stripe Push Notifications: Know the Moment You Get Paid

Get an instant push notification for every Stripe payment, failed charge, or dispute — paste one webhook URL into Stripe and you're done. No code required (but the API route is still there when you want custom logic).

FlowAlert TeamMay 12, 2026 6 min read

Stripe Push Notifications: Know the Moment You Get Paid

There's something deeply satisfying about getting a push notification the moment revenue hits your Stripe account. But Stripe's own email notifications are delayed, and the Stripe app's alerts are limited to what Stripe decides to expose.

FlowAlert connects to Stripe with a native webhook — you paste a FlowAlert URL into Stripe, paste Stripe's signing secret into FlowAlert, and every payment event that matters lands on your phone, signature-verified, routed to the right person, with acknowledgement and escalation when it's something like a dispute.

That's the whole setup. If you'd rather write your own handler — custom event keys, your own filtering, an MRR bot — the API route still works, and it's covered at the end.


The no-code way: FlowAlert's native Stripe webhook

Step 1: Create a Stripe source in FlowAlert

In your FlowAlert dashboard go to Setup → Integrations, click Connect, choose Stripe, and give it a name. FlowAlert generates a unique receiver URL:

https://api.flowalert.io/v1/hooks/stripe/whk_xxxxxxxxxxxxxxxx

Copy it — you'll paste it into Stripe next.

Step 2: Add the webhook endpoint in Stripe

  1. In the Stripe Dashboard, go to Developers → Webhooks
  2. Click Add endpoint
  3. Paste your FlowAlert receiver URL as the Endpoint URL
  4. Under Select events, add the events you want to route (table below)
  5. Click Add endpoint

One thing worth knowing: Stripe only delivers the event types the endpoint is subscribed to. That includes test events — if you plan to use the dashboard's Send test webhook or stripe trigger, add the event you'll test with to the selected events, or nothing will arrive.

Step 3: Paste the signing secret back into FlowAlert

On the endpoint's page, Stripe shows a Signing secret starting with whsec_. Click Reveal, copy it, and paste it into your Stripe source under Setup → Integrations, then Save.

The signing secret is how FlowAlert proves each request genuinely came from Stripe. Until it's set, the source won't accept events.

That's it — three pastes, no server, no code.


What arrives, out of the box

FlowAlert understands these Stripe events and maps them to routable keys:

Stripe eventFlowAlert event keyPriority
invoice.payment_failedstripe.payment_failedHIGH
charge.failedstripe.payment_failedHIGH
payment_intent.payment_failedstripe.payment_failedHIGH
charge.dispute.createdstripe.dispute_createdURGENT
checkout.session.completedstripe.payment_succeededNORMAL
payment_intent.succeededstripe.payment_succeededNORMAL
invoice.payment_succeededstripe.invoice_paidNORMAL
customer.subscription.createdstripe.subscription_createdNORMAL
customer.subscription.trial_will_endstripe.subscription_trial_endingHIGH
customer.subscription.deletedstripe.subscription_canceledNORMAL

Other event types are accepted and acknowledged (Stripe shows a ✓) but won't create an alert.

Pick one event per payment flow. Several Stripe events deliberately map to the same FlowAlert key — subscribe to the one that matches how you take payments, or a single payment fires multiple alerts:

  • Successful paymentscheckout.session.completed if you use Stripe Checkout, or payment_intent.succeeded if you use the Payment Element / Payment Intents API.
  • Failed paymentsinvoice.payment_failed for Billing/subscriptions, or charge.failed / payment_intent.payment_failed for one-off charges.
  • Subscription renewals are their own thing: invoice.payment_succeededstripe.invoice_paid.

Every alert carries a small set of normalized fields you can use in routing conditions: data.amount (major units — 49.99, not cents), data.currency (USD), data.customer_email, and data.reason (the human-readable failure or dispute reason). Stripe retries failed deliveries, and FlowAlert de-duplicates by Stripe's event id — a redelivered event never becomes a second alert.


Route the events to the right people

In Setup → Routing Rules, create a rule per key you care about:

Event keyRecipientPriorityRequires Ack
stripe.payment_succeededFounderNORMALNo
stripe.subscription_createdFounder + SalesNORMALNo
stripe.payment_failedBilling / SupportHIGHYes
stripe.subscription_canceledFounder + CSNORMALNo
stripe.dispute_createdFinance leadURGENTYes

For rules with acknowledgement required, FlowAlert keeps alerting until someone taps Acknowledge — and escalates to the next person if they don't. Disputes have a response deadline; this is exactly what escalation is for.

You can also add conditions — for example, route disputes over $500 to a different person with a condition on data.amount.


Test it

On the endpoint page in Stripe, use Send test webhook (the default test is payment_intent.succeeded — make sure it's one of your selected events), then check Dashboard → Alerts in FlowAlert. Once a routing rule exists for the key, the same event lands on a phone in a couple of seconds.


The custom way: your own webhook handler

The native integration covers the common events with sensible keys. Build your own handler instead when you want your own event keys, custom filtering, or alerts Stripe doesn't emit directly (like a daily MRR report).

You'll need a public HTTPS endpoint that verifies Stripe's signature and forwards what you care about to FlowAlert's REST API:

1const express = require('express'); 2const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY); 3 4const app = express(); 5 6async function flowalert(event, title, body, priority = 'NORMAL', data = {}) { 7 await fetch('https://api.flowalert.io/v1/events', { 8 method: 'POST', 9 headers: { 10 'Content-Type': 'application/json', 11 'X-Api-Key': process.env.FLOWALERT_API_KEY, 12 }, 13 body: JSON.stringify({ event, title, body, priority, data }), 14 }); 15} 16 17app.post( 18 '/webhook/stripe', 19 express.raw({ type: 'application/json' }), 20 async (req, res) => { 21 let event; 22 try { 23 event = stripe.webhooks.constructEvent( 24 req.body, 25 req.headers['stripe-signature'], 26 process.env.STRIPE_WEBHOOK_SECRET 27 ); 28 } catch (err) { 29 return res.status(400).send('Webhook signature verification failed'); 30 } 31 32 const obj = event.data.object; 33 if (event.type === 'payment_intent.succeeded') { 34 const amount = (obj.amount / 100).toFixed(2); 35 await flowalert( 36 'billing.payment_succeeded', // your key — name it whatever you route on 37 `💰 Payment — ${obj.currency.toUpperCase()} ${amount}`, 38 `Received from ${obj.receipt_email ?? 'unknown customer'}`, 39 'HIGH', 40 { paymentIntentId: obj.id } 41 ); 42 } 43 res.json({ received: true }); 44 } 45); 46 47app.listen(3000);

The event keys here are yours to define — the key you send just has to match the key on your routing rule. During development, forward webhooks to localhost with stripe listen --forward-to localhost:3000/webhook/stripe and fire test events with stripe trigger payment_intent.succeeded.

Bonus: a daily MRR push

Alerts don't have to come from webhooks — anything that can call the API can push. A scheduled job that sums your active subscriptions and sends one LOW-priority note at 9am:

1async function sendMrrReport() { 2 const subscriptions = await stripe.subscriptions.list({ status: 'active', limit: 100 }); 3 const mrr = subscriptions.data.reduce((sum, sub) => { 4 return sum + sub.items.data.reduce((s, item) => { 5 const amount = item.price.unit_amount ?? 0; 6 const interval = item.price.recurring?.interval; 7 return s + (interval === 'year' ? Math.round(amount / 12) : amount); 8 }, 0); 9 }, 0); 10 11 await flowalert('stripe.mrr_daily', `📊 Daily MRR Report`, `Current MRR: $${(mrr / 100).toFixed(0)}`, 'LOW'); 12}

Summary

For payment alerts, the native integration is the right default: three pastes, signature-verified, de-duplicated, and every failed charge or dispute reaches a person who has to acknowledge it. Reach for a custom handler only when you want your own keys or logic on top.

Get started with FlowAlert →

Get alerts where you’ll actually see them.

Everything in these guides works on the free plan — connect a source, add a routing rule, and the right person’s phone knows in under two minutes.

No card required · Free plan forever · 1,000 events/month