Revenue attribution
Connect Stripe, Polar, Dodo or Creem per website, and link every sale to the visit that produced it.
How it works
The script gives each visitor a first-party id (cookies datacheap_visitor_id and datacheap_session_id on your domain). When that id reaches the payment, ownlytics knows which visit, source and campaign produced the sale. It gets there in one of three ways:
- Payment links are tagged by the script automatically. Nothing to do.
- Server-created checkouts: pass the two ids as metadata (examples below).
- Success page: when the buyer lands back on your site with the provider's checkout id in the URL, the script links it.
Each website connects its own payment account. A dedicated account can send every payment to one site (new products included), or a shared account can split by product.
Overviews for each provider: Stripe, Polar, Dodo Payments, Creem.
Stripe
- In the website's setup, choose Stripe and click the link to create a restricted key. The permissions are pre-filled: read access to Checkout Sessions, Charges, PaymentIntents, Invoices, Subscriptions, Products, Prices and Customers, plus write access to Webhook Endpoints.
- Paste the key (
rk_live_…). Leave "Instant updates" on to create the webhook. - Choose "Every payment in this account" or pick products.
Payment Links
Nothing to do: the script adds client_reference_id to every buy.stripe.com link on your site. Optional backup: set the link's after-payment redirect to https://yoursite.com/thanks?session_id={CHECKOUT_SESSION_ID}.
Checkout Sessions
const cookie = (name) => request.headers.get('cookie')?.match(new RegExp('(?:^|; )' + name + '=([^;]+)'))?.[1];
const metadata = {
ownlytics_visitor_id: cookie('datacheap_visitor_id'),
ownlytics_session_id: cookie('datacheap_session_id'),
};
const session = await stripe.checkout.sessions.create({
mode: 'payment', // or 'subscription'
line_items: [{ price: 'price_…', quantity: 1 }],
metadata,
subscription_data: { metadata }, // subscriptions: renewals keep the visitor
success_url: 'https://yoursite.com/thanks?session_id={CHECKOUT_SESSION_ID}',
});
Subscriptions: the first paid invoice is credited to the checkout's visitor (with a free trial, that's the first charge after it), and every renewal inherits it. Custom PaymentIntent flows work when the intent carries the same metadata; a subscription charge paid that way still counts once.
Polar
- In Polar: Settings → Developers → New token, no expiration, with the scopes
organizations:read products:read orders:read subscriptions:read customers:read refunds:read checkouts:read webhooks:read webhooks:write. - Paste the token (
polar_oat_…), choose Production or Sandbox, keep "Instant updates" on. - Choose every payment or specific products.
Checkout links
Nothing to do: the script adds reference_id to every buy.polar.sh link, and Polar copies it onto the order. Optional backup: success URL https://yoursite.com/thanks?checkout_id={CHECKOUT_ID}.
Checkout API
const checkout = await polar.checkouts.create({
products: ['<product id>'],
metadata, // same two ids as above
successUrl: 'https://yoursite.com/thanks?checkout_id={CHECKOUT_ID}',
});
Dodo Payments
- Dodo → Developer → API keys: create a key and paste it (Live or Test).
- Pick this website's products. One key covers the whole business; other sites can use the same connection with different products.
Payment links (/buy/pdt_…) are tagged automatically. For checkout sessions, pass the same metadata object, and set return_url to a page on your site.
Creem
- Creem → Developers → API keys: create a key with full access and paste it. A test-mode key (
creem_test_…) connects your test store, a live key (creem_…) your live one. - Keep "Instant updates" on: ownlytics creates the webhook in Creem for you. It's how checkout metadata reaches ownlytics, so leave it on.
- Choose every payment in the store, or specific products.
Payment links
Nothing to do: the script adds metadata[ownlytics_visitor_id] to every creem.io/payment/prod_… link on your site, including links on your own checkout domain. Optional backup: set the product's success URL to a page on your site; Creem appends ?checkout_id=…&order_id=… and the script links the order. Short links (l.creem.io) can't carry the visitor, so link to the payment link itself.
Checkout API
const checkout = await creem.checkouts.create({
productId: 'prod_…',
metadata, // same two ids as above
successUrl: 'https://yoursite.com/thanks', // Creem adds ?checkout_id=…&order_id=…
});
Subscriptions: Creem copies the checkout metadata onto the subscription, so every renewal is credited to the same visit. Past sales are imported when you connect; one-time sales from before you connected are matched by the buyer's email.
Switching from DataFast
Checkout metadata named datafast_visitor_id / datafast_session_id is read too, so existing checkout code keeps working.
Weighing the two up? See ownlytics vs DataFast.