How to get a phone alert when a Stripe payment fails

Stripe emails your customer when their card fails, not you. Which Stripe events to watch, how to verify them, and how to get invoice.payment_failed on your iPhone in two steps.

When a card payment fails, Stripe can email your customer, retry the charge on a schedule and mark the invoice past due. All of that happens to the customer. To hear about it yourself while the payment can still be saved, you need Stripe's webhooks: they are where Stripe announces a failed payment the moment it happens.

This guide covers which events to watch, three ways to get them to your phone, and how to test it.

The events worth hearing about

Stripe sends hundreds of event types. A handful are money leaving or about to leave. These are the ones Acciti's Stripe connector knows, with the priority each arrives at. You choose which to turn on, and you can change any priority.

EventWhat happenedArrives as
invoice.payment_failedA customer's payment failed.High
customer.subscription.deletedA subscription was cancelled.Normal
invoice.paidAn invoice was paid.Quiet
checkout.session.completedA checkout completed.Quiet
charge.dispute.createdA charge was disputed.High

invoice.payment_failed is the one to start with. It fires each time a subscription invoice can't be charged, including each of Stripe's retries, so a customer whose card expired produces one event per attempt. Each attempt is another chance to get the card updated.

charge.dispute.created deserves the same priority. A dispute comes with a deadline for your evidence, and every day before you notice it is a day lost.

The quiet events are for people who like a note when money comes in. They arrive as a banner with no sound, so a good day doesn't sound like an outage.

Three ways to get them to your phone

An automation service

Zapier and IFTTT can watch Stripe and send a text or a push. Two costs come with that: the service now holds access to your Stripe account, and depending on the plan it may check for new events on a timer rather than as they happen.

Your own webhook endpoint

You can write an endpoint that receives Stripe's events and forwards them. Stripe signs every event with the endpoint's signing secret, and the endpoint has to check that signature, or anyone who finds the URL can send you a fake payment failure. Stripe's libraries do the check:

Node, with the stripe package
const event = stripe.webhooks.constructEvent(  rawBody,                           // the bytes, not parsed JSON  request.headers["stripe-signature"],  process.env.STRIPE_WEBHOOK_SECRET,) if (event.type === "invoice.payment_failed") {  // forward it to your phone}

Then the endpoint needs hosting, logs and someone to notice when it is the thing that broke. That is a lot of software to own for one alert.

A connector

Acciti's Stripe connector is that endpoint, already written. It checks Stripe's signature on every event, turns the events you picked into notifications, and refuses anything that fails the check.

Setting up the connector

  1. In Acciti, add a Stripe connector and copy its ingest URL.
  2. In the Stripe Dashboard, open Developers, then Webhooks, and add an endpoint with that URL. Select the events from the table above.
  3. Copy the endpoint's signing secret, which starts with whsec_, and paste it back into the connector.

Connectors are on the Solo plan and up. Compare plans

Test it before a real card fails

Add the same endpoint in Stripe's test mode, with its own signing secret on a second connector, and fire the event from the Stripe CLI:

Stripe CLI
stripe trigger invoice.payment_failed

The CLI creates the test objects that produce a real invoice.payment_failed in test mode, and Stripe delivers it to every test-mode endpoint listening for it. Your phone shows it:

09:41

Payment failed

now

[email protected]: 49.90 USD.

Stripe · chime

Dispute opened

now

49.90 USD disputed.

Stripe · chime

A failed payment and a new dispute, as the Stripe connector's rules write them.

Deciding what should wake you

A failed payment at 3 a.m. is rarely something you can fix at 3 a.m. High priority makes a sound and gets through Focus, but it doesn't repeat. Keep Emergency, which repeats until someone acknowledges it, for things that lose money every minute, such as checkout failing for everyone.

App Store renewals and refunds work the same way through App Store Server Notifications, and the connectors page lists every service Acciti verifies.

Hear the next failed payment.

Add a Stripe connector, paste its URL into Stripe, and invoice.payment_failed rings your phone.