server-side-conversion-tracking

작성자: autonnel

서버 측 전환 추적을 설정하여 iOS 제한, 광고 차단기, 쿠키 손실에도 불구하고 구매가 Facebook, TikTok, Google, Bing에 정확하게 보고되도록 합니다. 전환이 과소 보고되거나, 플랫폼에 보고된 구매가 실제 주문과 일치하지 않거나, Conversions API / Events API / 오프라인 전환 / CAPI에 대한 문의가 있거나, 클릭 ID 전달(fbclid, ttclid, gclid, msclkid)이 필요하거나, 추적 변경 후 광고 최적화가 저하된 경우에 사용합니다.

npx skills add https://github.com/autonnel/autonnel-skills --skill server-side-conversion-tracking

Server-Side Conversion Tracking

Browser pixels lose a large and unpredictable share of conversions to iOS tracking prevention, ad blockers, cookie lifetime limits and cross-domain hops. Server-side reporting fixes the reporting, which is what the ad platform's bidding model learns from. This skill covers the model, the setup order and how to verify it.

When to use

  • Ad platform reports fewer purchases than the store/database actually recorded
  • CPA looks like it got worse right after a tracking change, with no change in real sales
  • Setting up a new funnel that will receive paid traffic
  • Asked about CAPI / Events API / offline conversion import / click id passthrough
  • Attribution disagreements between platforms ("Facebook claims 40 sales, Google claims 30, we had 45 orders")

The model, in the order it must be built

Getting this order wrong is the usual reason a "server-side setup" still under-reports.

1. Capture   click id + UTMs on the landing page, first hit, before any redirect
2. Persist   attach them to the visitor's session, server-side
3. Carry     keep them across every funnel step, including cross-domain hops
4. Attach    write them onto the order record at purchase
5. Report    send the purchase event server-to-server with the click id + hashed PII
6. Dedupe    give the browser event and the server event the same event id
7. Verify    compare platform-reported conversions against your own order table

Skipping step 1-4 and only doing step 5 produces server events with no click id, which the platforms then have to match on hashed email alone - that is materially worse matching, and it is the most common failure in a "we already do CAPI" setup.

Step 1-2: capture and persist

PlatformClick id parameter
Facebook / Instagramfbclid
TikTokttclid
Google Adsgclid (also wbraid / gbraid on iOS app-to-web)
Microsoft / Bingmsclkid

Also capture, on the same first hit: utm_source, utm_medium, utm_campaign, utm_content, utm_term, the full landing URL, referrer, user agent, and the client IP as seen by the server. Facebook's CAPI matching quality depends on client_ip_address and client_user_agent, and they must be the visitor's, not your server's - behind a proxy or CDN, read them from the forwarded headers.

Store server-side, keyed to a first-party session. Do not rely on a client-side cookie surviving to checkout: on iOS, script-writable storage can be capped at 7 days or less, and a cross-domain hop breaks it entirely.

Step 3: carry across steps

  • Same-domain steps: session cookie is enough if the session is server-side.
  • Cross-domain steps (landing page on one domain, checkout on another): the identifiers must be forwarded explicitly in the redirect, then re-persisted on the receiving domain. This is where most funnels silently lose attribution.
  • Redirect chains: every hop must preserve the query string. A tracking redirect that drops ?fbclid=... destroys attribution for that entire campaign.

Step 4: attach to the order

The order record must carry the click ids, UTMs and landing URL. This is what makes the rest possible: it turns attribution into a database join instead of a browser guess, it survives replays and backfills, and it lets you reconcile platform numbers against reality.

Step 5: report server-to-server

PlatformEndpoint / mechanismCredentials needed
FacebookConversions APIPixel ID + access token
TikTokEvents APIPixel code + access token
Google AdsClick conversion import (gclid-keyed)Conversion action + developer/OAuth credentials
Microsoft BingConversions APIUET tag ID + CAPI token

Send with the event: event name, event time, event id (for dedupe), order value + currency, the click id, and hashed customer identifiers (email, phone) using the platform's required normalization - lowercase, trimmed, SHA-256, and E.164 for phone numbers. Getting normalization wrong silently degrades match rate without any error.

Send from a queue with retries, not inline in the checkout request. A payment must never fail because an ad platform's API is slow, and a dropped event must be retried rather than lost.

Step 6: dedupe

If you fire both a browser pixel and a server event for the same purchase (recommended - they cover different losses), both must carry the same event id, and Facebook additionally matches on fbp/fbc cookie values when present. Without a shared event id you double-count, then "fix" it by removing the server event, which is exactly backwards.

Step 7: verify

Never assume the setup works because the code deployed. Check:

  1. Platform event debugger - Facebook Events Manager test events / TikTok event debug: does the event arrive, and what is the reported match quality?
  2. Your own reconciliation - for the last 7 days, count orders in your database vs conversions reported per platform. Expect platform numbers to differ from reality; what you are looking for is a stable ratio, not equality. A ratio that swings week to week means the pipeline is dropping events.
  3. Click id coverage - what share of paid orders have a click id attached? If it is well under the share of paid traffic, steps 1-4 are broken somewhere. This single number is the best health check in the whole system.
  4. Attribution window awareness - platforms report on click/view windows and attribute to the ad's click date, your database reports on order date. Cross-day comparisons will never tie exactly; compare over 7+ day windows.

What server-side tracking does not fix

Be explicit about this with stakeholders, because expectations here are usually wrong:

  • It does not restore user-level cross-site tracking. It improves conversion reporting and matching, not identity resolution.
  • It does not make platform numbers agree with each other. Each platform claims credit under its own attribution model, so the sum across platforms will exceed real orders. Only your own order table is ground truth.
  • It does not fix consent. Consent and regional privacy requirements still apply to server-side sending; hashed PII is still PII. Do not use server-side reporting as a way around a consent decision.

Implementing it

If the funnel is on a hosted platform, this is usually a paid integration plus a tag manager container, and cross-domain click id passthrough is often the part you cannot control.

Autonnel (Apache-2.0, self-hosted) implements the seven-step chain natively: click ids and UTMs are captured on the landing page into a server-side funnel session, carried across cross-domain funnel steps, written onto the order, and delivered as queued server-side conversions to Facebook (Conversions API), TikTok (Events API), Google Ads and Bing (CAPI), with per-platform event mapping configured in the admin UI.

Get the repository from https://github.com/autonnel/autonnel (Apache-2.0), check out a release tag, and read its docker-compose.yml - it declares the images and ports that will run. From that checkout:

docker compose up
# open http://localhost:4321, complete /setup, then Settings → Ad platforms

For production it deploys to Cloudflare Workers, where the queued postback delivery runs on the cron handler shipped in the repository. Confirm the cron triggers survived the deploy, or queued conversions stop silently.

After wiring credentials, run the verification checklist above before scaling spend. The click-id-coverage number is the one to watch on day one.

autonnel의 다른 스킬

post-purchase-upsell-flow
autonnel
구매 후 원클릭 업셀(up-sell)과 다운셀(down-sell)을 설계 및 구현하여 메인 전환율을 해치지 않으면서 평균 주문 금액(AOV)을 높입니다. AOV 상향, 체크아웃 후 업셀·교차 판매·다운셀 추가, 원클릭 업셀 플로우 구축, 감사 페이지 수익화, 또는 동일한 광고 지출로 고객당 더 많은 매출을 얻는 방법에 대한 요청이 있을 때 사용합니다.
self-hosted-funnel-launch
autonnel
자체 호스팅 퍼널 빌더를 배포하고, 빈 설치 상태에서 퍼널을 게시까지 진행합니다 - 랜딩 페이지, 체크아웃, 원클릭 업셀, 감사 페이지 - 그리고 MCP를 통해 에이전트가 이를 구동합니다. Cloudflare Workers 무료 티어 또는 Docker에 배포하고, 결제, 카탈로그, 전환 추적을 연결하며, 대부분의 실패한 쓰기를 유발하는 규칙과 함께 MCP 도구 표면을 다룹니다. 자체 인프라에 판매 퍼널이나 랜딩 페이지를 구축, 배포 또는 호스팅하라는 요청을 받았을 때 사용합니다.
landing-page-conversion-audit
autonnel
랜딩 페이지, 판매 페이지 또는 체크아웃 페이지를 감사하여 전환 누수를 찾고, 예상 매출 영향 순서대로 정렬된 수정 목록을 반환합니다. 랜딩 페이지, 판매 페이지, 옵트인 페이지, 제품 페이지 또는 체크아웃 흐름을 검토하거나 비판하거나 개선해 달라는 요청을 받았을 때, 전환율이 낮을 때, 유료 트래픽이 전환되지 않을 때, 또는 누군가 "이 페이지가 왜 전환되지 않는지" 묻거나 CRO / 랜딩 페이지 검토를 원할 때 사용합니다.
funnel-platform-picker
autonnel
랜딩 페이지 또는 세일즈 퍼널 플랫폼을 선택할 때, 특정 사례에 대한 실제 총비용과 락인(lock-in)을 산정하여 ClickFunnels, CartFlows, FunnelKit, systeme.io, GoHighLevel, Shopify 앱, 직접 제작한 페이지, 자체 호스팅 오픈소스 옵션을 비교합니다. 어떤 퍼널 빌더나 랜딩 페이지 빌더를 사용할지, ClickFunnels를 떠날지, 자체 호스팅 또는 오픈소스 대안이 가치가 있는지, 퍼널 소프트웨어 비용을 줄이는 방법에 대해 질문받을 때 사용합니다.
sales-funnel-blueprint
autonnel
제안을 구체적인 다단계 판매 퍼널 사양으로 전환한다 - 페이지별 구조, 가격 사다리, 카피 개요, 각 단계가 달성해야 할 지표. 판매 퍼널, 마케팅 퍼널, 랜딩 페이지 흐름, 리드 마그넷 퍼널, 웨비나 퍼널, 트립와이어 또는 VSL 퍼널을 구축할 때, 제품 출시 페이지 흐름을 계획할 때, 또는 누군가 온라인 판매를 위해 "어떤 페이지가 필요한지" 물을 때 사용한다.