What should a payment alert include?
A useful payment alert says who paid, how much you keep, what changed in MRR, and where to look next. Here is each field, and why a raw Stripe webhook cannot give you them.
The ChargeBell Team
Updated October 1, 2026. 9 min read.

A payment alert should include the event, the amount, the customer, and a link to the Stripe record. Fee and net amounts help when Stripe's balance transaction is available. MRR belongs on subscription alerts, not on every payment. ChargeBell sends these fields in plain English where it can, but you still open Stripe for the final status and retry details.
Short answer
A successful payment alert should show the amount, the customer, and a Stripe link. ChargeBell adds gross, fee, and net amounts when it can read the balance transaction and net display is on. Subscription alerts can show MRR when it can be calculated. ChargeBell's failed payment alert does not show the decline code or a retry date.
A good payment alert and a bad one
Here is one event shown two ways. First, a raw Stripe webhook posted straight to Slack. An engineer can read it. A founder sees an amount in cents, a customer ID with no name, and nothing about fees.
Raw webhook example
🧩 payment_intent.succeeded
{ "amount": 24900, "currency": "usd", "status": "succeeded",
"customer": "cus_Qx9aB2c" }
Here is the same payment as a ChargeBell message, with sample data and gross display. Net fields appear only when the conditions above are met.
ChargeBellAPP
🔔 You got paid: $249.00
billing@acme.com
Amount (before fees): $249.00 · View in Stripe
The second message reads as a sentence. Fee and net amounts can be added to it, and subscription alerts use their own format for MRR. The sections below split required fields from optional ones.
What a payment alert should include, field by field
A payment alert should say what happened, how much, who paid, and where to look. Add fee and net when Stripe has them, MRR for a subscription change, and an urgency marker for a failure or dispute. Leave a field out when the data is missing instead of filling it with a guess.
1. Amount, gross and net after fees
The gross amount alone overstates what you earned. A raw charge.succeeded or payment_intent.succeeded event has the gross amount, currency, and status. It does not have the processing fee or the net amount that reaches your balance. Stripe keeps those on a separate balance transaction, which you fetch or expand to read. Stripe sends no webhook for the balance transaction itself.
Stripe fees vary by region, card, currency, and payment method. Read the net amount from the actual balance transaction instead of a fixed percentage. Stripe's pricing page lists the rates for your country.
Show both numbers
ChargeBell uses net display by default and shows gross, fee, and net when it can read the balance transaction. It shows the amount before fees when you pick gross display or the balance transaction is not available. A missing net field means unknown, not zero.
2. Who paid: name and email, not an ID
The raw event gives you a customer ID like cus_Qx9aB2c, with no name or email. You cannot spot a key account or reply to a support ticket from an ID. A good alert looks up the customer and shows the name and email in the message. Any Stripe payment notification in Slack should do this.
3. What happened: the event in plain English
The reader needs to know at a glance whether this is a sale, a failed charge, a refund, a dispute, or a cancellation. Each one goes to a different person and needs a different response. Start the message with a plain label and an emoji so people know the type before they read a number.
4. MRR change for subscription events
For subscription events, the MRR change is the most useful field. MRR moves in four ways: new, expansion, contraction, and churn. A "subscription updated" label tells you none of them. When a customer cancels at the end of the period, Stripe sends customer.subscription.updated first and customer.subscription.deleted only when the subscription ends. An alert has to read the event to know which movement it is.
A good subscription alert names the movement and the amount, such as "Upgrade · MRR +$40" or "Canceled · MRR −$249". It shows the customer, the old MRR, the new MRR, and the change. For setup steps, see how to monitor Stripe subscriptions in Slack.
5. A link and an urgency marker
The alert should link to the exact Stripe payment or customer, not the Dashboard home page, so checking takes one click. It should also show how urgent the event is. A routine sale can be quiet. A failed payment or a dispute needs someone to act, so it should look different and go to a different channel.
Urgency and routing in a payment alert
The higher the risk, the louder the alert should be. Routine events get a quiet message. Failures and disputes get a strong marker and go to the person who owns the fix. Events that need no action today belong in a digest, not a real-time ping.
So a payment alert also needs a severity marker, such as a color or emoji, and a channel or person who owns it. A failure also needs the reason and a next step. Here is a failed payment alert, built to look different from a sale:
ChargeBellAPP
⚠️ A $1,200.00 payment didn't go through
ap@globex.com · card declined
Check Stripe to see if it will be retried. · View in Stripe
This message shows the amount, the customer when Stripe has one, Stripe's failure message, and a prompt to check Stripe. It does not show a decline code, a retry schedule, or MRR at risk. Open Stripe for those, and use the Stripe decline codes cheat sheet to read the code. See also the failed payment alerts guide and which Stripe alerts go to which team.
Volume counts too
One Slack message per webhook turns a channel into noise nobody reads. Group related events and put low-urgency ones in a digest. Part of designing alerts is choosing what does not post in real time. See how to avoid noisy Stripe notifications.
Why a raw Stripe webhook is not a payment alert
A raw Stripe event wraps the data in envelope fields such as id, object, api_version, created, and type, and puts the object under data.object. Amounts are integers in the smallest currency unit, so amount: 2000 means $20.00. A non-engineer cannot read that, and anyone can misread it.
Three of the fields a good alert needs are not in the payload at all:
- Net after fees. It lives on a separate
balance_transactionthat you must expand or fetch. The charge webhook has neither the fee nor the net. - Customer name and email. The event has a
cus_ID, and you look up the customer record to get the name. - MRR movement. New, upgrade, downgrade, and churn have to be worked out from the event, because a cancellation often arrives as
customer.subscription.updated.
Stripe's own Stripe Workflows for Slack app lets you pick events, choose a channel, and add a Dashboard link, and it is free. Zapier, direct webhooks, and other forwarders can pass any field in the event. In each case, net after fees, the customer name, and the MRR movement need extra lookups that you set up and maintain. If you are thinking of building them yourself, ChargeBell vs custom Stripe webhook code lists what that involves.
Payment alert checklist
Use this list whether you build alerts yourself or compare tools. A payment alert should include:
- Amount, gross and net. Format the currency, and read the fee from the balance transaction instead of using a fixed percentage.
- The customer. Show the name and email, so the reader knows the account.
- The event type. Use a plain label and marker, such as new payment, failed payment, refund, dispute, new subscriber, cancellation, or payout.
- MRR change. For subscription events, show the amount and whether it is new, upgrade, downgrade, or churn.
- A direct link. Link to the exact Stripe payment or customer.
- Urgency and an owner. Mark failures and disputes clearly and send them to the people who act on them.
- Sensible volume. Put low-urgency events in a digest instead of one message per webhook.
How ChargeBell builds each payment alert
ChargeBell's Stripe Slack integration builds alerts from the checklist above. Each message is plain English. It shows the net amount after Stripe fees when it can read the balance transaction, the customer name and email when Stripe has them, and the MRR change on subscription alerts when it can be calculated.
Urgency and routing are built in. Payment failed and dispute created alerts are critical, so they skip quiet hours and can add an @channel mention. You can send sales to #wins and problems to #founders with per-alert routing. Quiet hours hold low-priority alerts and post them as one "while you were away" message. Daily and weekly digests collect the small events. ChargeBell connects with read-only Stripe OAuth, so it can read events but cannot move money or change anything.
Net
Fee and net shown when Stripe's balance transaction is available
Name + email
Customer shown by name when Stripe has it, not as an ID
MRR Δ
MRR change on subscription alerts when it can be calculated
Key takeaways
- A payment alert should show the event, amount, customer, and Stripe link. Fee, net, and MRR are added when the data exists.
- A raw webhook has no net amount and no customer name. Net is on a separate balance transaction, and the event has only a customer ID.
- Name the MRR movement. "Subscription updated" is not useful, and many cancellations arrive as an update event.
- Make failures and disputes louder than sales and send them to their owner. Put the rest in a digest.
- Raw forwarders and Stripe's own Slack app send the event's fields. The lookups that make an alert useful are extra work.
Set up the alert
Frequently asked questions
What should a payment alert include?
A payment alert should include the event, the amount, the customer, and a link to the Stripe record. Add the real fee and net amount when available, the MRR change on subscription events, and an urgency marker for failures and disputes.
Why doesn't a raw Stripe webhook show the net amount after fees?
A charge or payment_intent webhook has only the gross amount, currency, and status. Stripe puts the fee and net on a separate balance_transaction object that you expand or fetch. Stripe sends no webhook for the balance transaction, so a forwarded event cannot show net.
Can I assume Stripe's fee is 2.9% + $0.30?
No. Stripe fees vary by region, card, currency, and payment method. Read the actual balance transaction and check Stripe's pricing for your account instead of hardcoding a rate.
Why does a payment alert need the customer's name if Stripe sends a customer ID?
An ID like cus_Qx9aB2c has no name or email. You cannot recognize a key account or reply to a support ticket from it. A good alert looks up the customer and shows the name and email so the reader can act right away.
How should urgency change a payment alert?
The higher the risk, the louder the alert. A routine sale can be quiet. A failed payment or dispute should have a stronger marker, a reason, a next step, and go to the people who act on it. Low-urgency events belong in a digest.
Does ChargeBell calculate net after fees and MRR change?
ChargeBell shows fee and net on payment alerts when it can read Stripe's balance transaction and net display is on. Subscription alerts show an MRR change when it can be calculated. Routine payment and trial ending alerts do not include MRR. The Stripe connection is read-only.


