Tracking & Attribution

How Do You Track Trial-to-Paid Conversions Weeks Later?

A trial converts to paid weeks after the ad click. Which event to count, when a cohort's numbers are final, and how to keep the first touch.

Quick answer

Treat a trial as two conversions, not one. The signup is an identified event you can send within minutes of the click; the payment is the money event that lands two weeks to a month later with no browser attached. Connect them by storing the first touch against the person at signup, then matching the payment back to that record when the card clears. Report them separately — a campaign's trial volume and its trial-to-paid rate are different numbers, and only the second one pays for the ads.

Tell us what's broken. We'll fix your tracking — free.

Describe the tracking/attribution problem you're stuck on and we'll map it to a fix: server-side conversions to Meta, Google, TikTok and Pinterest, plus first-party tracking that survives Safari. No code required.

A trial-to-paid conversion is two events, not one. The signup happens in a browser you can see. The payment happens weeks later inside your billing system, with no browser, no click ID and no session attached. You connect them by storing the first touch against the person at signup, then matching the payment back to that record when the card clears.

The plumbing is the easy half. The decisions — which event you optimise against, when a cohort’s numbers are final, and whether you rank campaigns on trials or on paid conversions — are where most subscription attribution quietly goes wrong.


Which event is the conversion: the trial start or the first payment?

Both, for different jobs. The trial start is your optimisation event: it fires minutes after the click, it carries a real email, and it gives the ad platform something to learn from while the click is still fresh. The first payment is your measurement event: it is the only one with money attached.

Send only trial starts and the algorithm optimises for people who are willing to type a card into a form. That is not the same population as people who keep paying, and on some channels it is nowhere near it. Send only payments and you starve the algorithm — a campaign gets its first feedback thirty days after it started spending, by which time you have either wasted the budget or turned it off.

The working setup is both, named differently, with only one of them carrying revenue. A lead or signup event at day zero with no value on it. A purchase or subscribe event at first payment with the actual amount and currency. Two events, two purposes, no double counting, because they describe different moments in the same journey rather than the same moment twice.

The trap is sending both with a value and reading the total — your dashboard then shows revenue for trials nobody has paid for. Put the money on the payment event, and give the algorithm the free one too, through the Conversions API, so it arrives whether or not the browser cooperated.


Why is your trial cohort’s ROAS wrong until the cohort matures?

Because part of the cohort has not decided yet. On the last day of the month, a campaign that started spending three weeks ago has trials still sitting inside their trial window. Their payments have not happened, so its revenue column is structurally incomplete — not wrong in a way you can fix with better tracking, just early.

This is the single most expensive reporting mistake in subscription marketing. Someone compares September spend against September revenue, sees a bad ratio, and pauses a campaign whose trials convert on day 30. Half of them convert a week after the decision is made, on a campaign that is no longer running.

The fix is discipline, not software. Report by cohort — the month the trial started, not the month the payment arrived — and mark cohorts as immature until every member has passed the trial length plus a few days of dunning. A 14-day trial means September’s cohort is readable around 25 September for its first week and honest only in early October. Say the maturity date out loud on the report.

Your own lag distribution sets that date. Trials convert in a cluster around the trial end with a tail behind it, so pull the distribution once, find the day by which most paid conversions have landed, and make that your maturity rule. The same structural gap shows up outside subscriptions whenever you are attributing a purchase weeks after the ad click — the difference with a trial is that the delay is a fixed, known, billable number, so you have no excuse for being surprised by it.


How do you carry the first touch from the signup to the invoice?

Write the attribution onto the person at signup, not onto the payment. The signup is the last moment the browser still holds the campaign data: UTM parameters, the referrer, the landing page, and click IDs like gclid, fbclid and msclkid. Store those against the account record the moment it is created, and the payment can join back to them through the account weeks later.

Doing it the other way around — looking for the campaign at payment time — cannot work. The charge is a server-side event created by a billing schedule; there is no browser in the room to ask, and identifiers you did not save at signup are not retrievable later.

Three things make the carry survive:

  • Persist server-side, not in the browser. A cookie or localStorage entry is not a thirty-day storage medium. Safari’s tracking prevention caps script-written cookie lifetimes, ad blockers remove tags, and people clear browsers and switch devices. Attribution that matters for a month belongs in your database, on the user row.
  • Key on something that survives the gap. A normalised email, a normalised phone, and your own first-party visitor ID all outlive a session. Match on canonical values — lowercased and trimmed email, E.164 phone — so the same person is one person.
  • Keep first touch and last touch separately. A trial user typically has several sessions before signing up. First touch tells you which campaign created the relationship; last touch tells you which one closed it. Storing only one is throwing away half the answer.

The dispatch side of this — capturing Meta’s identifiers at the first visit and firing the delayed event server-side with a shared event ID — is covered in tracking SaaS trial conversions to Meta Ads. The reporting-side join, from a payment object back to a browsing session, is the same machinery described in attributing Stripe payments to campaigns.


Can you backdate the paid conversion to the day of the ad click?

No. Meta’s Conversions API accepts an event_time only within a seven-day window, so a payment that happens thirty days after the click cannot be timestamped back to the click. It is sent with the time it actually happened, and the platform uses the identifiers in the payload — not the timestamp — to decide which click it belongs to.

That surprises people, so it is worth being blunt about the consequence. Attribution of a delayed conversion is an identity problem, not a timestamp problem. The click ID, the hashed email and the hashed phone in the payload are what tie the event back to an ad. A perfectly accurate event_time with no identifiers attributes nothing.

It also explains why the trial-start event earns its place. The signup happens while the click is fresh and well inside every reporting window, so it is the event that reliably lands in the platform’s own attribution. The payment event arrives late, carries the money, and is credited on the strength of its identifiers.

Timeline diagram showing a trial-to-paid journey: ad click and signup on day zero with a lead event sent immediately, a thirty-day trial gap, and the payment on day thirty sent with today's timestamp because the seven-day event window will not accept a backdated one

One more consequence: backfilling historical conversions after installing tracking gets the timestamps clamped, not accepted. Backfill is useful for your own reporting and for matching customers, not for retroactively crediting campaigns that ran months ago.


How do you compare campaigns on trial-to-paid rate instead of trial volume?

Divide paid conversions by trials started, per campaign, per cohort. Two campaigns with the same cost per trial can differ by a factor of three on the share that ever pays, and the cheaper one is often the worse one. Cost per trial is a measure of your landing page. Trial-to-paid rate is a measure of the traffic.

Worked with round illustrative numbers: campaign A produces 100 trials at $20 each, campaign B produces 50 trials at $40 each. On cost per trial, A wins by double. Then the cohort matures — 12% of A’s trials pay, 34% of B’s do. A produced 12 customers for $2,000, or $167 each. B produced 17 for $2,000, or $118 each. The campaign that looked twice as expensive acquires customers a third cheaper, and you would only ever see it by waiting for the cohort.

Three rules keep that comparison honest:

  1. Group by cohort start, always. Paid conversions belong to the month the trial started, not the month the money moved.
  2. Compare mature cohorts only. Put the immature ones on the same report greyed out, with the maturity date beside them, so nobody reads a half-finished number as a verdict.
  3. Keep the denominator stable. Count trials the same way every month — deduplicated by person, excluding your own team and obvious junk — or the rate moves for reasons that have nothing to do with the campaign.

Once you have that rate by campaign, the budget question answers itself, in the same way as any other attribution channel you are deciding whether to scale: the channel with the best mature cost per paying customer gets the money.


How does PartialLeads track a trial-to-paid conversion weeks after signup?

By treating the payment as a purchase that arrived late, and having kept the identity that connects it to the click. Stripe connects as a purchase source over OAuth, alongside Shopify, WooCommerce, GoHighLevel and a universal webhook. Every payment then runs through one pipeline: normalise identity, deduplicate, match to a session in tiers, attach revenue to the lead, and write both a first-touch and a last-touch attribution row.

The pieces that matter for a delayed conversion specifically:

Identity that outlives the trial. The visitor ID is a first-party cookie set by the server rather than by script, so it is not subject to the seven-day cap Safari applies to script-written cookies. Behind it, a cluster resolver unions a person’s sessions across visitor ID, email, phone, IP plus user agent, a device fingerprint and shared click IDs. A person who clicked on a phone in August and paid on a laptop in September is one person, not two rows.

First touch and last touch, both written. Every matched payment writes both rows, each snapshotting UTMs, click IDs, referrer, landing page and time to purchase. That is what makes cohort reporting possible after the fact — the signup’s campaign is still attached to the payment a month later.

Deduplication that survives retries. Payments are idempotent on client, source, order ID and status phase, and dispatched events carry a deterministic event ID, so a redelivered webhook cannot double-count a conversion. Refunds get their own row that nets against the paid one, which matters when a converted trial refunds in its first week.

Dispatch back to the platforms. Matched payments fan out server-side to Meta, Pinterest, TikTok and Google Ads with hashed contact details attached — inside the platform’s event-time window, at the time the payment actually happened.

Where you see it working: the Attribution report’s Time to Purchase panel, which plots first-touch and last-touch lag side by side in buckets from under an hour to over 28 days, so a trial cohort’s shape is visible rather than assumed; the Avg Lag column on the channels table, where a channel whose buyers take 30 days is immediately distinguishable from one whose buyers take a day; and the first-touch model beside last-touch and resolved, which how to read an attribution report walks through in detail.

The honest constraints. There is no trial-state model in the product — no in-trial, converted or churned status, and no subscription cohort report. What exists is the payment, the lag between first touch and that payment, and the attribution rows on both ends; the cohort view is a computation you run on top of that, or in your billing system. And matching has a ceiling nobody controls: a person who signed up through a channel where the tag never ran has no session to match to, so their payment lands as unmatched revenue rather than a campaign row. Capture more of the person earlier and more of the revenue resolves.

Attribution report mockup showing the Time to Purchase panel — first-touch and last-touch lag plotted together across buckets from under an hour to over 28 days, with attributed revenue, median time to purchase and match rate tiles above, and a channels table carrying an average lag column

What breaks The mechanism Where you see it in the dashboard
The payment arrives weeks later with no campaign data Stripe and other purchase sources matched to a session in tiers, with first-touch and last-touch rows written per payment Purchases ledger, Attribution report
The browser that held the click ID is long gone Server-set first-party visitor ID plus an identity cluster across email, phone, IP and user agent, device hash and click IDs Journey timeline on the lead
Clicked on a phone in August, paid on a laptop in September Cluster resolution unions both sessions into one person before the payment is matched Journey ribbon on the Leads list
Nobody knows when a cohort is finished Time to Purchase distribution, first touch versus last touch, from under an hour to over 28 days Attribution report, Time to Purchase
Fast channels and slow channels look alike Average lag per channel beside revenue and ROAS Attribution report, channels table
A redelivered webhook double-counts a conversion Idempotent purchase dedup plus a deterministic event ID on every dispatched event CAPI activity log
A converted trial refunds in week one Refund rows carry their own status phase and net against the paid row Purchases ledger

Tell us what's broken. We'll fix your tracking — free.

Describe the tracking/attribution problem you're stuck on and we'll map it to a fix: server-side conversions to Meta, Google, TikTok and Pinterest, plus first-party tracking that survives Safari. No code required.

Sources

  1. Meta for Developers — Conversions API overview: https://developers.facebook.com/docs/marketing-api/conversions-api
  2. Meta for Developers — Server event parameters (including the event_time window): https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/server-event
  3. Meta for Developers — Customer information parameters: https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/customer-information-parameters
  4. Meta for Developers — Deduplicate Pixel and Conversions API events: https://developers.facebook.com/docs/marketing-api/conversions-api/deduplicate-pixel-and-server-events

Frequently asked questions

QShould I send the trial start or the paid conversion to Meta?
Both, as different events, with value only on the payment. The trial start fires while the click is fresh and gives the algorithm fast feedback. The paid conversion carries the money and is what you measure against spend. Sending both with a value attached is the mistake — your reported revenue then includes trials that nobody has paid for.
QCan I backdate a payment event to the day of the ad click?
No. Meta's Conversions API only accepts an event_time inside a seven-day window, so a payment thirty days after the click is sent with the time it actually happened. Attribution of a delayed conversion rests on the identifiers in the payload — click ID, hashed email, hashed phone — not on the timestamp. A backdated timestamp would not help even if it were accepted.
QWhen is a trial cohort's ROAS final?
After every member has passed the trial length plus a few days of failed-payment retries. For a 14-day trial, a cohort that started on the first of the month is roughly readable three weeks later and honest in the first days of the next month. Publish the maturity date beside the number so nobody makes a budget decision on a half-finished cohort.
QWhy do my cheapest trials produce the most expensive customers?
Because cost per trial measures your landing page and trial-to-paid rate measures your traffic. Broad, cheap audiences produce people who sign up easily and churn before billing. Divide paid conversions by trials started per campaign, on matured cohorts only, and rank on cost per paying customer instead. The ordering frequently reverses.
QWhere should I store the attribution — in the browser or the database?
The database, on the user record, written at signup. Browser storage does not reliably survive a month: tracking prevention caps script-written cookie lifetimes, blockers remove tags, and people switch devices. Capture UTMs, referrer, landing page and click IDs at the first pageview, persist them server-side, and the join still works when the invoice clears.
QWhat happens to conversions from people who never visited my site?
They stay unmatched, and that is the honest outcome. A payment from someone who arrived through a channel your tag never ran on has no session to join to, so no identifier ties it to a campaign. Record it as unmatched revenue rather than assigning it to a channel by guesswork, and track the unmatched share as its own number.
QDo trial-to-paid conversions count as first touch or last touch?
Both get written, and they answer different questions. First touch credits the campaign that created the relationship — usually the one that produced the trial signup. Last touch credits whatever session came before the payment, which for a trial converting automatically is often nothing at all. For acquisition decisions on subscriptions, first touch is normally the more useful of the two.
QHow do I handle a trial that converts, refunds, then resubscribes?
Keep every state as its own row rather than editing one. A refund nets against the paid amount instead of deleting it, and a later resubscription is a new payment on the same person. If you overwrite, your cohort totals change retroactively and last month's report stops reproducing — which is how attribution arguments start.

Find the qualified leads your forms are currently throwing away.

Install PartialLeads on one landing page, send traffic, and compare what your CRM captured against what PartialLeads recovered and qualified.