Google Ads Integration

Capture GCLIDs, pass them through your affiliate funnel, and send server-side conversions back to Google Ads — including Enhanced Conversions and Google Transparency Mode.

Overview

  • GCLID capture — reads gclid from landing URL and stores it alongside utk_click_id
  • Google Transparency Mode — passes clientId to Google's Consent-Mode compatible endpoint
  • Server-side conversions — sends conversion events to Google Ads API from your server, not the browser
  • Enhanced Conversions — hashes PII and passes to Google for improved match rates

GCLID Capture

The SDK automatically reads gclid from the landing URL and stores it as utk_gclid in a first-party cookie (30-day TTL). No extra configuration is needed.

JavaScript
var gclid = AffclixSDK.getAttribution().gclid;
console.log(gclid); // e.g. "Cj0KCQj..."
Auto-tagging required

Enable auto-tagging in Google Ads under Settings → Account Settings → Auto-tagging so gclid is appended to all ad destination URLs.

Google Transparency Mode

Transparency Mode is Google's Consent Mode v2 compatible approach for advertisers in the EEA and UK. When enabled, the SDK routes conversion events through the Transparency endpoint and includes clientId for modelled conversion support.

JavaScript
AffclixSDK.init({
  trackingDomain:        't.yourdomain.com',
  useGoogleTransparency: true,
  clientId:              'AW-123456789'
});

When useGoogleTransparency is true, client_id is appended to every tracking request. Clicks and conversions still go to the standard /c and /p endpoints on your tracking domain, which handle Google Ads transparency server-side.

Send Conversion to Google Ads

Client-side (gtag)

JavaScript
// 1. Fire the Affclix conversion postback
AffclixSDK.trackConversion({
  campaignID: 'YOUR_CAMPAIGN_ID',
  eventName:  'purchase',
  conversionData: {
    txn_id:   'ORDER-1001',
    sale:     '99.00',
    currency: 'USD'
  }
}).then(function() {
  // 2. Mirror it to Google Ads — fires gtag 'conversion' with your label
  AffclixSDK.adPlatforms.google.sendConversionEvent('AW-123456789/AbCdEfGhIjKl', {
    value:          99.00,
    currency:       'USD',
    transaction_id: 'ORDER-1001'
  });
});

Server-side postback

HTTPS POST
GET https://t.yourdomain.com/p
    ?auth={YOUR_SECURITY_TOKEN}
    &c={CAMPAIGN_ID}
    &click_id={CLICK_ID}
    &txn_id={ORDER_ID}
    &sale=99.00
    ¤cy=USD
    &gclid={GCLID}

Enhanced Conversions

Pass hashed customer data to improve conversion matching in Google Ads. The SDK automatically SHA-256 hashes PII before sending.

JavaScript
// Forwarded to gtag('set', 'user_data', ...) — Google normalises and
// hashes these values before they leave the browser.
AffclixSDK.adPlatforms.google.setUserData({
  email:        'customer@example.com',
  phone_number: '+919876543210',
  address: {
    first_name:  'Arjun',
    last_name:   'Sharma',
    city:        'Mumbai',
    postal_code: '400001',
    country:     'IN'
  }
});

AffclixSDK.trackConversion({
  campaignID: 'YOUR_CAMPAIGN_ID',
  eventName:  'purchase',
  conversionData: { txn_id: 'ORDER-1001', sale: '99.00', currency: 'USD' }
});
Hashing

All PII fields are normalised (lowercase, trimmed) and SHA-256 hashed by the SDK before leaving the browser. Raw PII is never sent to Affclix servers.

UTM + Google Attribution Flow

01

Ad Click

Google appends gclid and your UTM params to the landing URL.

02

SDK Captures on Landing

AffclixSDK.init() stores gclid, utm_source, utm_campaign, and utk_click_id in cookie + localStorage.

03

User Converts

On the thank-you page, trackConversion() reads stored attribution from the cookie/localStorage stack and includes it in the postback payload.

04

Affclix Credits Affiliate

Affclix matches utk_click_id to the affiliate, credits the commission, and forwards gclid to Google Ads via Offline Conversion Import.

Redirect Transparency

When the click passes through anything beyond Affclix, each hop consumes the landing URL instead of forwarding it. Google then loses sight of the destination and disapproves the ad for a destination mismatch — even though the page loads perfectly when you click it yourself.

The transparency flag tells every step of the chain to keep the original {lpurl} visible:

Tracking template with a redirect
https://acme.affclix.com/c?c=101&a=55&url={lpurl}&gclid={gclid}&force_transparent=true
force_transparent overrides your S2S setting

With the flag on, the click is redirected in the browser rather than handled server-side, whatever the campaign's server-to-server configuration says. Conversions that depend on the S2S path stop lining up — and you find out from a reporting gap a week later, not from an error. Tell the generator the campaign uses S2S and the audit will say so up front.

Add the flag only when the click really does redirect onward. On a direct Affclix-to-advertiser link it does nothing.

Destination Matching

Google compares the URL the user actually reaches against the final URL the ad declares. Three rules decide whether they match.

RuleWhat breaks it
The landing URL sits in the destination parameter{lpurl} placed anywhere other than after &url= — the tracker reads the destination from that parameter and nowhere else, so the click has no landing page even though the macro is present. The tracker also honours url= only when the click carries a real Google click ID (gclid, gbraid, wbraid or dclid) or force_transparent=true; with auto-tagging off, and the campaign's deep link setting off, the click goes to the campaign URL instead.
Same registrable domain as the display URLA final URL on a different domain from the one the ad displays. Google matches the registrable domain, so shop.example.com is fine when the display URL is example.com — what breaks it is a display URL naming another domain entirely, or a cross-domain redirect in the chain.
Identical parameters on both URLsA parameter present on only one side, or the same parameter carrying different values. Google counts either as a mismatch, even though the two URLs read as equivalent to a human.
Click IDs and UTMs are exempt

gclid, gbraid, wbraid, dclid and the utm_* parameters are appended by Google itself, so they are allowed to appear on the final URL without also being on the tracking URL. Everything else is compared.

Parallel Tracking & GCLID Capture

Parallel tracking is mandatory on Google Ads. Instead of redirecting the user through the tracker, Google sends the browser straight to the landing page and fires the tracking URL as a background beacon.

01

Click

Google opens the final URL in the browser and fetches the tracking template in the background, carrying gclid and your parameters.

02

Beacon

Nothing renders that response — no browser is watching it. The tracking path must answer with a 302 (/c, /cb, /sl); an interstitial or a JavaScript bounce page is never executed, so the chain stops at the tracker.

03

Capture on arrival

The gclid reaches the landing page, not the tracker. Capture it on the user's first arrival — the WebSDK stores it as utk_gclid in a first-party cookie for 30 days.

04

Replay on conversion

On the thank-you page, read the stored gclid back and send it with the conversion so Google can match it to the click that produced it.

gclid without utm_source reads as organic

A landing URL carrying gclid but no utm_source is attributed to organic traffic by analytics, click id and all, and the conversion is credited to the wrong channel. Set a final URL suffix of utm_source=google&utm_medium=cpc.

iOS sends a different click ID

On iOS, Google sends gbraid or wbraid instead of gclid. A template that captures only gclid loses iOS attribution completely rather than partially — the clicks arrive with an empty click-id column.

How the Tracker Handles Google Clicks

A click counts as a Google Ads click when it arrives with a real gclid, gbraid, wbraid or dclid, or with force_transparent=true. Ordinary affiliate traffic has none of these and is handled exactly as before.

SituationWhat the tracker does
Google's destination checker (AdsBot-Google) requests the templateAnswered with the same 302 a person would get — to the url= destination when present, otherwise to the campaign URL. Nothing is recorded: no click row, no capping, no payout. Other bots on the click path, including Googlebot, are still blocked.
The template carries url={lpurl}The click lands on that final URL, whatever the campaign's deep link setting says, and even when the campaign rotates landing pages. Only http and https destinations are followed.
Google sends the literal {gclid}This means auto-tagging is off. The unsubstituted macro is dropped rather than stored, so the click is recorded with an empty gclid instead of one ID shared by every click on the account.
The click is sent on to the landing pagegclid, gbraid, wbraid and dclid are added to the outgoing URL when it does not already carry them, so the landing page can capture them even under sequential tracking.
force_transparent=true is setThe click is always a plain 302, even when the campaign is set to a referrer-hiding redirect mode that answers with an HTML page. When the next hop is another Affclix tracking link, the flag, the destination and the click IDs are passed on to it; they are never added to an advertiser's offer URL.
The click is rejected (cap reached, targeting, fraud rules)A Google Ads click is still redirected to the declared destination instead of receiving an error, because Google treats an error at the end of a template as a broken destination and disapproves the ad. The click is still recorded as REJECTED, capping does not move and the affiliate earns nothing.
Self-hosted trackers

Each behaviour can be switched off with a GOOGLE_ADS_* environment variable on the tracker (for example GOOGLE_ADS_REDIRECT_REJECTED=false), and GOOGLE_ADS_ENABLED=false turns all of them off. Parameter names such as url and force_transparent must match on the tracker and the dashboard, or templates built in the dashboard stop being recognised.

Operational Guidance

Before you spend

  • Auto-tagging is on — Settings → Account Settings → Auto-tagging. Without it Google appends no gclid at all and every {gclid} in every template resolves to nothing.
  • The generated audit shows no blocking issues.
  • One live test click has run, and the gclid is visible in the landing page URL and stored in the cookie.
  • One test conversion has been sent and appears in both Affclix and Google Ads.

Audit what is actually configured

A template built correctly here and then pasted into the wrong Google Ads box — or edited later by whoever runs the ads — is the ordinary way this breaks, and nothing on the Affclix side can see it. With a connected Google Ads integration, read the live account instead:

Shell
# Audit every tracking template on a connected account
php artisan google-ads:audit-tracking --integration=12 --final-url=https://example.com/offer

# Pre-flight a tracking URL without calling Google
php artisan google-ads:audit-tracking \
    --url="https://acme.affclix.com/c?c=101&a=55" \
    --final-url="https://example.com/offer" \
    --chain="partner-network.com" --s2s

For a connected account the audit reads the account-level tracking template, final URL suffix and auto-tagging setting, then every campaign that is not removed:

  • A campaign with no template of its own is audited against the account-level template it inherits, and is labelled as inheriting it.
  • A campaign with no template anywhere is listed but not audited — its clicks go straight to the final URL, which is a valid setup.
  • Auto-tagging switched off is reported once for the whole account, not repeated as a missing gclid on every campaign.
  • Add --json for machine-readable output.
Account and campaign level only

Templates set on an ad group, ad, keyword or sitelink override the campaign template and are not read yet. If you use them, check those levels in Google Ads by hand.

The command exits non-zero when anything blocking is found — including auto-tagging switched off — so it can gate a deploy.

When something is wrong

SymptomUsual cause
"Destination not working" / "Destination mismatch"A redirect chain with no transparency flag, a landing page on a different registrable domain from the display URL, or a parameter on the final URL that the tracking URL does not carry.
Ad serves, clicks recorded, no conversionsgclid never captured on the landing page, or the cookie expired before the user converted.
Clicks recorded, gclid column emptyAuto-tagging is off, so Google sent the literal {gclid} and the tracker dropped it. Turn auto-tagging on.
Literal {click_id}-style tokens in a report columnAn Affclix token used in a Google template. Google forwards it untouched, so the literal braces land in the report — use the ValueTrack equivalent.
Traffic reported as organicNo utm_source on the landing URL. Set the final URL suffix.
iOS clicks have no click IDgbraid and wbraid are not in the template.
Nothing recorded at all, ad serving normallyThe template was pasted into the wrong Google Ads box, or points at something other than an Affclix tracking path (/c, /cb, /sl). Run the account audit above to see what is actually configured.
Clicks recorded, but "Destination mismatch" and traffic landing on the campaign URLAn encoded macro (%7Blpurl%7D), so the tracker never saw a destination.
Rate this article
★★★★★
Thanks for rating!

Was this article helpful?