Install on Shopify
Sign up for a 30-day Free Trial.
index_mail_icon
Aimerce Blogs
Why TikTok Is Not Tracking Shopify Purchases (ttclid)
23 July 2026
Why TikTok Is Not Tracking Shopify Purchases (ttclid)
First-Party Data 101
Illustration for article about fixing missing TikTok ttclid tracking on Shopify.

Quick Answer: TikTok purchases usually go untracked because ttclid, TikTok's click identifier, gets captured on the landing page but never survives the trip to the Shopify checkout domain or into the order record. Without it attached to your server-side purchase event, TikTok falls back to weaker probabilistic matching, and reported ROAS looks lower than actual sales.

Key Takeaways

  • ttclid only exists briefly in the landing page URL. If nothing captures it immediately, it's gone the moment the shopper navigates away, there's no way to recover it afterward.
  • The most common failure point isn't capture, it's the checkout domain transition. A ttclid saved in storefront storage often never reaches Shopify's separate checkout domain, which is why it's missing from the order even when it was captured correctly on landing.
  • A Shopify order webhook gives reliable, backend-confirmed purchase delivery, but the payload only contains order data. It has no idea what the browser stored earlier, so ttclid has to be written into the order record itself, as a cart attribute, order note, or metafield, before the webhook fires.
  • Running both the TikTok Pixel and TikTok CAPI is the right architecture, but only if both send the same event_id for the same purchase. Mismatched or randomly generated IDs cause TikTok to count one sale as two conversions.
  • As of April 2024, TikTok auto-appends ttclid to landing URLs, so for most merchants the real failure point isn't the URL parameter itself, it's what happens to that value after the click.

What is ttclid, and why does it matter for TikTok attribution?

ttclid is TikTok's click identifier, appended automatically to your ad's destination URL whenever a shopper taps a TikTok ad. It's the direct link between the ad click, the landing session, and the eventual conversion.

When ttclid is present and intact in the purchase event sent through TikTok CAPI, TikTok can match the conversion to the specific ad interaction with high confidence. When it's missing, TikTok falls back to probabilistic matching using hashed signals like email and phone, which works, but less reliably, particularly as browser privacy restrictions degrade the quality of those signals. Campaigns starved of ttclid-matched conversions take longer to exit the learning phase, spend less confidently, and are harder to scale. Ad spend keeps going out, TikTok just can't fully credit what it's driving.

Why does ttclid disappear before it reaches TikTok CAPI?

Usually one of four points in the journey, and any single failure anywhere in the chain means the purchase event goes out without it.

It's never stored in the first place. ttclid arrives as a URL parameter. If nothing on the store captures and stores it when the page loads, it's gone the moment the shopper navigates to a new page, with no second chance to retrieve it later.

Checkout crosses a domain boundary. Even when ttclid is captured correctly on the storefront, Shopify's checkout runs on a separate domain, and the journey from product page to cart to checkout to confirmation crosses at least one boundary, often more with express checkout. Browser storage doesn't automatically survive that transition. A value saved in a storefront cookie may simply not be readable once the shopper reaches Shopify's checkout domain.

Browser restrictions and ad blockers interfere with capture. The same class of problem that affects Meta Pixel tracking applies here: ad blockers, privacy extensions, and Safari's ITP can all prevent or shorten how long a client-side capture script has to do its job.

The server-side purchase event can't see what the browser stored. Shopify webhooks are reliable for order data, customer details, line items, payment status, but a webhook payload doesn't contain anything the browser stored during the session. If ttclid was captured but never written into the order record itself, the server-side event goes out clean and reliable, just without the one field that makes attribution work.

How should ttclid actually flow from click to purchase event?

Through four deliberate stages, treating the click ID as something explicitly carried forward rather than something that's simply present when needed.

Capture on landing. Read ttclid from the URL immediately on page load, before any navigation occurs.

Persist through browsing. Store the captured value somewhere durable enough to survive a multi-page session. A first-party cookie with a reasonable expiration holds up better than sessionStorage alone, which clears the moment the tab closes.

Attach to the Shopify order. This is the step most implementations skip. For ttclid to be available when the server-side purchase event fires, it needs to be written into the order record itself, as a cart attribute, order note, or order metafield, since that's the only version of the data the webhook can actually see.

Send with the server-side event. When the purchase event reaches TikTok's Events API after order confirmation, the ttclid attached to the order record goes with it, and TikTok receives a conversion it can confidently attribute.

Skip the third stage and every purchase event sent through TikTok CAPI is missing the click ID, no matter how well-built the rest of the pipeline is.

Which implementation approach is actually reliable?

It depends on how much TikTok spend is riding on getting this right, since the three common approaches trade off setup effort against durability in a fairly predictable way.

ttclid Capture Methods Compared

ApproachSurvives checkout domain transitionSurvives express checkout (Shop Pay, Apple Pay, PayPal)Setup effortBest for
Theme-level capture + session storageNoNoLow, a single theme scriptA quick test, not production-reliable spend
Order-level persistence (cart attribute or metafield)YesDepends on implementation, needs testing per checkout pathMedium to high, and must be tested across every payment pathTeams with development resources willing to test thoroughly
Dedicated server-side tracking layerYesYesLow, no development requiredMerchants running meaningful TikTok spend

Theme-level capture is the fastest to set up and the most fragile, useful as a starting fallback layer but not as the only mechanism if TikTok is a real spend channel. Order-level persistence solves the domain problem properly, since the data lives in Shopify's order record rather than browser storage, but cart attribute behavior differs across standard checkout, checkout extensions, and express flows, so it needs real testing across all of them before you trust it. A dedicated server-side tracking layer handles capture, persistence, and order attachment as one pipeline, including the express checkout paths that break the other two approaches, which is why it's the more reliable option once TikTok spend is meaningful enough that gaps actually cost money.

Aimerce takes this third approach for Shopify: capturing ttclid on landing, persisting it through the full journey including express checkout, and writing it into the order record so the server-side purchase event always has it available. Because the pipeline is built around Shopify's order creation signal rather than browser scripts, it doesn't break when checkout transitions or browser restrictions intervene, and the same infrastructure handles Meta alongside TikTok with consistent deduplication across both.

What should a clean TikTok CAPI payload actually include?

A smaller set of correct, consistent fields, rather than a larger set with formatting errors or gaps, the same principle that applies to Meta's Conversions API.

The fields that matter most: event_name using TikTok's canonical purchase event, CompletePayment. event_time as the timestamp of when the order was actually created, not when your server got around to processing it. event_id, a deterministic identifier derived from the order ID, used for deduplication. ttclid, included only if it was actually captured, never fabricated or guessed if it wasn't. page_url, typically the order confirmation page. value and currency, formatted accurately and consistently. And hashed email and phone when available, which TikTok uses for probabilistic matching when ttclid is absent or as additional confirmation. Get these core fields right before adding anything else.

How do you stop TikTok Pixel and CAPI from double-counting the same purchase?

By sending the same event_id from both the pixel and the server event, so TikTok recognizes them as one conversion instead of two.

Most Shopify stores running TikTok ads use both: the Pixel for on-site engagement, CAPI for reliable purchase delivery, the same architecture that makes Meta Pixel plus Conversions API work well together. The risk is double-counting: if TikTok receives a Purchase event from the pixel and a CompletePayment event from CAPI for the same order with no way to recognize them as the same conversion, reported conversions inflate and optimization signals get noisy. The fix is a shared, deterministic event_id, generated from the order ID (event_id = "purchase:" + order_id) and sent identically from both the pixel and the server event. A randomly generated ID in the browser and a different randomly generated ID on the server look like two distinct conversions to TikTok, which inflates the purchase count and makes CAPI appear to be adding conversions rather than completing the picture. Aimerce handles this automatically: the same event_id is sent from both the client-side pixel and the server-side API for a given action, with no manual GTM mapping required, so TikTok's system merges the overlapping signal into a single recorded conversion.

How do you test and debug a ttclid gap on Shopify?

Work through the chain in order, since a failure anywhere upstream makes everything downstream untestable.

Capture verification. Click a live TikTok ad, or build a test URL with a ttclid parameter appended. Confirm it's present in the landing URL, and confirm your capture script reads and stores it before any navigation happens.

Persistence verification. Browse a few pages after landing, then confirm the stored value is still accessible. Add to cart and confirm it hasn't been cleared.

Order attachment verification. Complete a test purchase, then check the resulting Shopify order record for ttclid in whichever field it should be written to. If it's not there, the server-side event won't have it either.

Server-side event verification. Confirm a purchase event fires after payment confirmation, not just at checkout initiation, that the payload includes ttclid from the order record, and that event_time is accurate and in Unix timestamp format.

Deduplication verification. Confirm the pixel and CAPI events for the same order share the same event_id, and check TikTok Events Manager to see the order appear as a single conversion, not two.

Attribution verification. Run a real test purchase through an actual TikTok ad click, then confirm in Events Manager that it shows a matched click ID. A conversion matched via click ID is confirmation the full chain is working end to end.

Common mistakes to avoid

  • Assuming capture equals delivery. Capturing ttclid on the landing page doesn't mean it survives to the order record, the checkout domain transition is where most implementations actually fail.
  • Fabricating a ttclid value when it wasn't captured. Omit the field entirely instead. A guessed value is worse than an honest gap, since it can corrupt matching rather than simply missing it.
  • Generating a new random event_id for the server event instead of reusing the one derived from the order ID. This breaks deduplication and inflates reported conversions.
  • Testing only the standard checkout path. Express checkout flows often skip steps a theme-level script depends on, and an approach that works on standard checkout can still fail silently on Shop Pay, Apple Pay, or PayPal.
  • Treating a lower TikTok-reported conversion count as a campaign performance problem before checking whether it's actually a tracking gap. Compare TikTok's numbers against actual Shopify orders first.

FAQ

What is ttclid and why does it matter for TikTok ads? ttclid is TikTok's click identifier, appended to your ad's destination URL when a shopper taps a TikTok ad. It's the direct link between an ad click and a conversion event. When it's present in your TikTok CAPI purchase event, TikTok can attribute the conversion with high confidence. When it's missing, TikTok falls back on probabilistic matching, which is less reliable and can understate your actual TikTok ROAS.

Do I still need the TikTok Pixel if I'm using TikTok CAPI? Most stores benefit from running both. The Pixel handles on-site engagement events like page views and add to cart, while CAPI provides more reliable purchase delivery, particularly for shoppers on iOS or using ad blockers. The two work together correctly when deduplication is implemented using a shared event_id.

Why does TikTok show fewer purchases than Shopify? Shopify records every completed order. TikTok only reports conversions it can attribute within its attribution windows and with sufficient match signals. Missing ttclid, weak match quality from incomplete user signals, or events arriving outside TikTok's attribution window all contribute to the gap. Server-side tracking improves delivery reliability but doesn't change TikTok's underlying attribution rules.

Can I recover ttclid after the purchase if I didn't capture it during the session? No. If it wasn't captured and persisted during the session, there's nothing reliable to attach to the order afterward. The click ID exists only in the original landing URL, which is why capture and persistence are the most critical steps in the whole chain.

What's the difference between TikTok CAPI and the TikTok Events API? They're the same thing. TikTok's server-to-server conversion mechanism is called both the Conversions API and the Events API depending on the source, with identical implementation and payload requirements either way.

How does TikTok server-side tracking compare to Meta's Conversions API for Shopify? The underlying principle is identical: move conversion delivery from the browser to the server for reliability and match quality. The specific parameters differ, Meta uses fbp, fbc, and event_id, TikTok uses ttclid, event_id, and hashed user signals. For merchants running both, a unified server-side pipeline is more efficient than maintaining two separate implementations.

Does server-side tracking for TikTok help with iOS attribution on Shopify? Yes. iOS privacy restrictions reduce the reliability of browser-based pixel tracking for both Meta and TikTok. Sending purchase events from the server after order confirmation means those restrictions don't prevent the conversion from reaching TikTok, since the ttclid was already captured and stored before any browser restriction could interfere.

Sources

[1] TikTok Ads Manager Help Center, "About TikTok Click ID"

Try Aimerce Pixel Risk-Free
for 30 Days

Most teams see results within 2 weeks.

Money-back guarantee.
It pays for itself, or you don't pay anything.

Install On
Sign Up for a
30-Day Aimerce Pixel Free Trial
Sign Up Using Your Shopify Account Email
*Money back guaranteed.
Aimerce pays for itself or you don’t pay anything.