Skip to main content

Polar

Polar

Connect Polar to see which channel, campaign or page brought each payment — not just how much you earned.

Polar tells you what you earned. It cannot tell you what earned it.

Connect it and every payment is matched to the visit that led to it, so the revenue card breaks down by channel, campaign and landing page beside the traffic that produced it.

What you get

  • Payments attributed to a source. A sale traced back to the search, the post or the campaign that brought the customer.

  • The subscription goals, with no code from you — the full list covers trials, upgrades, downgrades, pauses, cancellations and churn.

  • MRR, with a yearly plan counted as its monthly equivalent rather than as a spike and then a crash.

  • Your history, imported once on connection — including its attribution, which is unusual and explained below.

Connecting

Create an access token

Settings → Developers → New Token, and tick five boxes:

ScopeWhat it is for
webhooks:writeSetting up event delivery
orders:readPayments and refunds
subscriptions:readMRR and churn
products:readProduct names
checkouts:readAttribution from your checkout

Tick webhooks:write first — it is the one that fails loudest and latest. A missing read scope shows up the first time that data is needed; a missing webhooks:write stops the connection from being made at all.

Nothing pre-ticks these. Polar has no equivalent of Stripe's permissioned link, so this list is the instruction.

screenshot coming

Polar's new-token dialog with the five scopes ticked: Webhooks (write) and read on Orders, Subscriptions, Products and Checkouts. Light theme, cropped to the scope list.

Find your organization ID

Settings → General → Profile, the field named Identifier — a UUID like 98897d14-e6e4-448b-9fa7-26c812cd7881.

You supply this rather than us picking it, because a token can reach several organizations and only you know which one this site sells through. It is also checked against the token, so a token pointed at a different organization is caught before any money is read.

Paste both into TrueStat

Settings → Integrations → Polar. The token is encrypted before it is stored, and the webhook is created for you.

screenshot coming

Site settings, Integrations tab: the Polar card with the Access token and Organization ID fields, before any connection. Light theme, cropped to the card.

Sandbox and production are different addresses. A sandbox token is refused by the production API with a plain "invalid token" that reads exactly like an expired one. The link in the connection screen already points at the right dashboard for your environment — use it rather than navigating there yourself.

Linking a payment to a visitor

Without this, payments still appear — but under Unattributed, because nothing connects the payment to the visit that led to it.

Our script stores a visitor id in a cookie. How you pass it to Polar depends on how your checkout opens:

Checkout API

Your server creates the session and sets the metadata.

Checkout links

A buy button on your page, with no server call of your own.

Other methods

A shared link's checkout id, or matching on e-mail.

On Polar, metadata reaches your history too. Its API returns checkout metadata on listed orders, so payments made before you connected arrive already attributed — which no other provider we support can do.

What the numbers mean

  • Amounts include tax. A €100 sale with €20 VAT is recorded as €120, matching what Polar shows.

  • Fees are recorded, not subtracted. Polar is the merchant of record, so its fee is stored beside the amount — the revenue figure is the gross, which is the number that reconciles with your dashboard.

  • A plan change is counted as the difference. Moving a customer from $29 to $79 records $50 of new MRR, not $79 — the $29 was already there.

A downgrade can produce a negative payment, and it is real.

Moving to a cheaper plan makes Polar issue a credit for the unused time, and that credit arrives as an order with a negative total. It is not a refund: nothing was returned to the card, the charge and the credit simply cancel out.

You will see both rows. Their sum is what the customer actually paid, and it is what your Polar dashboard shows.

screenshot coming

The Revenue card with a Polar connection: total, new versus renewal, and refunds over the selected range. Light theme, cropped to the card.

Your history comes with you

Connecting imports the organization's past orders and subscriptions, so the dashboard is not empty on day one.

Polar's history keeps its attribution

This is the one place Polar does better than the others. Its API returns the checkout metadata on a listed order, so imported payments arrive already matched to the visit that produced them — as far back as your records go.

Stripe, Paddle and LemonSqueezy all lose that on import: their listed objects carry no metadata, so history lands under Unattributed and attribution starts from the first payment after connecting.

screenshot coming

The revenue breakdown by channel shortly after connecting Polar, with imported payments already carrying a source rather than sitting under Unattributed. Light theme, cropped to the breakdown.

Re-syncing later

Settings → Integrations → Polar → Re-sync history rebuilds payments and subscriptions from the organization.

It is safe to repeat: a payment already recorded is not counted twice. Your recorded lifecycle events — upgrades, pauses, trial conversions — are kept as they happened, because no provider can reproduce when they happened after the fact.

Disconnecting

Settings → Integrations → Polar → Disconnect removes the webhook from your organization, deletes the stored token, and clears the revenue this connection wrote. Your pageviews and goals are untouched.

If something is not working

The token was refused. Usually the environment: a sandbox token cannot read production, and the error does not say so. Check which dashboard you created it in.

The connection failed while creating the webhook. webhooks:write was not ticked. Tokens cannot be edited — create a new one with all five scopes.

Payments arrive but everything is Unattributed. The checkout is not passing ts_vid in its metadata. Check that you read window.truestat.visitorId at click time rather than at page load.

A payment is missing. Only orders that actually collected money are recorded — an order still pending, and the zero-amount order Polar writes when a free trial starts, are not revenue and are deliberately skipped.

Was this page helpful?

Last updated September 9, 2026