Mixpanel has no revenue switch to turn on. Revenue is data you send it, and how you send it decides what you can report on later. There are three ways in, and most teams use one or two of them:
- Send a purchase event from your own code, with the amount as a property.
- Forward Stripe's webhooks to Mixpanel through a small cloud function.
- Load subscription revenue from your data warehouse, for MRR and churn.
This guide walks through each, then the step most guides skip: tying a payment back to the channel that brought the customer in. Everything here comes from Mixpanel's documentation, read on 19 October 2026. Mixpanel changes often, so check the docs as you go.
We make Spreelytics, a different analytics tool, and say at the end how it handles the same job.
The short answer
If you sell one-off purchases, send a purchase event with the amount on it, from your server once the payment has succeeded. If you bill through Stripe and want every charge, refund and invoice, forward Stripe's webhooks. If you need MRR, churn and upgrades, load monthly snapshots from your warehouse. In every case, make sure the payment lands on the same person as their earlier visits, or you will not know which channel earned it.
1. Send a purchase event
Mixpanel's own guide treats a purchase as an ordinary event with the amount as a property. Its
example is an event named Purchase completed with item and price properties. In the browser
SDK it looks like this:
mixpanel.track('Purchase completed', {
item: 'Pro plan',
price: 49,
currency: 'USD',
});
A few things make this event far more useful later:
- Send it once the payment has succeeded. A track call on the "thank you" page counts people who reloaded it, and misses people who closed the tab. Sending it from your server when the payment is confirmed counts each sale once.
- Add the fields you will want to group by. Mixpanel's revenue guide suggests the amount, the currency, the plan and a user or account id.
- Convert currencies before you sum them. For payments in several currencies, the guide suggests
sending a base currency and the converted amount (
base_currencyandbase_ccy_amount) next to the original, and summing the converted one. - Keep the names plain. Mixpanel reserves names that start with
$ormp, so avoid those for your own properties.
With that event in place, you build the numbers yourself. Total revenue is the sum of the amount property in an Insights report. Average order value is that sum divided by the number of purchases, and revenue per user divides it by unique users. Lifetime value uses the property sum option in the Retention report, and the Funnels report can sum the amount at each step.
Refunds are the weak spot. A purchase event records the sale, and nothing changes it if the money is returned later. Either send a refund event with a negative amount and include it in your sums, or load purchases from your warehouse with Mirror Mode on, which keeps Mixpanel in step when past rows change.
2. Forward Stripe webhooks
If you bill through Stripe, Mixpanel's docs include a recipe that sends every Stripe event to Mixpanel as it happens. It is a short Python function you deploy yourself, on Google Cloud Functions in the guide, or AWS Lambda if you adapt it. The steps are:
- Create a cloud function with an HTTPS trigger that allows unauthenticated calls, because Stripe calls it directly.
- Paste in the code from the guide and deploy it.
- In Stripe, add a webhook that points to the function's address, with your Mixpanel project token
added as a
tokenparameter.
The function posts each Stripe event to Mixpanel's /import endpoint, using the Stripe event type as
the event name and the whole Stripe object as properties. The guide suggests subscribing to every
Stripe event and filtering in Mixpanel later.
Know what you are taking on:
- The whole Stripe object goes to Mixpanel. That can include fields you did not mean to share. Trim it in the function if that matters.
- There is no retry logic or logging. The function passes back whatever Mixpanel answers, so watch your Stripe webhook log for failed deliveries.
- Past payments are not included. The webhook only sees new events. Mixpanel points to its BigQuery and Snowflake warehouse connectors for history.
- Payments arrive on a separate identity. The function sends the Stripe customer id as
$device_id. Mixpanel only joins events to a person when they share an id, and your site does not know the Stripe customer id, so these payments do not join the visits that came before them unless you change the function. More on that below.
If you would rather not run code, Mixpanel's docs point to Vendo, a third-party integration, and Zapier can track a purchase event in Mixpanel when Stripe records a charge.
3. Load subscription revenue from your warehouse
For a subscription business, a purchase event is the wrong shape. MRR, churn and upgrades come from how much each customer pays this month compared with last month.
Mixpanel's answer is a monthly snapshot of each customer's revenue, stored as a historical profile property, with the account set to zero the month after it leaves so it counts as churned. From those snapshots it works out each change as new, upgrade, downgrade, churn or flat, and builds net revenue retention, MRR churn and MRR growth.
The catch is how the snapshots arrive. They come in through Mixpanel's Warehouse Connectors, and in the docs' own words, "Only customers using the Warehouse Connectors get access to these features." So you need your billing data in a warehouse such as BigQuery or Snowflake first.
Tie each payment to its channel
Revenue in Mixpanel tells you how much. Which channel earned it is a separate step, and it only works if two things are true.
The payment must land on the same person as their visits. The visit that came from a Google ad carries its UTM tags on that browser's events. The purchase has to arrive on the same person, or the two never meet. In practice:
- Call
mixpanel.identify()with your own user id when someone signs up or logs in, so their earlier anonymous visits join their profile. - Send the purchase event with that same user id. From your server, that means the server-side SDK or
/importwith the user id, not a new anonymous id. - If you use the Stripe recipe, store your user id on the Stripe customer, for example in its metadata, and change the function to send it in place of the Stripe customer id.
You need an attribution model. Mixpanel has nine, including time decay and custom ones, on its paid plans. On the free plan you can still break revenue down by a UTM property, but the credit then follows whatever that property holds on the purchase itself.
A quick test catches most mistakes. Open your site from a link with a made-up UTM campaign, buy something with a test card, then open that person's profile in Mixpanel. If the visit and the purchase sit on the same timeline, the join works.
How Spreelytics does the same job
We built Spreelytics around this exact question, so the plumbing is shorter. Connect Stripe, Paddle, Polar or Lemon Squeezy in Settings → Revenue and the webhook is created for you. Every payment and refund then arrives on its own, and past payments can be imported. If you sell subscriptions, the Revenue page works out MRR and ARR from each charge's billing period, with no warehouse in between. It does not break out churn, upgrades or downgrades the way Mixpanel's warehouse setup can. SaaS analytics shows how MRR, attribution, funnels and retention fit together.
To tie a payment to its visit, you pass the visitor id into your checkout's metadata on the server. Each payment is then credited to the channels that brought the buyer in, by last-touch or linear attribution, on every plan including Free. The whole setup, with the code, is in how to see which channel earned each Stripe payment.
Mixpanel goes much further on product analysis, with feature flags and experiments, and we have neither. It also puts session replay on its free plan, where ours comes with Growth. If you are weighing the two, see Spreelytics vs Mixpanel and Mixpanel pricing. If you are choosing between Mixpanel and its closest rival, see Mixpanel vs Amplitude.