Why Stripe and GA4 revenue do not match
A diagnostic guide to the definitions, timing, refunds, currencies, identities, and processing differences behind Stripe and GA4 revenue gaps.
Stripe and GA4 can show different revenue for the same day, month, or customer journey even when both integrations are working. The usual reason is that the products were never measuring the same fact.
Stripe knows whether money was successfully collected and later refunded. GA4 knows whether your site or app sent a purchase event with a value and currency. Those records can line up, but they are not interchangeable.
Start with the direct answer
Treat Stripe as the financial total. Use GA4 revenue to validate purchase-event behavior and acquisition analysis.
Before comparing the numbers, write down both definitions:
Stripe comparison = successful paid charges - refunds
GA4 comparison = purchase-event value reported by the selected property
If your Stripe report includes subscriptions, one-off payments, and refunds while GA4 includes only browser-side checkout completions, the gap is expected.
Check the revenue definition first
“Revenue” can refer to several different measures:
- successful charges;
- paid invoices;
- checkout-session totals;
- payment-intent amounts;
- purchase-event value;
- net revenue after refunds;
- recognized accounting revenue;
- normalized recurring revenue.
Pick one operating definition and compare only records that belong to it. MRR should never be compared directly with GA4 purchase revenue: MRR is a subscription snapshot, while purchase revenue is a flow of transactions.
Revinho defines its operating view in the methodology: gross revenue is successful, paid, non-disputed Stripe charges; net revenue subtracts refunds.
Check payment status and asynchronous checkout
A browser can reach a “success” page before every commercial edge case has settled. Payments can require additional action, complete asynchronously, fail after an initial attempt, or be retried.
If the site sends a GA4 purchase event from the success page without confirming the server-side payment outcome, GA4 may record revenue that Stripe never successfully collects. The opposite also happens: a server-side payment succeeds after the visitor closes the browser, so Stripe has revenue but GA4 receives no final event.
The durable pattern is:
- Let Stripe confirm the commercial outcome.
- Make client and server event delivery idempotent.
- Use one stable transaction identifier to prevent duplicate purchase events.
- Reconcile payment records rather than trusting a single browser transition.
Check refunds and disputes
GA4 purchase events usually remain in historical analytics after a later refund unless your implementation sends and reports a corresponding refund event. Stripe, meanwhile, maintains the refund against the commercial record.
Imagine a customer pays €100 on July 4 and receives a €100 refund on July 20:
GA4 purchase-event value for July: €100
Stripe gross revenue for July: €100
Stripe refunds for July: €100
Stripe net revenue for July: €0
Nothing is necessarily broken. The reports answer different questions. Stripe documents that a refund occurs after a payment succeeds; Revinho keeps refunds visible instead of silently erasing the original charge.
Check duplicate and missing purchase events
GA4 revenue is only as reliable as the purchase-event implementation.
Common duplicate paths include:
- firing on every success-page refresh;
- firing once in the browser and again through a tag manager;
- resending without a stable transaction ID;
- recording the full order once per line item;
- replaying an event after a client retry.
Common missing paths include:
- consent preventing analytics storage;
- an ad blocker stopping the analytics request;
- navigation before the event is delivered;
- an asynchronous payment finishing after the session ends;
- a mobile or server purchase that never loads the tracked site.
Do not “fix” the mismatch by multiplying GA4 revenue to resemble Stripe. Fix the event contract, then keep Stripe as the ledger.
If a GA4 purchase or signup key event suddenly disappears while Stripe outcomes continue, follow the GA4 key-event outage diagnostic before treating the mismatch as a demand or checkout failure.
Check timezones and day boundaries
Stripe timestamps are stored in UTC. GA4 reports use the property's configured timezone. Your reporting layer may use a third timezone if the business workspace is configured differently.
A payment at 23:58 UTC can fall on the next calendar day in Europe or the previous day in the Americas. Daily charts will disagree even when a month total eventually matches.
Compare timestamps after projecting both records into one declared reporting timezone. Also avoid comparing an incomplete current day with a finalized Stripe ledger.
Check currencies and units
GA4 purchase events require a coherent value and currency. Stripe API amounts use integer minor units. Confusing 9900 cents with 9900.00 major units creates a 100× difference before exchange rates are considered.
For multiple currencies:
- preserve each original amount and currency;
- convert only at the reporting boundary;
- use a dated reference rate;
- label converted totals as estimates;
- never add USD and EUR minor units directly.
Revinho follows those rules and keeps native currency totals available for auditability.
Check processing and recent dates
GA4 reports can change while Google processes late and modeled data. Google's data-freshness documentation notes that processing can take 24–48 hours and that some data can arrive later.
When a mismatch appears only in yesterday's figures:
- Exclude today.
- Wait for the normal processing window.
- Compare again using the same timezone.
- Re-import the recent window rather than treating yesterday as immutable.
A persistent historical gap deserves an implementation audit. A moving gap in the most recent day may be ordinary processing.
A practical diagnostic sequence
Work in this order:
- Match the date range and timezone.
- Match the revenue definition.
- Separate gross revenue, refunds, and net revenue.
- Match currencies and minor-unit interpretation.
- Compare successful Stripe transactions with unique GA4 transaction IDs.
- Inspect duplicate and missing event paths.
- Recheck after provider processing has settled.
This order prevents a week of tag debugging when the real difference was a refund or midnight boundary.
What Revinho does with the mismatch
Revinho does not force GA4 revenue to equal Stripe. Stripe remains the source of truth for revenue, while GA4 remains the source for acquisition and on-site behavior.
The product can show that sessions, key events, and Stripe revenue moved during the same reporting period. That relationship is labeled associated unless a deterministic join exists. It is useful evidence for an investigation, not proof that a source generated the payment.