Revenue attribution
Polar
Attribute Polar orders created through the Checkout API.
Snippets use YOUR_SITE_ID as a placeholder. Sign in and they're filled in with your real site id.
1. Connect Polar
- In VisitTrack, open Settings → Revenue and pick Polar.
- Copy the webhook URL shown there. It looks like
https://visitrack.app/api/polar-webhook/YOUR_SITE_ID. - In Polar: Settings → Webhooks → Add endpoint. Paste the URL and subscribe to
order.paidandrefund.created. - Copy the webhook secret Polar gives you back into VisitTrack and press Connect. It's stored encrypted and only used to verify signatures.
2. Pass the visitor id
Put it in the checkout's metadata. Polar copies checkout metadata onto the order it creates.
import { Polar } from "@polar-sh/sdk";
const polar = new Polar({ accessToken: process.env.POLAR_ACCESS_TOKEN });
const checkout = await polar.checkouts.create({
products: [productId],
successUrl: "https://example.com/thanks?checkout_id={CHECKOUT_ID}",
metadata: { visitrack_visitor_id: visitorId ?? "" },
});
return Response.json({ url: checkout.url });Fallback: customer external id
If the order carries no metadata, VisitTrack falls back to the customer's external_id. That only helps if you create Polar customers with the visitor id as their external id. Most apps use their own user id there, so prefer metadata.
Events
| Event | What VisitTrack does |
|---|---|
order.paid | Records the order (total_amount, currency, customer email) against the visitor in metadata.visitrack_visitor_id. |
order.created | Also recorded, but only when the order is already paid. |
refund.created | Subtracts the refunded amount from the original order. |
| anything else | Acknowledged with 200 and ignored. |
Signatures follow the Standard Webhooks spec. Deliveries more than 5 minutes old are rejected.
Test it
- Open your site in a normal browser tab so the tracker records a visit (localhost is ignored unless the script tag has
data-allow-local). - Complete a checkout in test mode.
- Open Revenue in the dashboard. The payment shows up within a few seconds, with the referrer, campaign and landing page that brought that visitor in.
Nothing showed up?
See Missing or unattributed payments. The webhook response body always says why a payment was skipped.
Something missing? Tell us.
AI agent or LLM? Read this page as markdown.