# Closed-won vs. paid reconciliation: match Salesforce wins to Stripe invoices and flag the gaps

Source: https://mcpforgtm.com/recipes/revenue-reconciliation (StackMCP, independent directory of official MCP servers)

## Goal

RevOps teams who want every closed-won opportunity checked against what was actually invoiced and paid in Stripe, before commissions go out or the month is closed. Everything stays read-only. Salesforce can be swapped for HubSpot, Attio or Pipedrive.

## Connected tools

- Stripe: https://mcp.stripe.com (setup: https://mcpforgtm.com/tools/stripe)
- Salesforce: https://api.salesforce.com/platform/mcp/v1/platform/sobject-all (setup: https://mcpforgtm.com/tools/salesforce)

## Guardrails

- Read only in Salesforce. Don't edit any opportunity, amount, stage or owner.
- Read only in Stripe. Don't create, finalize or void invoices, change customers or subscriptions, create payment links or coupons, move money, or issue refunds.
- Show how each opportunity was matched to Stripe, and list unmatched records on both sides instead of guessing.
- Flag differences without deciding which system is right. Commission questions go to finance.
- Keep amounts and owner names in the report to me. Don't post them anywhere.

## Steps

1. Look at the Opportunity and Account schema in Salesforce and tell me which fields hold the amount, close date, owner, account website and any Stripe customer ID. Then use SOQL to list opportunities marked Closed Won with a close date in {period}: name, account, website, owner, amount and close date. Don't change any records.
2. In Stripe, read the customers, invoices and subscriptions for those accounts, from the start of {period} to 30 days after it ends. Match each opportunity to a Stripe customer by {stripe id field} if it's set, otherwise by email domain. Show how each match was made. Read only. Don't change anything in Stripe.
3. For each opportunity, compare the won amount with what was invoiced and what was paid, using subtotals before tax. Flag: no invoice, invoiced but unpaid, partly paid, or a different amount. If a subscription bills in instalments, compare against what should have been billed so far and mark it as a schedule, not a gap.
4. Give me a table of the mismatches only, grouped by owner, then a list of paid Stripe invoices with no closed-won opportunity. Add a line for each owner where the Salesforce amount and the paid amount differ, so I can check commissions. Don't change anything in Salesforce or Stripe.

## Expected output

Mismatches between closed-won and paid, grouped by owner. Example (all names fictional):

```
Closed Won in September (Salesforce): 18 opportunities, $412,000. Matched to a Stripe customer: 17. Nothing has been changed in Salesforce or Stripe.

Mismatches only:

| Opportunity | Owner | Won amount | Stripe | Flag |
|---|---|---|---|---|
| Quarry Lane Analytics (fictional), new logo | Alex Rivera | $33,000 | No invoice for customer quarrylane.example up to Oct 30 | Missing |
| Mossgate Labs (fictional), expansion | Priya Raman | $40,000 | INV-0440, $40,000, open since Sep 29 | Invoiced, not paid |
| Larkspur Freightworks (fictional), renewal | Sam Whitlock | $46,000 | INV-0436, $41,400 paid (10% coupon on the invoice) | Different amount, -$4,600 |
| Brightwater Dental Group (fictional), annual | Sam Whitlock | $18,000 | Quarterly subscription, $4,500 paid so far | Billing schedule, not an error |

Match basis: 15 by Stripe customer ID field on the account, 2 by email domain, 1 not matched (Quarry Lane).

Commission check: Larkspur's won amount in Salesforce is $46,000, but $41,400 was paid. Ask finance which number the plan uses before commissions are paid.

Paid in Stripe with no closed-won opportunity: 1 invoice, $12,000, customer tidewell.example (Tidewell Robotics, fictional).

All amounts are subtotals before tax, in USD.
```

## Watch for

- Wrong customer matched: A Stripe customer name often differs from the Salesforce account name. Match on a Stripe customer ID field if your org stores one, otherwise on email domain. Show the match basis for every row and list unmatched opportunities instead of guessing.
- A billing schedule flagged as partial payment: A quarterly or monthly subscription won't have paid the full contract yet. Read the subscription, compare what should have been billed so far, and mark those rows as a schedule rather than a gap.
- Late invoices flagged as missing: A deal won on the last day of the month is often invoiced the next week. Look at invoices up to 30 days after the period ends before marking anything missing.
- Tax or currency read as a different amount: An invoice total can include tax, or be in another currency. Compare subtotals before tax, show the currency on every row, and flag currency mismatches separately.
