Tracking & Attribution

Where Do You Find the gclid for a Shopify Order?

Shopify orders have no gclid field. See where the click id sometimes hides, how to capture it at landing and export paid orders for Google Ads import.

Quick answer

Usually you don't, because Shopify doesn't store Google's click id as its own field on an order. Sometimes it survives inside the order's landing page URL, but only when the buyer landed from the ad and checked out on that same visit. To have a gclid for every paid order, capture gclid, gbraid and wbraid when the visitor lands, keep them, and join them to the order when it's paid.

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.

On most Shopify orders, the gclid isn’t there to find. Shopify has no dedicated click-id field on an order, so Google’s gclid, gbraid and wbraid only show up by accident, inside the landing page URL Shopify records for the visit. To get one on every paid order, capture it when the visitor lands and join it to the order later.

That’s the wall people hit when they set up offline conversion import. Google Ads wants one row per sale with the click id it issued. Shopify has the sale, the value and the time. The one column that ties the sale to an ad click is the one it doesn’t keep.

Does Shopify store the gclid on an order?

Not as a field of its own. An order in Shopify’s Admin API carries landing_site (the URL the buyer landed on), referring_site, source_name and note_attributes, but nothing named gclid, gbraid or wbraid. If a click id is on the order at all, it’s inside one of those general fields.

Two places are worth checking before you build anything:

  • The landing page URL. Google’s auto-tagging adds the click id to the ad’s landing URL. When the buyer lands from the ad and checks out on that same visit, the query string can survive in landing_site. Parse it and you have your gclid for that order.
  • Note attributes. If a theme script or app wrote the click id into the cart, it arrives on the order in note_attributes. Many stores find one here they didn’t know an app was saving.

Neither is reliable on its own. The landing URL describes one visit, and cart data only exists if something put it there. If your Google orders only show “google / cpc” as a source, the guide to attributing ecommerce revenue to the ad click explains why a source label isn’t something Google can match.

What does a Google Ads offline import need from each Shopify order?

A click id Google issued, the conversion action the sale counts toward, the conversion time with a timezone offset, and ideally the value and currency. Shopify already has the time, value and currency on every order. The click id is the one field it can’t produce after the fact.

Google’s own API definition of a click conversion lists all three click-id types, and each row carries one:

  • gclid — the standard Google click id from auto-tagging.
  • gbraid — described by Google as “the URL parameter for clicks associated with app conversions”.
  • wbraid — “the URL parameter for clicks associated with web conversions”. Some iPhone traffic arrives with a wbraid and no gclid, so a setup that only saves gclid loses those buyers. Capturing gbraid and wbraid for offline conversions covers why.

The same definition gives the time format as yyyy-mm-dd hh:mm:ss+|-hh:mm, for example 2019-01-01 12:32:45-08:00. Always include the offset.

Status matters too. A Shopify order that’s pending, voided or later cancelled shouldn’t become a conversion. Upload orders once financial_status is paid, or Google’s bidding learns from sales that never happened.

Why is the gclid usually gone by the time the order is placed?

Because the click id lives in exactly one URL. Google adds it to the landing page, and the next page view doesn’t carry it. Unless something reads it on that first request and saves it, the product page, the cart and the order placed three days later have no way to get it back.

Journey from a Google Ads click to a paid Shopify order across three visits: the landing URL carries a gclid, the collection page and a return visit two days later show the click id greyed out as lost, and a second lane shows the same click id stored at landing and carried onto the paid order row

Where it disappears, in the order it usually bites:

  • It never reaches the page. Redirects, link shorteners and some consent or cache setups strip the query string first. Why the gclid goes missing on landing pages walks through each.
  • The buyer comes back later. They click an ad on Monday and return by typing your URL on Thursday. Thursday’s visit has no click id, and that’s the visit that checks out.
  • They switch devices. Phone for the ad, laptop for the order. Nothing in one browser travels to the other.
  • The path skips your theme. Checkout on a different domain, a link straight to checkout, or a draft order invoice never passes through the cart your script wrote to. Why attribution breaks between your landing page and Shopify checkout covers that handoff.

How do you get the gclid onto Shopify orders yourself?

Save the click id in a first-party cookie when the visitor lands, copy it into the cart as a cart attribute before checkout, and read it back from the order’s note_attributes when you export paid orders. It’s a theme-level fix: a short script in theme.liquid and an export job.

Step 1: save the click id at landing, then write it to the cart. Put this in your theme so it runs on every page, because ads land on product and collection pages too:

// Save Google click ids from the landing URL, then copy them into the cart.
(function () {
  var p = new URLSearchParams(window.location.search);
  var keys = ['gclid', 'gbraid', 'wbraid'];
  keys.forEach(function (key) {
    var v = p.get(key);
    if (!v) return; // never overwrite a stored id with nothing
    document.cookie = 'pl_' + key + '=' + encodeURIComponent(v) +
      '; path=/; max-age=' + 90 * 86400 + '; SameSite=Lax';
  });

  var attrs = {};
  keys.forEach(function (key) {
    var m = document.cookie.match('(?:^|; )pl_' + key + '=([^;]*)');
    if (m) attrs[key] = decodeURIComponent(m[1]);
  });
  if (Object.keys(attrs).length) {
    fetch('/cart/update.js', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ attributes: attrs })
    });
  }
})();

The 90 days is a storage choice, not a Google rule. Match it to your conversion action’s click window.

Step 2: export paid orders. Pull orders where financial_status is paid, read gclid, gbraid or wbraid from note_attributes, and fall back to parsing landing_site. Write one row per order: click id, conversion action name, the paid time with its offset, the order total and the currency. A Google Sheet works as the import source.

Which value should each row send?

Send the same number every time. Most stores use the order total. If you’d rather send margin or a net figure, sending dynamic conversion values to Google Ads offline imports covers the trade-offs.

What does the do-it-yourself version still miss?

Every buyer whose click id isn’t in that browser’s cart when they check out. The returning shopper with cleared storage, the phone-to-laptop buyer, the direct checkout link and the draft order invoice all arrive with an empty column. Test your “Buy it now” and express checkout buttons too, since some skip the cart page your script relies on.

It also leaves two jobs nobody owns:

  • Rows that go out but don’t match. A misspelled conversion action or a click outside the window fails quietly. Why offline conversions don’t match the gclid lists the usual causes.
  • Keeping the export honest. Someone has to filter by payment status, handle refunds, and make sure an edited order isn’t uploaded twice.

How does PartialLeads find the gclid for a Shopify order?

It keeps the click on the visitor instead of the cart. The PartialLeads pixel records gclid, gbraid and wbraid on the visitor’s session at landing. When a paid order arrives from Shopify’s order webhooks, it’s matched back to that visitor, and a row with the click id, hashed email and phone, value and currency is written to a Google Sheet your Google Ads account imports on a schedule.

The click is captured where it appears. The tag reads Google’s click ids from the landing URL on the first page view, alongside UTMs and the referrer.

The order is joined to the person, not the cart. Orders come from Shopify’s webhooks, so nothing depends on the checkout page running a script. The order is matched to a session by visitor ID first, then email, then phone, then IP. Sessions are stitched into one person across visits, so a buyer who clicked on Monday and came back Direct on Thursday still carries Monday’s click.

Only paid orders become rows. An order is sent once its financial_status is paid. A cash-on-delivery or bank-transfer order is sent when it’s marked paid, not when it’s created.

The value is the full order total. That’s Shopify’s total_price, including tax and shipping, after discounts, in the order’s currency. There’s no subtotal option. An order is recorded once, so a later edit, like a post-purchase upsell added to it, doesn’t change its row.

PartialLeads Integrations Google Sheets page showing a connected sheet with offline-conversion rows for paid Shopify orders, each carrying a gclid, gbraid or wbraid, conversion time, value and currency, beside a Purchases ledger summary of matched and unmatched orders

Where you see it working. Integrations → Google Sheets shows the connected sheet and the rows written for paid orders, with their click ids. The Purchases ledger lists every paid order, matched or unmatched, so you can reconcile it against Shopify’s order list. On the Leads list, the API column shows which integrations each buyer was sent to.

The honest constraints.

  • A Google Sheet, not an API. PartialLeads writes rows. You create the import conversion action in Google Ads and schedule the import from the sheet, and Google credits orders after the next import runs.
  • No click, no credit. If the landing URL had no click id, or the buyer never came from a Google ad, the row has nothing for Google to match.
  • It doesn’t write the gclid back into Shopify. The click lives on the PartialLeads visitor and the sheet row, not in your Shopify admin.
  • Keep one source per purchase. PartialLeads uses its own event ids and doesn’t deduplicate against Google’s own Shopify app or another tag. Make one purchase conversion action primary.
  • Purchases only, for Google. There’s no GA4 integration.
  • We control the row; Google controls the match. Every paid order is written. Whether Google ties it to a click is Google’s side.
What breaks The mechanism Where you see it in the dashboard
Shopify has no gclid field on the order gclid, gbraid and wbraid captured on the visitor’s session at landing Leads list, Journey column
Buyer returns later or on another device, cart has no click Sessions stitched into one person; order matched by visitor ID, email, phone or IP Purchases ledger, matched vs unmatched
Import needs one clean row per sale Paid order from the webhook written with click id, value and currency Integrations → Google Sheets
Unpaid or cancelled orders inflate conversions Only orders with financial_status = paid are sent Purchases ledger
Two tools report the same purchase Own event ids, no cross-tool dedup, so one primary action Leads-list API column

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


Frequently asked questions

QDoes Shopify save the gclid on orders?
Not as its own field. A Shopify order records a landing page URL, a referring site, a source name and note attributes, but no gclid, gbraid or wbraid field. The click id can appear inside the landing page URL when the buyer landed from the ad and checked out in the same visit, or in note attributes if a script or app saved it to the cart.
QCan I get the gclid from Shopify's order export CSV?
Usually not. The standard order export has no click-id column, so there's no gclid to pull out directly. You need the Admin API, an app that saves the click id, or a tool that captures it at landing and writes your import rows for you.
QWhy do some Shopify orders have a gclid in the landing page URL and others don't?
The landing URL describes one visit. It carries the gclid only when the buyer arrived from the ad and ordered without leaving. A buyer who came back later by typing your address, switched devices, or used a link that stripped the query string has a landing URL with no click id in it.
QShould I upload pending or cash-on-delivery Shopify orders to Google Ads?
Not until they're paid. Upload an order once its financial status is paid. Pending, voided and cancelled orders aren't sales yet, and uploading them teaches Google's bidding to chase buyers who never paid. A cash-on-delivery or bank-transfer order can be uploaded once it's marked paid.
QDo I need gbraid and wbraid as well as gclid?
Yes, if you advertise to iPhone users. Some iOS clicks carry gbraid or wbraid instead of gclid. If you only save gclid, those buyers reach your export with an empty click column and can't be matched. Capture all three at landing and send whichever one the order has.
QCan I find the gclid for orders placed before I started capturing it?
Only if it happens to be in the order's landing page URL. Otherwise, no. The click id exists in the landing URL at the moment of the click, and if nothing saved it then, it can't be rebuilt from the order later. Start capturing now, and orders from visitors who land after that point will carry one.

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.