Documentation

LTV Tracker Docs

Everything you need to connect your marketing channels to your Stripe revenue. Setup takes about 10 minutes.

Quick start

LTV Tracker works by installing a small JavaScript snippet on your site and registering a webhook in your Stripe dashboard. That's all — no backend changes required if you use Stripe Payment Links.

1
Add the snippet to every page that has a buy button — paste it before the closing </head> tag. Your unique snippet is in Settings → Tracking.
2
Register the webhook in your Stripe dashboard (see Webhook setup).
3
Paste the signing secret in LTV Tracker → Settings → Stripe Webhook Secret.
That's it for Payment Links. If you use custom Stripe Checkout sessions, see theStripe Checkout section for one extra backend step.

This is the easiest integration. If your buy buttons point to a buy.stripe.com URL, the snippet handles everything automatically.

How it works

When a visitor lands on your site from an ad, the snippet reads the UTM parameters from the URL and stores them. When they click any buy.stripe.com link, the snippet automatically injects a client_reference_id containing the attribution data. Stripe passes this to your webhook when the payment completes.

html
<!-- Your buy button — no changes needed -->
<a href="https://buy.stripe.com/your_link">Buy now</a>

<!-- After snippet runs, it becomes: -->
<a href="https://buy.stripe.com/your_link?client_reference_id=YOURKEY__google__brand__keyword">Buy now</a>
ℹ️
The snippet patches all buy.stripe.comlinks on the page automatically. You don't need to modify your links manually.

Stripe Checkout

If you create Stripe Checkout sessions from your own backend, add one extra step to pass the attribution data as metadata.

Step 1 — Read UTMs on your frontend

javascript
// On your checkout page, read the attribution the snippet captured
const attr = window.ltvTracker?.getAttribution() ?? {};

// Send it to your backend when the user clicks buy
const res = await fetch('/create-checkout-session', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    utm_source:   attr.utm_source   ?? '',
    utm_medium:   attr.utm_medium   ?? '',
    utm_campaign: attr.utm_campaign ?? '',
    keyword:      attr.keyword      ?? '',
  }),
});

Step 2 — Pass it to Stripe on your backend

javascript
const session = await stripe.checkout.sessions.create({
  // ... your existing params (line_items, mode, etc.)
  metadata: {
    ih_project_id:  'YOUR_TRACKING_KEY',   // from LTV Tracker Settings
    utm_source:     body.utm_source,
    utm_medium:     body.utm_medium,
    utm_campaign:   body.utm_campaign,
    google_keyword: body.keyword,
  },
});
ℹ️
Replace YOUR_TRACKING_KEY with the key from LTV Tracker → Settings → Tracking API Key.

Webhook setup

The webhook lets Stripe notify LTV Tracker the moment a customer converts. Without it, attribution events won't be recorded.

1. Add the endpoint in Stripe

Go to Stripe Dashboard → Developers → Webhooks → Add endpoint and enter your unique URL:

https://ltv-tracker.com/api/webhooks/stripe-client/YOUR_TRACKING_KEY

2. Select these events

checkout.session.completed
invoice.paid

3. Save the signing secret

After creating the webhook, Stripe shows a signing secret starting with whsec_. Copy it and paste it in LTV Tracker → Settings → Stripe Webhook Secret.

⚠️
Make sure you're in the correct Stripe mode — use test mode keys and webhooks while testing, and live mode in production. They use different signing secrets.

GDPR & consent

By default, the snippet stores attribution data as soon as a visitor arrives with UTM parameters. If you don't have a cookie consent banner, no action is needed.

If you do have a consent banner, you can put the snippet in manual consent mode so it only stores data after the visitor accepts.

Enable manual consent mode

Add window.ltvTrackerManualConsent = true before the snippet loads, then call window.ltvTracker.enable() when the visitor accepts.

html
<!-- 1. Set the flag BEFORE the snippet -->
<script>window.ltvTrackerManualConsent = true;</script>

<!-- 2. Load the snippet as normal -->
<script>
  (function(w,d,s,k){
    w._ltv=w._ltv||{q:[]};
    w._ltv.k=k;
    var el=d.createElement(s);
    el.src="https://ltv-tracker.com/api/tracker/YOUR_KEY";
    el.async=true;
    d.head.appendChild(el);
  })(window,document,'script','YOUR_KEY');
</script>

<!-- 3. Wire your consent banner -->
<script>
  // Cookiebot
  window.addEventListener("CookiebotOnAccept", function() {
    if (Cookiebot.consent.marketing) window.ltvTracker.enable();
  });

  // OneTrust
  window.addEventListener("OneTrustGroupsUpdated", function(event) {
    event.detail.includes("C0004")
      ? window.ltvTracker.enable()
      : window.ltvTracker.disable();
  });

  // Simple custom banner
  document.getElementById("accept-btn").onclick = () => window.ltvTracker.enable();
  document.getElementById("reject-btn").onclick = () => window.ltvTracker.disable();
</script>
Even without consent, UTMs are captured in memory for the current page load. If the visitor converts in the same session, attribution is still recorded — no storage needed.

JS API reference

The snippet exposes a global window.ltvTracker object with the following API:

window.ltvTracker.enable()

Flush any pending UTM data to cookie + localStorage and activate tracking. Call this when the visitor accepts marketing cookies.

window.ltvTracker.disable()

Clear all stored attribution data and disable tracking. Call this when the visitor rejects or revokes consent.

window.ltvTracker.getAttribution()

Returns the current attribution object { utm_source, utm_medium, utm_campaign, keyword } or null. Works even before enable() — returns in-memory UTMs from the current URL.

window.ltvTracker.projectId

Read-only. The tracking API key this snippet is configured with.

window.ltvTrackerManualConsent

Set to true before the snippet loads to disable auto-enable. The snippet will wait for you to call enable() manually.

FAQ

Do I need to modify my Stripe Payment Links?

No. The snippet automatically patches all buy.stripe.com links on your page. Just add the snippet and the webhook.

What attribution rate can I realistically expect?

70–85% is typical, which matches industry tools like Google Analytics. Same-session conversions are always captured (even without cookies). Cross-session conversions require the cookie to survive, so you lose a small percentage from cookie rejection and ad blockers.

What data does the snippet store?

Only UTM parameters (utm_source, utm_medium, utm_campaign, keyword). No personal data, no fingerprinting, no third-party requests. The Stripe customer ID is only associated after a successful payment.

Does it work with Stripe test mode?

Yes. Use your test Stripe secret key in Settings and register the webhook in your Stripe test dashboard. Make sure the signing secret matches the mode (test vs live).

What if a customer rejects cookies and converts a week later?

Attribution will be lost for that conversion. This is the correct behaviour under GDPR — the visitor said no to tracking. Same-session conversions still work because UTMs are held in memory.

Can I use this with Paddle or LemonSqueezy?

Not yet — LTV Tracker currently supports Stripe only. Paddle and LemonSqueezy support is on the roadmap.

Something missing? hello@ltv-tracker.com