ingestlayer/blog

all posts
Post#playbook

Get a Slack message for every Stripe payment.

A Stripe payment notification in Slack, without Zapier: one webhook, a dedupe, and a message that says who paid and why, not a cus_ id.

ben7 min read


A Stripe payment notification in Slack is the one alert nobody ever mutes. Acme Robotics paid $299 · subscription upgrade, second seat this month. It costs nothing to receive and it makes the whole team look up. On a slow Tuesday it's the difference between wondering whether the business is working and watching it work.

Stripe will happily send you the raw material: it fires a webhook for everything. The catch is that the webhook says cus_Q8xT… and amount_paid: 29900, and one swipe of a card can arrive four times under four different names. Getting from that to the sentence is the actual job, and it's why most teams end up wiring the whole thing through Zapier and paying per task for the privilege.

which stripe event is actually a payment

The first surprise is that “a payment” isn't one event. A single successful charge can fire charge.succeeded, payment_intent.succeeded, checkout.session.completed, and invoice.paid. Subscribe to all of them and your channel celebrates every sale four times. For a subscription business the one to listen to is invoice.paid: it fires once per movement of money, and it carries billing_reason, which is the payload's way of telling you why the money moved.

The second surprise is that plenty of paid invoices are for $0: trials starting, credit balances covering a cycle. And like every webhook sender, Stripe delivers at least once, so the same event will occasionally show up twice with the same id; that retry behavior has its own post. So the raw feed needs three small corrections before it deserves the channel: pick one event type, drop the zeros, collapse the redeliveries.

a stripe payment notification worth reading

Then there's the message itself. The payload names the customer cus_Q8xT2fJk; the channel deserves the company. One enrichment on the customer email turns the id into a name the whole team recognizes, and the ping reads like news instead of a log line.

And not every payment is the same news at the same volume. subscription_create is a brand-new customer, the thing you want on your phone. subscription_cycle is the fourteenth renewal: good news, channel-grade. The warehouse wants all of it, zeros included, because the trial conversions you'll want to count next quarter are hiding in those $0 invoices.

the zapier tax

The usual way to get all this is a zap: trigger on the Stripe event, look up the customer, format the message, post it. Four steps, and Zapier bills every step of every run as a task, so the price of the cash-register sound scales with exactly the thing you're celebrating. The other reflex, a fetch call pasted into the webhook handler, is free right up until a retry double-pings the channel or a slow response starts dropping events.

the pipeline

representation

01source

sourcehttp.webhookWebhook
matchinvoice.paid

02pipeline · 2 steps

  • 01CTLdedupekey $event.id · within 72h
  • 02ENRenrich.company$event.payload.customer_email → company

03destinations · 3

  • toslackSlack
    channel#revenue
    when$event.payload.amount_paid > 0
  • totelegramTelegram
    chat@founders
    when$event.payload.billing_reason == "subscription_create"
  • towarehouse.pgPostgres
    tableevents.payments

#revenue hears about every real payment, in words: company name, amount, and the billing_reason that says whether it's a new deal or a renewal. Your phone only buzzes for brand-new subscribers. Postgres records everything, including the $0 invoices that never made a sound. One webhook in, three destinations out, and the dedupe up top protects all of them at once from Stripe's retry schedule.

how ingestlayer does this

You point the Stripe webhook endpoint at a pipeline and the events start flowing: signed, acknowledged immediately, processed on the pipe's clock. dedupe and enrich.company are first-class actions, and the per-destination when is how one feed serves the channel, your phone, and the warehouse without compromise. It's the same shape as the signup ping on Telegram. Different event, same three moves.

Wire your Stripe webhook to a pipeline. The quickstart takes about five minutes, which is less time than naming the zap.


Read next

Notifications as code: alert routing belongs in git.

The rules deciding what your team hears about production live in dashboards nobody reviews. Notifications as code puts them in git, behind a PR.

← back to all posts