Skip to content

Send the ad click IDs to Stripe alongside the UTM parameters - #323

Merged
paulocastellano merged 1 commit into
mainfrom
feat/checkout-metadata-click-ids
Sep 1, 2026
Merged

Send the ad click IDs to Stripe alongside the UTM parameters#323
paulocastellano merged 1 commit into
mainfrom
feat/checkout-metadata-click-ids

Conversation

@paulocastellano

@paulocastellano paulocastellano commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #322, which sent the UTM parameters and onboarding answers to the Stripe subscription but left the ad click IDs behind.

UTM parameters say which campaign a customer came from. The click ID identifies the individual click — which is what Google Ads and Meta need to match a paying subscription back to the exact ad that produced it. Without it the attribution stops at campaign level and offline conversion import is not possible.

Signup already captures one per network, so this is purely a forwarding change:

column network
gclid Google
fbclid Meta
li_fat_id LinkedIn
ttclid TikTok
rdt_cid Reddit
epik Pinterest

Every key is spelled out at the call site rather than mapped over a constant, so what reaches Stripe can be read in one place without following an indirection.

The 500-character cut is load-bearing here

Stripe caps a metadata value at 500 characters and rejects the request rather than truncating. A rejected request means the checkout session is never created and the customer cannot subscribe at all — silent lost revenue, triggered by whatever happened to be in their signup URL.

In #322 this could not happen: the UTM columns are varchar(255). The click IDs are deliberately texta3b85d19 established that truncating them at 255 destroys their value — so they are unbounded and the ceiling is now reachable. Cutting at 500 on the way out trades a truncated click ID for a checkout that still works.

Not included: X / Twitter

There is no twclid column, and nothing captures it at signup. Adding it is a migration plus capture wiring, not a metadata change, so it is out of scope here — worth its own PR if we run X ads.

Tests

StartSubscriptionCheckoutTest covers the full payload including all six click IDs, an owner with nothing filled in ([]), and a 900-character fbclid arriving at Stripe as exactly 500.

Full suite green: 4063 passed.

@paulocastellano
paulocastellano force-pushed the feat/checkout-metadata-click-ids branch from 88667a7 to 9cec1d7 Compare September 1, 2026 01:56
Signup already captures a click ID per ad network -- gclid, fbclid,
li_fat_id, ttclid, rdt_cid, epik -- but only the UTM parameters reached
the subscription. UTMs say which campaign a customer came from; the click
ID identifies the individual click, which is what Google and Meta need to
match a subscription back to the ad that produced it.

Every key is spelled out at the call site, so what reaches Stripe is
readable in one place without following a constant.

Click IDs are text columns on purpose, since truncating them at 255 would
destroy the value. Stripe caps a metadata value at 500 characters and
rejects the request rather than truncating, so an unbounded column
reaching it would fail the whole checkout and the customer could not
subscribe at all. Values are cut to 500 before they are sent. The UTM
columns are varchar(255) and cannot reach it; this exists for the text
ones.
@paulocastellano
paulocastellano force-pushed the feat/checkout-metadata-click-ids branch from 9cec1d7 to 80ffdc1 Compare September 1, 2026 01:58
@paulocastellano
paulocastellano merged commit b689e39 into main Sep 1, 2026
5 checks passed
@paulocastellano
paulocastellano deleted the feat/checkout-metadata-click-ids branch September 1, 2026 02:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant