Stripe + Razorpay vs. Airtable Revenue Ledger: Nightly Reconciliation with Claude Narrative to Microsoft Teams via Pipedream

Every night, pull raw charge data from Stripe and Razorpay, diff it against your Airtable ledger, let Claude write a plain-English mismatch summary, and have it in Microsoft Teams before your finance lead pours their first coffee.

The flow
Razorpay logo
Source
Razorpay
Stripe logo
Process
Stripe
Airtable logo
Process
Airtable
Claude logo
Process
Claude
Microsoft Teams logo
Destination
Microsoft Teams

The stack in the order it runs — data flows from the source through to where it lands.

Why this stack

The pain is specific. You're running Stripe for international cards and Razorpay for Indian UPI and netbanking. By the time your bookkeeper opens a spreadsheet Monday morning, the week's mismatch is already a mess — retried charges creating duplicates, refunds hitting one gateway but never your ledger, settlement delays stacking on each other. Manual reconciliation at this scale is a 2-hour job. It gets skipped.

Pipedream is the right orchestrator because it handles authenticated API calls to both Stripe and Razorpay natively — no OAuth flows to write yourself. Its scheduled workflow plus code step combo lets you diff arrays in JavaScript without spinning up a server. Airtable is the ledger because most early-stage ops teams already track expected revenue there. It's the source of truth they control, not a payment gateway they don't.

Claude does one specific job: take a JSON diff of mismatches and write 3–5 sentences a non-technical finance lead can act on. 'Stripe shows 3 charges totaling ₹12,400 with no matching Airtable record — likely a webhook lag from yesterday 11 PM IST' is more useful than a raw JSON dump in Teams. That's the entire scope. Don't overcomplicate it.

Skip this stack if your transaction volume exceeds ~5,000 charges per night — Pipedream's free-tier execution limits will bite you. Move to n8n self-hosted or a dedicated reconciliation service like Reconcile.ly. Also skip this if you already pipe both gateways into a data warehouse. Use dbt there instead.

The stack (5)

  1. Razorpay logo

    Payments + payouts built for India.

    Webhooks and the reports API make revenue an automatable signal, not a dashboard you check.

  2. Stripe logo

    Global payments with first-class APIs.

    Events + Sigma let you wire billing into any ops report or alert.

  3. Airtable logo

    Relational database with a spreadsheet face. Operational memory for every workflow I run.

    The audit trail across views, automations, and webhooks is unmatched in no-code land.

  4. Claude logo

    Long-context reasoning model from Anthropic — my daily driver for nuanced writing and orchestration.

    Better tone-matching and longer working memory than GPT for the tasks I care about most: guest messages, drafts, code review.

  5. Microsoft Teams logo

    Chat + channels for Microsoft-365 shops.

    If the company is on Outlook/365, Teams is where reports get read — push there, not a separate tool.

How it runs

  1. 1

    Create the Airtable revenue ledger base

    In Airtable, create a base called 'Revenue Ledger' with a table named 'Transactions'. Required fields: `transaction_id` (text), `gateway` (single select: Stripe / Razorpay), `amount` (currency), `currency` (text), `status` (single select: captured / refunded / disputed), `created_at` (date+time), `reconciled` (checkbox). This is your canonical record — the thing you diff against. Every expected charge lands here, either manually or via your existing billing webhook. Get this right before touching anything else.

  2. 2

    Set up a Pipedream scheduled workflow

    In Pipedream, create a new workflow with a Schedule trigger. Set it to run daily at 01:00 UTC — or 06:30 IST if your team is India-based. Name it 'Nightly Revenue Reconciliation'. Under Settings, enable 'Retry on failure' with 2 retries and a 5-minute delay. Gateway APIs occasionally 503 at night during settlement runs. The retries save you from a false alarm in Teams.

  3. 3

    Fetch last 24 hours of Stripe charges

    Add a Node.js code step. Use the Stripe SDK: call `stripe.charges.list({ created: { gte: yesterdayUnix, lte: todayUnix }, limit: 100 })` with pagination via `auto_paging_each`. Store results as an array of objects: `{ id, amount, currency, status, created }`. Watch the `amount_captured` vs `amount` distinction — only count `status: 'succeeded'` charges. Store the array as `stripeCharges` in the step's output.

  4. 4

    Fetch last 24 hours of Razorpay payments

    Add a second Node.js step. Call `GET https://api.razorpay.com/v1/payments?from=UNIX_YESTERDAY&to=UNIX_TODAY&count=100` using Basic Auth — key_id and key_secret stored as Pipedream environment variables. If `count` returns 100 items, paginate with the `skip` param. Normalize each record to match the Stripe shape: `{ id: payment.id, amount: payment.amount / 100, currency: payment.currency, status: payment.status, created: payment.created_at }`. Store as `razorpayPayments`. The normalization step matters — mismatched shapes will break your diff downstream.

  5. 5

    Pull today's Airtable ledger records

    Add a Pipedream Airtable action — 'List Records'. Point it at your Revenue Ledger base and Transactions table. Add a filter formula: `AND(IS_AFTER({created_at}, YESTERDAY()), IS_BEFORE({created_at}, TODAY()))`. Map the returned records to a flat array of `transaction_id` values. This becomes your `ledgerIds` set. If Airtable returns more than 100 records, enable the 'Return all records' toggle in the action config — don't leave it off and wonder why your diff is wrong.

  6. 6

    Diff gateway charges against the ledger

    Add a Node.js code step. Merge `stripeCharges` and `razorpayPayments` into a single `allGatewayTxns` array, tagging each item with a `gateway` field. Filter for mismatches: `const mismatches = allGatewayTxns.filter(txn => !ledgerIds.includes(txn.id))`. Also run the inverse — ledger records with no gateway match, your potential ghost entries. Output both as `missingFromLedger` and `missingFromGateway`. If both arrays are empty, set a flag `allClear: true` to short-circuit the Claude call. No point paying for a Claude call when everything matched.

  7. 7

    Generate Claude narrative for mismatches

    Add an HTTP request step to `https://api.anthropic.com/v1/messages`. Set the model to `claude-3-5-haiku-20241022` — fast and cheap for structured summaries. Prompt: 'You are a finance ops assistant. Given this JSON of revenue mismatches between payment gateways and our Airtable ledger, write 3–5 plain-English bullet points a non-technical finance lead can act on. Flag amounts over $500 USD equivalent as HIGH PRIORITY. JSON: {{mismatches}}'. If `allClear` is true, skip this step entirely and use a hardcoded message: '✅ All gateway charges matched the ledger. No action needed.'

  8. 8

    Post the digest to Microsoft Teams

    Add an HTTP POST step targeting your Teams Incoming Webhook URL — create it under your Finance channel → Connectors → Incoming Webhook. Send an Adaptive Card payload with: a header 'Nightly Revenue Reconciliation — {{date}}', a summary line '{{stripeCharges.length}} Stripe + {{razorpayPayments.length}} Razorpay charges reviewed', the Claude narrative as body text, and a count badge 'Mismatches: {{mismatches.length}}' colored red if greater than 0, green if 0. Keep the card under 28KB. Teams silently drops anything over that limit — you'll never know it failed.

  9. 9

    Create an Airtable record for each mismatch

    Add a Pipedream loop step over `missingFromLedger`. For each item, call the Airtable 'Create Record' action in your Revenue Ledger table, setting `reconciled` to false and a new field `flag` to 'GATEWAY_ONLY'. Your finance lead opens Airtable the next morning and sees a pre-populated list of charges to investigate — they don't need to re-read the Teams message to know where to start. Set a view filter in Airtable for `flag = GATEWAY_ONLY AND reconciled = false` and drop that view link directly into the Teams card.

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 services

More like this