Skip to main content

How to track Stripe revenue in your A/B tests in Mida

Connect Stripe once and Mida shows revenue, revenue per visitor (RPV) and average order value (AOV) for every variant of your experiment. You don't need to write any tracking code for the payment itself.

How it works

The short version: Stripe sends every payment to Mida. Mida finds the visitor who paid, saves the payment as a Purchase event on that visitor, and your experiment reads those events to show conversions, revenue, RPV and AOV per variant.

1. The connection

When you connect, Mida creates a webhook endpoint in your Stripe account. It is a URL unique to your project. Stripe calls it each time something happens in these four events:

Stripe event

What Mida uses it for

payment_intent.succeeded

The money. The amount and currency of a successful payment. This is what creates the Purchase.

checkout.session.completed

Who paid. The visitor ID, if you passed one, and the customer's email from Stripe Checkout.

invoice.paid

Subscriptions. Tells a first payment from a renewal.

charge.refunded

Refunds. Reduces the revenue of the original payment.


​
​

Every request is signed by Stripe. Mida checks the signature with your webhook signing secret before it reads anything, and rejects anything it can't verify. Events from the other mode (test or live) are ignored.
​

Mida only uses a restricted, read-only key. It is encrypted at rest and is used to set up the webhook and to look up a Checkout session when needed. It can't charge customers or move money.

2. From payment to Purchase event

  1. Stripe sends payment_intent.succeeded with the amount.

  2. Mida keeps one record per payment, keyed by the Stripe PaymentIntent ID. Stripe can resend an event or deliver events out of order. Neither creates a duplicate, and if the visitor info arrives after the money, Mida fills it in then.

  3. Mida looks up the visitor by ID inside your project. It never creates visitors, so a payment can't add to your monthly tracked users.

  4. If a visitor is found, Mida writes a Purchase event on that visitor with the revenue, the currency and the payment ID. This is the same kind of event your own code or Shopify would send.

  5. If no visitor is found, the payment is saved as Unattributed and is not scored.

3. How Mida knows who paid

Stripe doesn't know about your experiment, so the visitor's ID has to travel with the payment. These are the four ways it can:

Situation

What carries the ID

Stripe Payment Link or buy button

The Mida tag adds client_reference_id=<visitor id> to the link when the page loads and again at click. Stripe sends it back with the payment. No code needed.

Your own checkout

Your server reads the visitor ID (the optimize_uuid cookie, or mida.uuid() in the browser) and sets metadata.mida_uuid when it creates the payment. A few lines of code.

Thank-you page

If the redirect URL ends with ?session_id={CHECKOUT_SESSION_ID}, the tag sends that session ID and the visitor ID to Mida. This catches payments the first two missed.

Email

If the visitor was identified with their email earlier, Mida matches the buyer's email. This is the weakest method and it does not work on free plans.

If more than one is present, Mida trusts them in this order: payment metadata, then the link ID, then the thank-you page, then email. A subscription renewal reuses the visitor from the subscription's first payment, so it needs no ID of its own.

4. How results are calculated

  • Your experiment's Revenue goal reads the Purchase events.

  • Mida joins each Purchase to the experiment by visitor. Only visitors who were exposed to the experiment, and who paid after they saw it, are counted.

  • Conversion is the share of exposed visitors with a Purchase. Revenue is the sum of their payments after refunds. RPV is revenue per exposed visitor. AOV is revenue per order.

  • Payments in other currencies are converted into your project currency when the report runs.

  • Reports update in 5-minute steps, so a new payment can take a few minutes to show up.

Steps to integrate

Before you start

  • The Mida tracking code is installed on your website.

  • You are an Owner or Admin in Mida.

  • You have a Stripe account. You can start in test mode.

  • Stripe works on all Mida plans.

Step 1. Create a Stripe key

Mida needs a restricted key. It can read payments and nothing else.

  1. In Stripe, go to Developers → API keys → Create restricted key.

  2. Set these permissions:

Permission

Access

Payment Intents

Read

Charges

Read

Checkout Sessions

Read

Invoices

Read

Subscriptions

Read

Customers

Read

Account

Read

Webhook Endpoints

Write

Lastly, Create the key and copy it. It starts with rk_test_ (test mode) or rk_live_ (live mode).

The Webhook Endpoints: Write permission lets Mida set up the connection for you. Without it you can still connect. See No webhook permission? below.

Step 2. Connect Stripe in Mida

  1. Go to Integrations and find Stripe under Payments.

  2. Click Connect Stripe, then Enable Stripe Integration.

  3. Open the Config tab, paste your key and click Test & Connect.


    Mida checks the key and creates the webhook in your Stripe account. When it works you see a green Connected label.

This screen shows:

  • TEST or LIVE, depending on your key.

  • Attributed: payments matched to a visitor and counted.

  • Unattributed: payments Mida could not match. They are not counted.

  • Recent transactions: each payment, its status and the experiment it belongs to.

The payments in these screenshots are example data.

No webhook permission?

If your key can't create webhooks, Mida shows Waiting for webhook secret. Do this once:

  1. Click Copy next to the URL.

  2. In Stripe, go to Developers → Webhooks → Add endpoint and paste the URL.

  3. Select these 4 events: payment_intent.succeeded, checkout.session.completed, invoice.paid, charge.refunded.

  4. Save the endpoint, copy its signing secret (starts with whsec_), paste it into Mida and click Save secret.

Payments are not recorded until the signing secret is saved.

Step 3. Pass the visitor ID

Mida can only count a payment if it knows which visitor paid. The visitor ID is called the Mida visitor ID (mida_uuid). Whether you have to pass it yourself depends on how your customers pay.

Find your case:

How customers pay

Do you pass the visitor ID?

What to do

Payment Link or Buy button on a page that has the Mida code

No

Nothing. The Mida code adds the ID to the link for you.

Payment Link opened from outside your site (email, ad, social post)

Can't

The link is not on a page with the Mida code, so it has no ID. The thank-you page backup below can still match the payment, but only if the visitor already browsed your site in that same browser.

Stripe Checkout created by your server

Yes

Set client_reference_id and metadata.mida_uuid (see code).

Custom payment form (Stripe Elements or Payment Intents)

Yes

Set metadata.mida_uuid on the PaymentIntent (see code).

Subscriptions created by your server

Yes

Set metadata.mida_uuid on the subscription (see code). Renewals reuse it.

Invoices, phone orders, charges created by your team

No visitor exists

These show as Unattributed, unless the customer's email matches a visitor you identified.

Payment Links and Buy buttons (no code)

The Mida code finds every buy.stripe.com link and <stripe-buy-button> on the page and adds the visitor ID. It does this when the page loads, and again at the moment of click, so links added later are covered too.

For this to work:

  • The Stripe integration is enabled in Mida (Step 2).

  • The Mida code is on the page that has the link.

  • The visitor clicks the link from that page.

Where to get the visitor ID

You only need this for your own checkout, custom forms and subscriptions.

  • On your server: read the optimize_uuid cookie, for example req.cookies.optimize_uuid.

  • In the browser: call await mida.uuid(), then send the value to your server with your checkout request.

If your site waits for cookie consent, the cookie may not exist yet. Use mida.uuid() in the browser and send it to your server.
​

// Browser: send the visitor ID with your checkout request
const midaUuid = await mida.uuid();
fetch('/create-checkout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ midaUuid }),
});


Your own checkout

// Server: create the Checkout session
stripe.checkout.sessions.create({
// ...your usual settings
client_reference_id: midaUuid,
metadata: { mida_uuid: midaUuid },
payment_intent_data: { metadata: { mida_uuid: midaUuid } },
// Subscription mode only:
// subscription_data: { metadata: { mida_uuid: midaUuid } },
});


Custom payment form

stripe.paymentIntents.create({
// ...your usual settings
metadata: { mida_uuid: midaUuid },
});


Subscriptions

stripe.subscriptions.create({
// ...your usual settings
metadata: { mida_uuid: midaUuid },
});
The first payment is linked to the visitor. Each renewal reuses that visitor, so renewals need no ID of their own.


Backups

These catch payments the methods above missed. Set them up on top of the main method, not instead of it.

  • Thank-you page. In Stripe, set the after-payment redirect to a page that has the Mida code, ending with ?session_id={CHECKOUT_SESSION_ID}. When the visitor lands there, the Mida code sends the session ID and the visitor ID to Mida. It works for Payment Links and Checkout, in the same browser the visitor used to start.
    ​

  • Email. If you already call mida.identify({ email }) for your visitors, Mida can match the buyer's email. This is the weakest method and it does not work on free plans.

Check that it worked

  1. Open your site in a browser where you are in an experiment.

  2. Make a test payment with Stripe's test card 4242 4242 4242 4242.

  3. Open the Stripe card in Integrations and look at Recent transactions.

  4. The payment should show Attributed, with the experiment and variant. The Link column shows how it was matched: metadata, client_reference_id, handoff or email.

If it shows Unattributed, the ID didn't reach Stripe. Re-check your case in the table above.


How to use in Mida

1. Create a Revenue goal

  1. Open the Stripe card in Integrations, go to the Info tab and click Use as conversion goal. This opens a Revenue goal for you. You can also go to Metrics and create a new goal with the Revenue type.
    ​

  2. Keep the name "Stripe revenue", or change it. Click Save Goal.

2. Use it in your experiment

Set the Revenue goal as the experiment's main goal. You can also add it as a secondary metric to an experiment that has a different main goal.
​

Connecting Stripe does not change any experiment by itself. Only experiments that use the Revenue goal read Stripe payments.
​

3. Read your results

For each variant you see conversion rate, revenue, RPV and AOV. With a Revenue goal, a visitor counts as converted once a Stripe payment is linked to them.
​

A payment counts when all of these are true:

  • Mida matched it to a visitor.

  • That visitor was in the experiment and saw it before paying.

  • It is a first payment, or you turned on renewals (see below).

  • A 5-minute reporting step has passed. New payments show up within a few minutes.


Heads up

  • Use one source of purchases per project. If you also send Purchase events from Shopify or your own code, revenue is counted twice.

  • Refunds lower the revenue of that payment. The conversion stays. A full refund makes the revenue zero.

  • Subscriptions. The first payment always counts. Renewals do not count by default. To count them, switch on Count subscription renewals as revenue in the Settings box on the Config tab. It applies to payments received after you switch it on.

  • Test and live mode. Mida follows your key. A TEST connection only reads test payments and a LIVE connection only reads live payments. To switch, click Disconnect and connect again with the other key.

  • Currencies. Payments in other currencies are converted into your project currency.

  • Rotate key. Click Rotate key and paste a new key whenever you replace the key in Stripe.

  • Disconnect. Click Disconnect to delete the key from Mida. If Mida created the webhook for you, it is removed from Stripe too. If you added it by hand, delete it in Stripe yourself. Your payment history stays.

  • Safety. Your key is encrypted and never shown again, only the last 4 characters. Mida never stores card details, only the amount, currency, payment ID and a hidden version of the customer's email.


Troubleshooting

What you see

What to do

Stripe rejected this key

Copy the key again. Check that it starts with rk_ or sk_ and that you pasted all of it.

Waiting for webhook secret

Follow No webhook permission? and save the signing secret.

No payments show up

Check the label. A TEST connection ignores live payments, and a LIVE connection ignores test payments.

Many Unattributed payments

The payment didn't carry the visitor ID. Check Step 3 and make sure the Mida code is on the page where the visitor pays.

Payment is Attributed but the experiment shows no conversion

The experiment's goal must be the Revenue goal. Also check that the visitor saw the experiment before paying.

Renewal (not counted)

Switch on Count subscription renewals as revenue if you want renewals counted.

Revenue looks too high

Another Purchase source is connected to the same project. Turn one off.

Still stuck? Contact us from the chat bubble and we'll help.

Did this answer your question?