The webhook hits.
The alert fires once.
Latch is a small production worker for a VPS. It verifies Stripe signatures, stores each event.id exactly once, and posts a short human message to Slack and/or Telegram. Retries are exponential. Failures land in a dead-letter you can inspect.
What it notifies
Handled in v1:
invoice.payment_failedcharge.dispute.createdcustomer.subscription.deleted
Every other Stripe type is acknowledged with HTTP 200 and is not sent downstream. Each alert includes customer email when present, amount + currency, the event type, and a Dashboard URL.
Stripe setup
- Deploy Latch on a VPS (see the README). Confirm
GET /healthreturns{"status":"ok"}. - Your public endpoint is:
https://YOUR_HOST/webhooks/stripe - In Stripe Dashboard go to Developers → Webhooks → Add endpoint.
- Paste that URL. Select at least the three events above. Save.
- Reveal the endpoint’s Signing secret (
whsec_…) and set it asSTRIPE_WEBHOOK_SECRETon the box. Restart Latch. - Send a test event from the Dashboard. You should get one Slack/Telegram message. Send it again: still one message.
.env.example to .env on the server. Keep STATUS_TOKEN private — it gates GET /deadletter.
Pricing
Placeholder for a managed Latch. Self-hosting this repo stays free. No checkout on this page.
Why a worker, not a Zap
Stripe retries. Humans double-click “Send test”. A naive forwarder pages you twice for one dispute. Latch latches on event.id first, then delivers. If Slack is down, it backs off and keeps the payload in SQLite instead of asking Stripe to hammer you.