Never Miss a Stripe Payment Again — Real-Time Alerts on Slack, Discord and Telegram with n8n
Stripe processes the payment. You find out 3 hours later when you check your dashboard.
For solo founders and small teams, missing real-time payment events isn’t just inconvenient — it means slower fulfillment, delayed onboarding, and missed opportunities to catch failed payments before customers churn.
This tutorial shows how to build a Stripe → multi-channel alert system with n8n that notifies your whole team instantly, in whichever app you actually use.
What Gets Alerted
The workflow listens to five Stripe webhook events:
Event What it means Who carespayment_intent.succeeded
Customer paid
Everyone 🎉
payment_intent.payment_failed
Card declined
Support team
charge.refunded
Refund issued
Finance
customer.subscription.deleted
Subscription cancelled
Sales/CS
invoice.payment_failed
Recurring payment failed
Finance
Each event generates a formatted message delivered simultaneously to Slack, Discord, Telegram, and/or email — your choice.
The Slack Message Format
Instead of raw JSON, the alerts are formatted for humans:
💰 New Payment
Amount: €149.00
Customer: Acme Corp ([email protected])
Product: Professional Plan
Payment ID: pi_3abc...
Time: 26 Jul 2026, 14:32
Enter fullscreen mode Exit fullscreen mode
For failed payments:
⚠️ Payment Failed
Amount: €149.00
Customer: [email protected]
Reason: insufficient_funds
Retry: Stripe will retry in 3 days
Payment ID: pi_3xyz...
Enter fullscreen mode Exit fullscreen mode
n8n Setup
1. Stripe Webhook
In your Stripe Dashboard → Developers → Webhooks → Add endpoint:
Endpoint URL: https://your-n8n.com/webhook/stripe-alerts
Events to send: Select the 5 events listed above
Enter fullscreen mode Exit fullscreen mode
Copy the Signing Secret — you’ll need it to verify webhook authenticity.
2. Webhook Verification (Security)
Always verify Stripe webhooks. n8n’s built-in Stripe Trigger node handles this automatically. If you’re using a plain Webhook node, add this verification in a Code node:
const stripe = require('stripe'); // not available in n8n — use the Stripe Trigger node instead
Enter fullscreen mode Exit fullscreen mode
Use the Stripe Trigger node — it handles signature verification out of the box. Don’t use a plain Webhook node for Stripe.
3. The Event Router
After the Stripe Trigger, add a Switch node that routes on {{$json.type}}:
-
payment_intent.succeeded→ Branch 1 -
payment_intent.payment_failed→ Branch 2 -
charge.refunded→ Branch 3 -
customer.subscription.deleted→ Branch 4 -
invoice.payment_failed→ Branch 5
Each branch formats the message and sends to your channels.
4. Message Formatting (Code Node)
const event = $input.first().json;
const type = event.type;
const obj = event.data.object;
let emoji, title, details;
if (type === 'payment_intent.succeeded') {
emoji = '💰';
title = 'New Payment';
const amount = (obj.amount / 100).toFixed(2);
const currency = obj.currency.toUpperCase();
details = `Amount: ${currency} ${amount}\nCustomer: ${obj.customer || 'Guest'}\nID: ${obj.id}`;
} else if (type === 'payment_intent.payment_failed') {
emoji = '⚠️';
title = 'Payment Failed';
const amount = (obj.amount / 100).toFixed(2);
const reason = obj.last_payment_error?.message || 'Unknown reason';
details = `Amount: ${obj.currency.toUpperCase()} ${amount}\nReason: ${reason}\nID: ${obj.id}`;
} else if (type === 'charge.refunded') {
emoji = '↩️';
title = 'Refund Issued';
const amount = (obj.amount_refunded / 100).toFixed(2);
details = `Amount refunded: ${obj.currency.toUpperCase()} ${amount}\nCustomer: ${obj.customer || 'Guest'}`;
}
const message = `${emoji} *${title}*\n${details}\n_${new Date().toLocaleString('en-GB')}_`;
return [{ json: { message, type, raw: obj } }];
Enter fullscreen mode Exit fullscreen mode
5. Multi-Channel Delivery
Connect the formatted message to all your channels in parallel (use Merge node if you want a single execution path):
Slack — HTTP Request:
POST https://hooks.slack.com/services/YOUR/WEBHOOK/URL
Body: { "text": "{{$json.message}}" }
Enter fullscreen mode Exit fullscreen mode
Discord — HTTP Request:
POST https://discord.com/api/webhooks/YOUR_WEBHOOK_URL
Body: { "content": "{{$json.message}}" }
Enter fullscreen mode Exit fullscreen mode
Telegram — HTTP Request:
POST https://api.telegram.org/botYOUR_TOKEN/sendMessage
Body: { "chat_id": "YOUR_CHAT_ID", "text": "{{$json.message}}", "parse_mode": "Markdown" }
Enter fullscreen mode Exit fullscreen mode
6. Google Sheets Logging
Every event also appends a row to your Sheets log:
Timestamp | Event Type | Amount | Currency | Customer Email | Payment ID | Status
Enter fullscreen mode Exit fullscreen mode
This gives you a complete audit trail outside Stripe — useful for reconciliation, and for team members who don’t have Stripe access.
Filtering by Amount (Optional)
Don’t want a Slack notification for every $1 microtransaction? Add an IF node before the Slack branch:
// Only alert Slack for payments over €50
return $json.raw.amount > 5000; // Stripe amounts in cents
Enter fullscreen mode Exit fullscreen mode
Discord can still log everything, Slack only gets the significant ones.
Estimated Setup Time
- Stripe webhook: 5 minutes
- n8n workflow import and configure: 10 minutes
- Slack/Discord/Telegram webhook URLs: 5 minutes each
- Test with Stripe’s webhook simulator: 5 minutes
Total: ~30 minutes to first real-time alert.
Get the Pre-Built Workflow
The complete workflow with all 5 event types, formatting logic, and multi-channel delivery configured is available at n8nmarkets.com. Search “Stripe Payment Alerts Slack Discord SMS Email Sheets”.
Includes the workflow JSON ready to import, plus setup guide for each notification channel.
Which Stripe events do you find most useful to monitor in real-time? For most SaaS teams it’s failed payments — catching those within minutes instead of hours dramatically improves recovery rates.
답글 남기기