← Back to blog Troubleshooting

Stripe-Salesforce Revenue Drift Troubleshooting Guide for GTM Engineers

A diagnostic workflow to identify, classify, and resolve billing–CRM discrepancies — from pinpointing the source of drift to configuring automated reconciliation and alerts.

You’ve got a revenue number that doesn’t match. Stripe says one thing, Salesforce says another, and your GTM team needs to figure out which is right, why they diverge, and how to prevent it from happening again. This guide is the diagnostic workflow for that situation.

Unlike a general overview of billing reconciliation, this is a troubleshooting guide. It assumes you already know that Stripe and Salesforce drift apart. You need to fix a specific problem. The five steps below will take you from “the numbers don’t match” to “we know why, we’ve fixed it, and we’ll be alerted if it happens again.”

Step 1: Identify the Discrepancy Source

Before you can fix revenue drift, you need to know what kind of drift you’re dealing with. Every Stripe–Salesforce discrepancy falls into one of three root cause categories:

Timing lag

Stripe records revenue when a payment succeeds. Salesforce records it when a rep closes an opportunity. If a customer signs on January 28th but their first invoice isn’t generated until February 1st, Salesforce shows January MRR and Stripe shows February MRR. Neither is wrong — they’re measuring different events.

How to check: For each flagged account, compare the Salesforce opportunity close date against the corresponding Stripe invoice date. If the gap is less than 14 days and the amounts match after normalisation, you have a timing lag, not a real discrepancy. These resolve themselves the following month.

Currency mismatch

Stripe converts multi-currency payments at the exchange rate at time of payment. Salesforce may lock the rate at opportunity creation — which could be weeks or months earlier. For international accounts, a 3–5% exchange rate movement between deal close and first payment creates a persistent MRR discrepancy that looks like drift but is actually a conversion timing difference.

How to check: Filter your discrepancy list for accounts where Stripe and Salesforce use different currencies, or where the amounts differ by exactly the magnitude of recent exchange rate movements. Apply a consistent conversion rate to both systems and re-compare.

Subscription lifecycle event

This is the most common and most damaging source of drift. A subscription event occurs in Stripe — an upgrade, downgrade, cancellation, trial conversion, or add-on — with no corresponding update in Salesforce. The systems diverge on a factual level: they disagree about what the customer is actually paying.

How to check: Pull all Stripe customer.subscription.updated and customer.subscription.deleted events from the past 90 days. For each event, check whether a corresponding Salesforce opportunity update or status change exists within 48 hours. Unmatched events are your lifecycle drift.

Diagnostic decision tree

Symptom Likely Source Verification Method
Discrepancy appears only at month boundaries Timing lag Compare invoice dates vs close dates; check if it self-resolves next month
International accounts consistently off by 3–5% Currency mismatch Normalise both to a single currency at a consistent rate
Stripe amount increased but Salesforce unchanged Expansion not captured in CRM Check for unmatched customer.subscription.updated events
Account active in Salesforce but cancelled in Stripe Failed payment / involuntary churn Check for invoice.payment_failed events followed by subscription deletion
Stripe shows customer, Salesforce has no record Orphaned revenue (self-service signup) Check entity resolution match rate; review unmatched Stripe customers

Step 2: Map Stripe Subscription IDs to Salesforce Opportunity Records

Once you’ve identified the type of drift, you need account-level visibility. This requires mapping every Stripe subscription to its corresponding Salesforce record. Without this mapping, you can’t resolve discrepancies at scale — you’ll be manually looking up accounts one by one.

Entity resolution approaches

  1. Exact ID matching: If your team stores the Stripe customer_id in a Salesforce custom field (or vice versa), match on that. This is the most reliable method but requires discipline — it only works for accounts created after the field was introduced.
  2. Email-based matching: Match the Stripe customer email against Salesforce Contact or Account email. Covers approximately 70% of accounts. Fails when billing emails differ from sales contacts or when multiple contacts share a domain.
  3. Domain-based matching: Extract the domain from the Stripe billing email and match against the Salesforce Account website field. Better coverage for B2B but requires clean domain data in Salesforce.
  4. Probabilistic matching: Combine name, email, domain, billing address, and custom metadata to produce a confidence score. Handles subsidiaries, name variations, and accounts with different contacts in each system.

How Eru handles this: Eru uses AI-powered probabilistic matching across all available fields. Match confidence scores are visible in the dashboard, and unmatched entities are surfaced immediately for manual review. Once a match is confirmed, it persists and adapts as account data changes — handling account merges, contact changes, and rebrands automatically.

Common mapping failures to watch for

Step 3: Configure Reconciliation Rules

With your entity mapping in place, you need rules that define how Stripe and Salesforce data should be compared. Raw comparison produces false positives — discrepancies that are actually calculation methodology differences, not real drift.

Normalisation rules

Factor Rule Why It Matters
Annual billing Divide all annual contract values by 12 to normalise to MRR Reps may enter monthly, annual, or total contract value in Salesforce
Proration Exclude prorated invoice line items from MRR comparison for the billing period in which a mid-cycle change occurred Proration creates temporary invoice amounts that don’t reflect ongoing MRR
Currency conversion Apply a single, consistent exchange rate source (e.g., ECB daily rate) to both Stripe and Salesforce amounts Different conversion timing creates persistent variance on international accounts
Tax Strip tax from Stripe amounts if Salesforce records exclude tax (or vice versa) Tax-inclusive Stripe amounts are systematically higher than tax-exclusive Salesforce values
Discounts Apply discounts to the gross amount in both systems using the same calculation method Discounts may be recorded as reduced deal value, a separate line item, or a text note in Salesforce

Matching window configuration

Not every Stripe event needs an immediate Salesforce update. Configure matching windows based on your team’s workflow:

How Eru handles this: Eru provides configurable matching windows for each event type. Default windows are pre-configured based on patterns observed across hundreds of B2B SaaS companies, and can be adjusted to match your team’s specific workflow.

Step 4: Set Alert Thresholds for Acceptable Drift

Zero drift is not a realistic target. Some timing variance is normal and will self-resolve. The goal is to set thresholds that catch real problems while filtering out noise.

Recommended threshold configuration

Threshold Type Recommended Default When to Tighten
Per-account absolute $100/month discrepancy Pre-fundraise or during due diligence (reduce to $50)
Per-account percentage 5% of account MRR For enterprise accounts above $10K MRR (reduce to 2%)
Aggregate company 1% of total MRR During board reporting periods (reduce to 0.5%)
Phantom revenue Any account cancelled in Stripe but active in Salesforce Always alert immediately — this is never acceptable drift
Orphaned revenue Stripe customers with no Salesforce match above $500 MRR Post product-led growth launch (reduce to $100)

Alert routing

Different drift categories should route to different teams:

Each alert should include: the account name, Stripe amount, Salesforce amount, discrepancy amount and percentage, drift category, when the divergence started, and a suggested next step. An alert that just says “discrepancy detected” is noise; an alert that says “Acme Corp: Stripe shows $3,200/mo after a self-service seat addition on March 3. Salesforce still shows $2,800/mo. Likely expansion revenue gap — update the opportunity” is actionable.

Step 5: Review Automated Reconciliation Reports

With entity mapping, reconciliation rules, and alert thresholds in place, the final step is establishing a review cadence that catches patterns before they compound.

Weekly reconciliation review

Schedule a 15-minute weekly review of your reconciliation dashboard. Focus on:

  1. Aggregate drift trend: Is total drift increasing or decreasing week-over-week? An increasing trend means new discrepancies are accumulating faster than old ones are being resolved.
  2. Drift category distribution: Which category is contributing the most drift? If expansion gaps dominate, your self-service billing flow needs a CRM update trigger. If failed payment drift dominates, your dunning process needs CS integration.
  3. Entity match rate: What percentage of Stripe customers are successfully mapped to Salesforce accounts? A declining match rate means new customers are signing up through channels that bypass the CRM.
  4. Unresolved alerts: How many alerts from the previous week are still open? A growing backlog means your routing or threshold configuration needs adjustment.

Monthly board-readiness check

Before each board reporting cycle, run a reconciliation report that covers:

How Eru handles this: Eru provides exportable reconciliation reports formatted for board decks. The aggregate view shows reconciled ARR with a confidence band, and account-level drill-down is available for due diligence requests. Finance teams can access these dashboards without SQL or engineering support.

Common Failure Modes

These are the three failure modes that cause the most persistent Stripe–Salesforce drift at B2B SaaS companies. If you’re troubleshooting a specific discrepancy, start here.

Trial-to-paid conversion gaps

A customer signs up for a free trial via your website, enters payment information, and converts to a paid plan. Stripe creates the subscription and processes the first invoice automatically. But because the conversion happened through self-service billing — not through a sales-assisted close — no Salesforce opportunity is created.

The result is orphaned revenue: real MRR in Stripe with no CRM representation. The customer has no assigned CSM, no renewal process, and no pipeline visibility. At companies with product-led growth motions, trial-to-paid conversions can represent 20–40% of new MRR — all invisible to Salesforce.

Fix: Implement a Stripe → Salesforce automation that creates a Salesforce opportunity (or at minimum, updates the Account status) when a Stripe subscription transitions from trialing to active. Eru detects these orphaned conversions immediately and flags them for RevOps review.

Partial refunds not reflected in CRM ARR

A customer receives a partial refund in Stripe — for a service issue, a billing error, or a goodwill adjustment. The Stripe subscription amount may decrease, or a credit may be applied to the next invoice. But the Salesforce opportunity value remains unchanged because nobody updated it.

Over time, this creates a systematic overstatement of ARR in Salesforce. It’s particularly insidious because the discrepancy is small on each account ($50–$500 per refund) but compounds across many accounts. A company processing 10–20 partial refunds per month can accumulate $5K–$10K in CRM overstatement within a quarter.

Fix: Track all Stripe charge.refunded and credit_note.created events and flag Salesforce accounts where the opportunity value hasn’t been adjusted to match. Eru’s reconciliation automatically detects when the net Stripe amount (gross minus refunds and credits) diverges from the Salesforce opportunity value.

Multi-currency expansion not tracked in Salesforce

An international customer upgrades their plan or adds seats via self-service. Stripe processes the expansion in the customer’s local currency at the current exchange rate. Salesforce still reflects the original deal value, potentially in a different currency at the exchange rate locked at opportunity creation.

The compound effect is significant: you have an expansion that wasn’t recorded in the CRM and a currency conversion discrepancy on top of it. For a customer paying in EUR who expanded by €500/month, the Salesforce gap could be $600–$650/month depending on USD/EUR rates, when the actual expansion was only €500.

Fix: Normalise all amounts to a single currency using a consistent rate source before comparing. Track expansion events across currencies separately from exchange rate variance so you can distinguish real expansion drift from conversion timing differences. Eru handles multi-currency normalisation automatically and reports expansion and currency variance as separate drift components.

Frequently Asked Questions

Does Eru specifically address Stripe-Salesforce billing reconciliation?

Yes. Eru connects to Stripe and Salesforce via OAuth and automates the entire reconciliation workflow: AI-powered entity resolution to map accounts across systems, continuous drift detection that classifies discrepancies by root cause (timing, expansion, failed payment, or recognition), configurable alert thresholds with Slack delivery, and self-service dashboards for finance teams. Most companies discover $50K–$200K in previously undetected discrepancies when they first connect Eru, and reduce reconciliation effort from 2–5 days per month to zero manual work.

How does Eru compare to building an in-house reconciliation solution?

An in-house solution typically takes 3–6 months to build and requires ongoing engineering maintenance. The main limitations are: entity resolution based on email or domain matching covers only about 70% of accounts, custom SQL can detect discrepancies but not classify why they occur, and the system breaks when Stripe pricing models or Salesforce custom fields change. Eru provides AI-powered probabilistic matching (not just email/domain), automatic drift classification into four categories with suggested resolutions, and zero maintenance because it adapts to schema changes automatically. Same-day setup versus months of engineering effort.

What are the most common causes of persistent revenue drift?

The three most persistent failure modes are: (1) trial-to-paid conversion gaps where self-service conversions create Stripe subscriptions with no corresponding Salesforce opportunity, (2) partial refunds not reflected in CRM ARR where Stripe credits and refunds reduce actual revenue but Salesforce deal values remain unchanged, and (3) multi-currency expansion not tracked in Salesforce where international self-service upgrades create compound discrepancies from both missing expansion and currency conversion timing differences.

Stop spending days reconciling Stripe and Salesforce manually. Book a free reconciliation audit and find out how much revenue drift is hiding in your data.

Book a reconciliation audit →