Install tracking

Three pieces, then a verification test. Pick the recipe that matches your checkout.

Tracking has three parts: (1) the apply link you share with potential partners, (2) partli.js on your site so each visit can carry attribution into checkout, and (3) wiring the click ID into your Stripe Checkout call. The wiring step is what trips merchants up — it depends on how your checkout is built.

Verify before you go live

Every program is locked in draft until you pass an end-to-end verification test on its detail page. The verification panel exercises the full chain (real test transaction → Stripe → our webhook) so misconfigurations surface before you share the apply link with real partners.

Pick your checkout pattern

partli.js does as much as it can client-side. Some checkout flows give it a clear hook to inject the click ID; others require one or two lines of your own code because the Checkout Session is created on your server.

1. Stripe Buy Button or Payment Link

Pattern: <a href="https://buy.stripe.com/..."> or the embedded Stripe Buy Button web component.

Code needed: none beyond the script tag. partli.js intercepts the click and appends ?client_reference_id=<id> to the Stripe URL.

2. Stripe.js library

Pattern: Stripe.redirectToCheckout({...}) from the official Stripe.js library.

Code needed: none beyond the script tag. partli.js patches Stripe.redirectToCheckout to inject clientReferenceId into the options object.

3. Stripe Pricing Table (embedded element)

Pattern: <stripe-pricing-table> embedded in your page.

Code needed: set the client-reference-id attribute when you render the element. partli.js can't reach inside Shadow DOM.

<stripe-pricing-table
  pricing-table-id="prctbl_..."
  publishable-key="pk_live_..."
  client-reference-id={window.Partli?.getClickId?.()}
></stripe-pricing-table>

4. Backend creates the Checkout Session (most common production setup)

Pattern: your frontend calls your backend (POST /api/create-checkout-session), your backend creates the Stripe session via the SDK, returns the URL, and the frontend redirects via window.location.href.

Code needed: two snippets — frontend reads the cookie + sends to your backend; backend stamps the session.

// Frontend
const clickId = window.Partli?.getClickId?.();
const promo = window.Partli?.getPromotionCode?.();
const res = await fetch("/api/create-checkout-session", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ plan, clientReferenceId: clickId, promotionCode: promo }),
});
const { url } = await res.json();
window.location.href = url;
// Backend
const session = await stripe.checkout.sessions.create({
  mode: "payment",  // or "subscription"
  line_items: [{ price: priceId, quantity: 1 }],
  success_url: "...",
  cancel_url: "...",
  customer_creation: "always",  // recommended for cleaner Customer rows
  client_reference_id: req.body.clientReferenceId || undefined,
  ...(req.body.promotionCode && {
    discounts: [{ promotion_code: req.body.promotionCode }],
  }),
});

Why partli.js can't do this for you: the actual stripe.checkout.sessions.create call runs on your server, where browser-side JavaScript can't reach. Whoever creates the session has to set client_reference_id.

5. Custom (non-Stripe) billing

Pattern: any other billing system — LemonSqueezy, Paddle, Chargebee, custom in-house.

Code needed: read the pref_cid cookie at conversion time and POST it to our REST API from your billing webhook.

Then verify

After you wire your pattern, open the program edit page and run the verification test. The panel opens your destination URL with a sentinel click ID, watches our webhook for the resulting Stripe event, and tells you specifically what's broken if anything is — or marks the program as ready to go live if everything connected.

One more thing — what about your partners?

Partners (the people earning commissions) onboard into Stripe Connect Expressthe first time they receive a payout — KYC + bank details, ~3 minutes per partner. That's separate from connecting your own Stripe for attribution and unavoidable for any payout system.