Daily Revenue Digest: Stripe + Razorpay → Google Sheets → Slack Alert
Stop manually reconciling Stripe and Razorpay every morning — automate the full digest into Google Sheets and Slack before standup.
The stack in the order it runs — data flows from the source through to where it lands.
The pain is specific: two payment processors, two dashboards, one person copy-pasting numbers into a spreadsheet every morning and hoping they remembered to subtract refunds and convert INR. That's 20-40 minutes of work that still produces errors. It compounds weekly.
n8n is the right orchestration layer here — not Zapier. It handles multi-step HTTP requests to both the Stripe and Razorpay REST APIs inside a single workflow, lets you write JavaScript transform nodes inline, and runs self-hosted so your payment data never touches a third-party iPaaS server. That last point matters when you're moving live revenue figures.
Google Sheets is the reconciliation ledger. Every run appends a new row — no database setup, permanent audit trail, finance can see it without touching n8n. Once you have 30 days of data, you can wire a Looker Studio chart on top of that sheet in under 10 minutes. Slack is the delivery layer because that's where your team already is.
Skip this if you're processing more than ~500 transactions/day — Stripe and Razorpay will paginate aggressively and your workflow runtime will push past 2-3 minutes. At that volume, use their webhook-based event streams into a Supabase table and run the aggregation query from there. Also skip this if your finance team needs GAAP-compliant reporting. This is an operational pulse check, not a revenue recognition tool.
The stack (5)
The universal data scratchpad.
Still the fastest place to land tabular data everyone can read.
How it runs
- 1
Create the n8n workflow with a Schedule Trigger
Create a new workflow in n8n and add a Schedule Trigger node. Set it to run daily at 8:00 AM in your local timezone using cron expression '0 8 * * *'. This is your single clock — everything downstream is deterministic from this trigger. Don't add any other entry points to this workflow.
- 2
Fetch yesterday's Stripe revenue via HTTP Request node
Add an HTTP Request node pointed at 'https://api.stripe.com/v1/charges'. Set authentication to Header Auth with key 'Authorization' and value 'Bearer sk_live_XXXX'. Add query params: 'created[gte]' = yesterday 00:00:00 UTC as a Unix timestamp using n8n's expression $now.minus({days:1}).startOf('day').toUnixInteger(), 'created[lt]' = today 00:00:00 UTC, 'limit' = 100. Add a second HTTP Request node for 'https://api.stripe.com/v1/refunds' with the same date params to capture refunds separately. Watch for 'has_more: true' in the response — if you're paginating, add a Loop node. Most teams under 500 txn/day won't hit this.
- 3
Fetch yesterday's Razorpay revenue via HTTP Request node
Add another HTTP Request node. URL: 'https://api.razorpay.com/v1/payments'. Auth: Basic Auth with your Razorpay Key ID as username and Key Secret as password. Query params: 'from' = yesterday 00:00:00 IST as Unix timestamp, 'to' = today 00:00:00 IST, 'count' = 100. Razorpay returns amounts in paise — 1 INR = 100 paise — so you'll divide by 100 in the next step. Filter only payments where 'status' = 'captured'. Anything else is not settled revenue.
- 4
Aggregate and reconcile in a Code node
Add a Code node in JavaScript. Sum Stripe's 'amount' field (in cents, divide by 100) minus refunds. Sum Razorpay's captured amounts (divide by 100 for INR, then convert to USD using a hardcoded or fetched exchange rate). Output a single object with these exact fields: { date, stripe_usd, razorpay_inr, razorpay_usd_equiv, total_usd, stripe_refunds_usd, net_usd, stripe_txn_count, razorpay_txn_count }. Log any Stripe charges where status != 'succeeded' to a separate 'flagged' array — those are your reconciliation exceptions and you need to see them every day.
- 5
Append row to Google Sheets
Add a Google Sheets node with action 'Append Row'. Map your sheet ID and tab name — e.g. 'Daily Revenue'. Map each field from the Code node output to the corresponding column in this order: Date, Stripe USD, Razorpay INR, Razorpay USD Equiv, Total USD, Stripe Refunds, Net USD, Stripe Txn Count, Razorpay Txn Count, Flagged Count. Never overwrite. Always append. This row is your audit trail and the dataset that powers any chart you build later.
- 6
Format and post the digest to Slack
Add a Slack node with action 'Send Message'. Target your #revenue or #standup channel. Use Block Kit formatting: a header block with the date, a section block with a two-column layout showing Stripe and Razorpay side by side, and a context block with refund totals and flagged transaction count. If flagged count > 0, append a '⚠️ N transactions need review' line to the message. Use a Slack Bot Token stored in n8n credentials — not a webhook URL. You'll want to thread replies to this message later, and webhook URLs don't support threading.
- 7
Add a threshold alert branch
Before the Slack node, add an IF node. Condition: net_usd < your expected daily floor — e.g. $300. If true, route to a separate Slack node that posts to #alerts with an @channel mention and a message like '🚨 Revenue below threshold: $X vs expected $300+'. This fires independently of the digest — the digest always goes out, the alert escalates separately. Set your threshold to roughly 60% of your 30-day daily average so you're not paging the team on a slow Sunday.
Want me to build this for you instead?
Product Audit and CTO Mode run out of this same thinking. If you’re reading this thinking “I want this, but in my product” — let’s talk.
See servicesMore like this
Gmail Thread Aging + Stripe Invoice Overdue: Unified AR Follow-Up Digest to Slack via Zapier
Surface overdue Stripe invoices and the exact age of your last Gmail thread with that customer — every morning at 8:30, automatically — so AR follow-up stops living in someone's head.
Intercom Ticket Volume + Razorpay Failed Payments: Daily Support-Cost-per-Revenue Alert to Slack via Zapier
Catch the support cost blowout from Razorpay failed payments before your agents are already buried.
Outlook Calendar Load + HubSpot Deal Velocity: Weekly Ops Digest to Microsoft Teams
Every Monday at 07:30, your revenue team gets one Teams card: last week's deal pipeline movement next to each rep's actual meeting load — so you stop guessing whether low close rates are a pipeline problem or a capacity problem.