Polar
Connect Polar with an organization access token and attribute orders and subscriptions.
Connecting Polar imports your payments, refunds and subscriptions into Trakily and keeps them in sync. Trakily only reads data; it never creates charges or changes anything in your Polar account. Read Revenue attribution first if you haven't.
1. Create a organization access token
- 1
Polar → Settings → Developers → New token
- 2
Scopes: orders:read, subscriptions:read
- 3
Paste the token here (production or sandbox are both detected)
Direct link: polar.sh/dashboard
Production and sandbox tokens are both detected automatically.
2. Connect it in Trakily
- 1
Open your site's Settings → Revenue (owners only) and click Connect next to Polar.
- 2
Paste the organization access token, then click Connect Polar. Trakily checks the key.
- 3
The first sync imports your full history in the background. After that, Trakily pulls changes every 15 minutes, and webhooks deliver new payments within seconds.
Keys are encrypted at rest and only used to read payments. Test-mode and live keys both work; a test key only sees test data.
3. Webhook for real-time updates
Polar webhooks are added by hand. They are optional: without one, new payments still arrive with the next sync (every 15 minutes).
In Polar, open your organization's Settings → Webhooks, add an endpoint with the URL below, select the events listed, and copy the endpoint's secret.
https://trakily.com/api/webhooks/polar/pls_…
Events to send:
order.paidorder.refundedsubscription.createdsubscription.updatedsubscription.canceledsubscription.revokedPaste the endpoint's signing secret into the Webhook card in Settings and click Save (you can also add it while connecting). Every webhook is verified with that secret; requests that don't match are rejected.
4. Pass the visitor id at checkout
Read the ids from Trakily's cookies on your server and pass them as checkout metadata. Trakily reads metadata.trakily_visitor_id and metadata.trakily_session_id from orders and subscriptions.
// Read Trakily's ids on your server (Next.js example)
import { cookies } from "next/headers";
const jar = await cookies();
const visitorId = decodeURIComponent(jar.get("_trakily_vid")?.value ?? "").split("|")[0];
const sessionId = jar.get("_trakily_sid")?.value ?? "";
await polar.checkouts.create({
products: ["<product id>"],
successUrl: "https://yoursite.com/thanks?checkout_id={CHECKOUT_ID}",
metadata: { trakily_visitor_id: visitorId, trakily_session_id: sessionId },
});The keys are always trakily_visitor_id and trakily_session_id. The visitor id is the first part of the _trakily_vid cookie (before the first |); the session id is the _trakily_sid cookie. If the session id is missing, Trakily uses the visitor's latest session before the payment.
Success page detection
Use checkout_id={CHECKOUT_ID} in your success URL as in the example. Polar fills in the id and the script reports it from your thank-you page.
Troubleshooting
- “This Polar token can't read orders.” Create a new token with the
orders:readandsubscriptions:readscopes. - “Polar rejected this token.” The token is invalid or expired; create a new one.
- Payments arrive but show as unattributed. Pass the visitor id at checkout (step 4). Payments that can't be matched yet are retried every hour for 90 days, so a later identify call can still link them.
- Nothing new since connecting. Click Sync now on the provider card. If the card says Needs attention, the error message tells you what the provider returned (for example a revoked key).