Back to blog

Salesforce + Stripe: why your data drifts and how to reconcile it automatically

·7 min read·Corentin Charneau·Lire en français
SalesforceStripereconciliationRevenue IntegrityRevOps

For a company running €2M ARR, a 2% desynchronisation between Salesforce and Stripe means €40,000 in revenue you can't properly account for: overstated ARR distorting your projections, undetected churn inflating your metrics, oral discounts that never made it into either system. Those €40,000 aren't lost in the strict accounting sense. They're invisible, until an audit or a due diligence process surfaces them at exactly the wrong moment.

Salesforce and Stripe are two of the most widely deployed tools in mid-market B2B. They coexist in almost every RevOps stack. Yet they weren't designed to communicate with precision. The native integration exists, but it only handles the simple cases. The moment pricing gets complex, the moment a discount falls outside the standard path, the moment a churn isn't logged promptly: the data diverges. Quietly, over months.

The four gap types that come up every time

The first time a company runs a proper line-by-line reconciliation across six to twelve months of data, the same four families of discrepancy appear, almost without exception.

Gap type one: a Closed Won opportunity with no matching Stripe subscription. A rep closes a deal in Salesforce, marks the opportunity Closed Won, moves on to the next prospect. In theory, someone needs to go into Stripe and create or activate the corresponding subscription. In practice, that handoff isn't systematized. It depends on a Slack notification, an email, a checklist no one audits. Contracts get signed but generate no billing for weeks, sometimes months. The customer is onboarded, uses the product, and no invoice goes out.

Gap type two: diverging amounts for the same customer. The Stripe subscription shows €1,200/month. The Salesforce opportunity records €1,400. The €200 gap corresponds to an oral discount agreed during final negotiations. The rep adjusted their CRM entry. Nobody updated Stripe. This pattern multiplies with headcount, deal complexity, and the absence of a clear rule about who owns billing configuration.

Gap type three: an active Stripe subscription for a customer marked Churned in Salesforce. A customer cancels. RevOps updates the CRM. But the Stripe subscription isn't cancelled at the same moment: either through oversight, or because the churn process is owned by a different team operating on a different timeline. Invoices continue going out. Some customers pay them without flagging the issue. Others dispute them months later, triggering credits and strained relationships.

Gap type four: misaligned contract start and end dates. The Salesforce contract starts March 1st, but the Stripe subscription was activated March 8th. A prorated amount is owed. Nobody bills it because the date gap isn't caught by any system. Across fifty customers with this kind of misalignment, the cumulative unbilled days add up to a meaningful amount by year-end.

Why the native integration isn't enough

The question comes up regularly: Salesforce and Stripe both offer native integrations, AppExchange connectors, Stripe Billing Portal packages. Why do these gaps persist?

The answer is structural. These integrations transmit the basics: customer name, amount, payment status. They don't transmit business context. A conditional discount ("20% for 12 months, then back to list price") lives in a custom Salesforce field. The integration doesn't map it to Stripe. A manually negotiated contract end date sits in a free-text field, not a structured field the integration can interpret.

More fundamentally, these integrations are built for one-directional flows: triggering the creation of a Stripe customer from a Salesforce account, or pushing a payment status back into the CRM. They're not built for continuous bidirectional reconciliation: comparing the state of data on both sides, identifying divergences, classifying them by type and financial impact.

Reconciliation, by nature, requires looking at both systems simultaneously, understanding what each knows that the other doesn't, and deciding what to correct and where.

What the first manual reconciliation reveals

For companies that have never done this exercise, the first attempt is often a sobering experience. Export the Salesforce opportunities from the last twelve months into a CSV, export the Stripe subscriptions and invoices for the same period, then try to cross-reference them manually: this takes a skilled analyst three to eight hours. And the output is rarely reassuring.

The difficulty is technical. Customer identifiers aren't standardized: Salesforce uses an internal Account ID, Stripe uses a Customer ID (cus_xxxx), and the two don't share a common key in most standard configurations. You end up matching on approximate business keys: company name, billing email, domain, sometimes VAT number. Each of these has variants and edge cases.

Contract dates add another layer. A Salesforce deal dated February 15th may correspond to a Stripe subscription created February 22nd, with a service period starting March 1st. Nothing matches directly. A human eye can reconstruct the logic; a VLOOKUP cannot.

The result: manual monthly reconciliation is time-intensive, incomplete, and generates its own errors on complex cases (multi-line contracts, conditional discounts, partial credits). It covers maybe 80% of transactions, leaves the 20% most complex cases in a grey zone, and detects gaps with a 30 to 60 day lag.

The architecture of automated reconciliation

A reliable Salesforce-Stripe reconciliation rests on a four-layer architecture that can be implemented progressively.

Layer one: nightly extraction and ingestion. A scheduled job pulls data from both systems each night via their respective APIs. From Salesforce: opportunities (status, amount, dates, discounts, account ID) and accounts (email, domain, legal name). From Stripe: subscriptions (status, plan, amount, start and end dates, customer ID), invoices (billed amount, status, date), and charges (amount collected, date). The nightly extraction ensures a consistent snapshot of both systems without interfering with daytime operations.

Layer two: normalisation into a shared schema. Data from both systems is loaded into an intermediate store with a unified schema. Each entity receives a canonical identifier built from available business keys: billing email (cleaned and normalised), domain (extracted from email or website), company name (normalised by stripping legal suffixes and resolving spelling variants). This normalisation layer is the most critical step: the quality of matching depends entirely on it.

Layer three: matching algorithm and gap detection. For each reconstructed Salesforce-Stripe pair, the system compares four critical dimensions: existence (does the Closed Won opportunity have a subscription?), amount (do the amounts match, within prorata tolerance?), status (are the statuses consistent?), and dates (are start and end dates aligned within an acceptable window?). Each detected gap is classified into one of the four families described above, and enriched with an estimated financial impact.

Layer four: gap report and targeted human review. The nightly report surfaces only the cases requiring human attention. Perfectly reconciled transactions don't appear. Gaps are sorted by descending financial impact. For each gap, the context is displayed: what Salesforce knows, what Stripe knows, the calculated discrepancy, the classification, and a suggested correction. The reviewer isn't doing reconciliation work: they're validating or rejecting proposals.

This architecture brings monthly reconciliation time down from three to eight hours to thirty to sixty minutes of human validation. It covers 100% of transactions, not a sample. And it catches discrepancies within 24 hours, not at month-end close.

What continuous reconciliation makes possible

Beyond gap detection, a continuously reconciled Salesforce-Stripe dataset produces three structural improvements in financial data quality.

Reliable ARR. When the data is reconciled, the ARR calculated from Stripe matches the ARR expected from Salesforce. Business metrics rest on coherent data, not on the best available approximation.

Real-time churn detection. The moment a Stripe subscription is cancelled or a payment fails persistently, the system can flag that the corresponding Salesforce opportunity is still marked Active. The account executive has the information before the customer slips off the radar for three months.

Accurate MRR provisions at close. Month-end accounting provisions for unbilled revenues or outstanding credits can be calculated from a reconciled view of both systems, rather than estimated from a CRM export whose freshness is uncertain.

For teams preparing a fundraise, an audit, or an acquisition process, the ability to present ARR and MRR metrics reconciled line-by-line between the commercial CRM and the billing system is an operational maturity signal that investors and acquirers know how to read.


Sources: Stripe API documentation, Salesforce AppExchange, MGI Research, ScaleXP (2025).

Salesforce + Stripe: why your data drifts and how to reconcile it automatically | Tie-Out