Failed Stripe payments on self-hosted Gotify

Failed Stripe payments on self-hosted Gotify

Failed charges are the quiet leak in ARR. Stripe emails land in a shared inbox. Slack is a poor place for customer emails and invoice IDs if the channel is wide. Gotify keeps the ping on a server you run: Android push, simple WebUI, one application token.

The Stripe webhook still points at AlertHub — same URL as failed payment alerts and subscriptions. You only add Gotify in Connections. Critical maps to Gotify priority 8 (sound); warning maps to 5. Info never leaves the dashboard.

Gotify must be HTTPS and reachable from the internet. A LAN-only instance will not receive anything.

Events worth paging

Stripe eventLevelGotify priorityWhy
invoice.payment_failedCritical8Recurring billing missed
payment_intent.payment_failedCritical8One-time charge missed
customer.subscription.deletedWarning5Churn to review
invoice.paid / payment_intent.succeededInfo—History, no siren

Do not put full PAN or extra PII in titles. Amount, currency, and invoice id are enough on a lock screen.

Setup (once)

  1. Build the Stripe URL (placeholders in the failed-payments post or Stripe docs).
  2. In Stripe: Developers → Webhooks → that URL, events above.
  3. In Gotify: Apps → create an app → copy the token → paste https://your-gotify/message?token=YOUR_TOKEN in Connections → Gotify.

Subpath installs work: https://example.com/gotify/message?token=….

Alert 1: Invoice payment failed

invoice.payment_failed at critical is the default for SaaS. Title with amount and currency; description with invoice id and a reminder to open Stripe (not the customer email on the notification if the phone is public). Gotify priority 8 is the point — dunning email is not.

Alert 2: One-shot payment_intent.payment_failed

Checkout that never completes still needs a human when the cart is high-value. Same AlertHub project, second Stripe webhook URL with a distinct ah_title, or one URL and {{type}} in the title. Keep successful intents at info.

Alert 3: Subscription deleted

customer.subscription.deleted at warning is a review queue, not a fire alarm. Finance can watch Gotify WebUI; on-call does not need priority 8 for every cancel.

Ideas to squeeze more value

  • Slack later, not instead. Add Slack for a private #billing if the team grows — hybrid on-call. Do not dump Stripe into #general.
  • Zapier/Make Stripe. If you already go through automation, send AlertHub as the last node — n8n/Zapier/Make → Gotify.
  • ntfy instead of Gotify. Same Stripe URL, ntfy destination if you do not run a server.
  • Rotate the Gotify app, not Stripe. One token in Connections; Stripe keeps talking to AlertHub.

FAQ

Does Stripe POST to Gotify?
No. Stripe → AlertHub → Gotify.

Can I use HTTP on the LAN?
No. AlertHub calls from the cloud. Terminate TLS on a reverse proxy.

Do test-mode events page production?
Use a separate AlertHub project (or ignore info) for Stripe test webhooks.

Next steps

Keep the Stripe webhook, paste a Gotify message URL, and fire invoice.payment_failed in test mode.

Related: Gotify setup · Stripe failed payments · WooCommerce → Gotify