HubSpot Deal Slip + Stripe MRR Gap Reconciliation: Weekly Risk Digest to Slack via Make

Surface the gap between what HubSpot says closed and what Stripe actually collected — before it blows up at quarter-end.

The flow
HubSpot logo
Source
HubSpot
Stripe logo
Process
Stripe
Make logo
Process
Make
Slack logo
Destination
Slack

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

Why this stack

The most common ops failure in early-stage B2B SaaS: deals marked Closed Won in HubSpot that never converted to active Stripe subscriptions, and deals marked Closed Lost where Stripe still shows an active subscription — usually a payment that went through before someone updated the deal. This playbook runs every Monday, cross-references both systems, and flags every mismatch before it becomes a finance argument.

Make (formerly Integromat) is the right glue here because it has native HubSpot and Stripe modules that handle OAuth and pagination without you writing a single API loop. The visual scenario editor also makes the cross-reference logic auditable — and when a workflow touches revenue data people will argue about, auditability matters.

The join key between the two systems is email. HubSpot's deal API returns `dealstage`, `closedate`, and `associations.contacts`. You pull the associated contact's email, then hit Stripe's customer search API (`/v1/customers/search?query=email:'x'`) to retrieve active subscriptions. If your HubSpot contact records have dirty email data, you'll get false mismatches — fix that first.

Skip this if you're PLG. If users self-serve without a sales rep ever creating a HubSpot deal, you'll have thousands of Stripe customers with no corresponding deal and this workflow generates noise. This is specifically for sales-assisted or hybrid motions where every Closed Won deal should map to a Stripe subscription.

The stack (4)

  1. HubSpot logo

    CRM + marketing for go-to-market.

    Pipeline data becomes an automatable input for revenue reports.

  2. Stripe logo

    Global payments with first-class APIs.

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

  3. Make logo

    No-code automation builder. Visual scenarios that chain APIs and AI calls.

    Per-operation pricing is cheaper than Zapier at the volumes I run, and the visual editor handles branching cleanly.

  4. Slack logo

    Team chat where most ops alerts and reports land.

    The default place a small team already lives — pipe reports here instead of email nobody opens.

How it runs

  1. 1

    Create a Make scenario with a weekly schedule

    In Make, create a new scenario. Add a Schedule trigger set to run every Monday at 7 AM — set the timezone to your business timezone. Name it `HubSpot-Stripe MRR Reconciliation`. Store your HubSpot Private App token and Stripe Secret Key as Make connections, using Make's built-in HubSpot and Stripe connection types so OAuth is handled without custom headers.

  2. 2

    Fetch HubSpot deals closed in the past 30 days

    Add a HubSpot Search for Deals module. Filter by `dealstage = closedwon` and `closedate` within the last 30 days. Request properties: `dealname`, `amount`, `closedate`, `hs_object_id`. Then add a HubSpot Get Associated Contacts module — associate each deal with its contacts and pull the contact's `email` property. Email is the join key to Stripe. If a deal has no associated contact with an email, flag it as a data hygiene issue — not a revenue mismatch. Keep those two categories separate.

  3. 3

    Look up each contact email in Stripe

    Add a Stripe Make an API Call module set to GET `/v1/customers/search?query=email:'{{email}}'&expand[]=data.subscriptions`. This returns the Stripe customer object with active subscriptions inline. For each Closed Won deal you're answering two questions: does a Stripe customer with this email exist, and do they have an active subscription? Capture `customer.id`, `subscriptions.data[0].status`, and `subscriptions.data[0].plan.amount` for the comparison.

  4. 4

    Run the same check for Closed Lost deals

    Add a second HubSpot Search for Deals module, this time filtering for `dealstage = closedlost` and `closedate` within the last 30 days. Run the same Stripe customer lookup. You're looking for the inverse: Closed Lost deals where the Stripe customer has an `active` subscription. That means either the deal stage was updated wrong or a payment went through after the deal was lost. This is where billing ops mistakes hide most often.

  5. 5

    Aggregate mismatches in a Make Array Aggregator

    Add a Make Array Aggregator module that collects two arrays: `closed_won_no_stripe` (Closed Won deals with no active Stripe subscription) and `closed_lost_active_stripe` (Closed Lost deals with an active Stripe subscription). Each item should include: deal name, deal amount, close date, contact email, and Stripe subscription status. Also compute `total_mrr_at_risk` by summing the `amount` field across all `closed_won_no_stripe` deals.

  6. 6

    Format and post the digest to Slack

    Add a Slack Create a Message module posting to `#revenue-ops`. Build the message in three sections: (1) a summary line — 'MRR Reconciliation: {N} Closed Won deals have no active Stripe sub | {M} Closed Lost deals still active in Stripe | $X MRR at risk'; (2) a bullet list of `closed_won_no_stripe` deals with deal name, amount, and email; (3) a bullet list of `closed_lost_active_stripe` deals. If both arrays are empty, post a green checkmark summary: 'All Closed Won deals have active Stripe subscriptions. No anomalies found.' That clean-run message is your confirmation the automation is actually working.

  7. 7

    Create Airtable records for each mismatch requiring action

    After the Slack message, add an Airtable Create a Record module for each item in both mismatch arrays. Table: `CRM-Billing Reconciliation`. Fields: Deal Name, Type (Closed Won No Sub / Closed Lost Active Sub), Amount, Contact Email, Close Date, Status (default: Open), Assigned To (leave blank for manual assignment). This gives revenue ops or sales a lightweight action queue to work through during the week — items get marked Resolved as they're fixed.

  8. 8

    Add an error handler for API failures

    In Make, add an error handler route on the Stripe lookup module. If Stripe returns a 429 (rate limit) or 5xx, route to a Slack Create a Message module that posts to `#ops-alerts`: 'MRR Reconciliation scenario failed at Stripe lookup — check Make execution log.' Without this, a Stripe API blip silently skips the entire reconciliation run and you won't know for a week.

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