Docs menu · Google Ads and COD
Getting Started
Integrations
Server-side GTM
COD Order Protection
Advanced Features
Downloads
Tools & Support
Docs / COD Order Protection
Google Ads: Sheet import vs PixelFly hold & fire
Both methods send a conversion after a COD order is confirmed — not at fake checkout. They are different Google products with different rules for time, click IDs, and setup. This guide explains which to use and how PixelFly’s hold → fire path maps to Google’s requirements.
Full COD setup: COD + server GTM. Official Google docs: offline import guidelines, import errors & 90-day GCLID.
conversion_date_time.
Both need a real gclid (or wbraid / gbraid). Neither invents attribution without it.
Are PixelFly hold & fire OK for Google Ads?
Yes — when you do this:
- Store
gclid(and iOSwbraid/gbraidwhen present) at hold. - Send the confirmed purchase one of three ways:
- sGTM stores: fire path sGTM /data. PixelFly POSTs the purchase to
/datawith click IDs onpage_location, and the Google Ads Conversion (COD confirmed) tag in our server container fires (Client Name = Data Client). - Proxy stores, GA4 import: link GA4 to Google Ads and import the GA4 purchase. PixelFly sends the confirmed purchase to your GA4 Receiver with the shopper’s GA client and session IDs, so GA4 credits the ad click.
- Proxy stores, Google Ads API: a Google Ads (click conversions) Receiver uploads the purchase to an Import from clicks conversion action (needs a Google Ads API developer token).
- sGTM stores: fire path sGTM /data. PixelFly POSTs the purchase to
- Fire within your conversion window and within ~90 days of the click (Google retains GCLIDs ~90 days).
- Do not also fire a browser Purchase for the same COD order (double counting).
Use one of these per conversion action: the same order through two of them (or alongside a browser Google Ads Purchase tag) counts twice.
Side-by-side comparison
| Topic | Google Sheet / offline import | PixelFly hold → fire (sGTM) |
|---|---|---|
| What Google product | Conversion action: Import from clicks | Usually a Website (or GA4) conversion + sGTM Ads tag |
| How data is sent | Upload CSV / Sheet / API with gclid + time + value | Approve & Fire → POST /data → Data Client → Ads tag |
| Conversion time | You set conversion_date_time with timezone (yyyy-mm-dd HH:mm:ss±HH:mm). Must be after the click |
Hit arrives at fire time; gclid links to the original click. PixelFly also stores checkout event_time (critical for Meta) |
| Click ID | gclid / wbraid / gbraid column required for click match | Same IDs held at checkout, replayed on page_location + event fields |
| GCLID age limit | Upload more than ~90 days after click → rejected | Fire outside window / ~90 days → usually not attributed |
| Speed | Batch; often ~3 hours to appear | Near real-time on Approve; UI can still lag hours |
| Meta / TikTok | Google Ads only | Same fire can hit Meta, GA4, TikTok tags |
| Deduping | order_id / unique gclid + name + datetime | transaction_id = Woo order id on the Ads tag |
| Common failure | Wrong timezone (“conversion precedes click”), late upload, wrong conversion action | No gclid at hold, fire path = Receivers only, browser Purchase still fires for COD |
Event time explained (simple)
Day 0 Click ad (gclid created)
Day 0 COD order placed → PixelFly HOLD (store gclid + checkout event_time)
Day 3 Order confirmed → PixelFly FIRE
Sheet: you upload conversion_date_time = Day 0 or Day 3 (your choice; must be after click)
sGTM: Google Ads tag runs on Day 3; attribution still ties back via gclid to Day 0 click
Google Ads campaign reports usually credit the click / impression date, not the upload or fire date. To compare with your order list, add All conv. (by conv. time) in Google Ads (conversion reporting help).
event_time for Meta CAPI (correct for delayed events).
Google Ads website tags primarily need a valid gclid on the fired hit; they are not the same as Sheet’s mandatory conversion_date_time column.
Architecture — PixelFly path for Google Ads
Web GTM: purchase + payment_method + email + phone + gclid → sGTM
→ PixelFly COD Protection tag → POST /cod/hold
→ Held Events (pending)
Confirm order
→ Approve & Fire (fire path = sGTM /data)
→ POST {host}/data (gclid on page_location, transaction_id, value, user_data)
→ Data Client → Google Ads Conversion tag
Proxy store
→ Approve & Fire → Worker → GA4 Receiver → (GA4 → Google Ads import)
or → Google Ads Receiver → uploadClickConversions
Architecture — Sheet / offline import
Capture gclid at checkout (cookie / CRM / Sheet row)
Confirm COD order
→ Append row: Google Click ID | Conversion Name | Conversion Time | Value | Currency | Order ID
→ Upload to Google Ads (Import from clicks)
→ Google matches gclid → conversion
When to use which
- Prefer PixelFly hold & fire if you already use server GTM, want Meta + Google from one approve, and want near real-time fire from the dashboard or Woo webhook.
- Prefer Sheet / OCI if ops already live in Sheets/CRM, or you need an exact confirm timestamp in an Import from clicks action. (Proxy stores no longer need it: use the GA4 import or the Google Ads Receiver.)
- Do not use both for the same COD purchase into the same “primary” conversion unless you intentionally want two actions and understand double counting.
Checklist — Google Ads with PixelFly
- Web GTM forwards plaintext
email,phone,payment_method, andgclidto sGTM (not hashed phone as the phone field). - sGTM COD tag holds COD only; browser Ads Purchase = prepaid only (
payment_method≠cod). - sGTM: dashboard fire path = sGTM /data; Data Client accepts
/data; Google Ads tag trigger =purchase+ Client = Data Client +is_delayed= true. Proxy: a GA4 Receiver (with the GA4 import) or a Google Ads Receiver. - Pass
transaction_id= order id on the Ads tag. - Confirm Held Event raw payload shows
gclidbefore you rely on Ads attribution. - Fire within the conversion window (and < ~90 days from click).
FAQ
Is hold & fire “as good as” Sheet import?
For attribution quality, both depend on gclid and timing windows.
Sheet gives stricter control of conversion_date_time.
PixelFly is better for automation and multi-platform fire.
Neither works without click IDs (or a strong Enhanced Conversions match on an import action).
Why did my held order have no gclid?
The visitor had no Google click cookie / parameter, or Web GTM did not forward gclid to sGTM.
PixelFly stores what the hold receives — fix mapping, then test a new order from a Google Ads click.
Can I use Receivers /e for Google Ads?
Yes: add a Google Ads (click conversions) Receiver (Google Ads API: developer token, OAuth, customer ID and an Import from clicks action), or send the purchase to a GA4 Receiver and import it into Google Ads. Receivers don’t run sGTM tags, so on sGTM stores the server Google Ads tag with fire path sGTM /data is simpler.