See which closed-won deals in Close are actually paying in Stripe

By General Input

Match every won deal to its Stripe customer, spot the ones never billed, past due, or quietly churned, and see how much of your closed-won number was real.

Integrations

  • Close
  • Stripe
  • Slack Bot

Type

App

Categories

  • Sales
  • Finance

Build me an internal app that answers the question my CRM cannot: of everything we marked closed-won in Close, who is actually paying us in Stripe. This is a reconciliation board I open and work through, not an alert that fires when a payment fails.

The main board lists every closed-won Close opportunity from the last 12 months, each one matched to its Stripe customer. Load won deals with the Close List Opportunities operation filtered to won status over a date range covering the last 12 months, and use Close List Leads to pull the lead record behind each opportunity along with its contact email addresses and company website. Each row shows the lead and company name, the deal value we booked, the close date, the matched Stripe customer, the subscription status, the amount actually billed, and any unpaid balance. Put the booked value and the billing reality side by side on the same row so the gap is obvious at a glance.

To get billing reality, match each deal to a Stripe customer with Stripe Search Customers, falling back to Stripe List Customers when a broader scan is needed. Once matched, pull that customer's Stripe List Subscriptions for subscription status and recurring amount, and Stripe List Invoices for paid totals, open invoices, overdue invoices, and unpaid balance. Stripe amounts come back in the smallest currency unit, so convert before displaying and format using the invoice currency.

A summary strip pinned to the top of the app shows booked deal value versus actually billed revenue across the visible set, plus the difference as both an amount and a percentage, so we can see how much of our closed-won number was fiction. Show the row count for each of the three tabs in that strip too.

The board splits into three tabs I work through. "Won but never paid" holds deals with no matched Stripe customer at all, or a matched customer with no active subscription and no paid invoices. "Paying but past due" holds customers carrying open or overdue invoices, sorted by unpaid balance descending so the biggest exposure is first. "Churned" holds customers whose subscription is canceled while the Close lead still looks like a happy account, and each of those rows should show the lead's current Close status next to the cancellation date so the contradiction is visible.

Matching rules matter. Try the lead's contact email addresses against Stripe first, and if nothing matches, fall back to the company domain taken from the lead's website URL compared against the domain of the Stripe customer email. Show a small badge on each row saying whether the match came from email, from domain, or was linked by hand, so I can tell how much to trust it.

Any unmatched deal needs a way to link it to a Stripe customer manually: let me search Stripe customers from the row, pick the right one, and save that link. Store these manual links in the app's own storage keyed by the Close opportunity or lead id, and check that stored mapping before doing any automatic matching, so the app remembers the link and never asks me about that deal again. Let me undo a manual link if I picked the wrong customer.

From any row I need to act without leaving the app. Create Task on the Close lead to chase collections or schedule a save call, with a due date I pick. Create Note on the Close lead to record what billing told me. Update Lead to flip the lead status to something like At Risk. Each action should confirm inline and refresh the row it came from.

Add a button that posts the week's churn and unpaid totals to our revenue channel using the Slack Bot Send a Message action. The message should summarize total unpaid balance, how many customers are past due, how many have churned, the total booked value that never turned into billing, and name the few largest offenders. Let me choose which channel it goes to.

Practical notes: page through both the Close and Stripe list results rather than reading only the first page, cache the fetched data for the session so switching tabs is instant and give me a manual refresh button, show a clear loading state on first load because this pulls from two systems, and handle deals whose lead was deleted in Close without breaking the board.

Related prompts

Explore more prompts
Let support send one-off Loops emails without an engineerA brand asset library your marketing team actually searchesTurn Mailjet email clicks into ranked HubSpot follow-upsClean out the Looker dashboards and Looks nobody opensLiveKit live operations console for room moderationWake up dormant Keap leads with a researched reasonCustomer lifecycle inspector for Loops, Stripe and PostHogLiveChat coverage board for planning next week's shiftsPhone routing control panel for LiveKit voice agentsLinkedIn Ads budget pacing dashboard for every client account