본문으로 건너뛰기
LinkProfit

단축 링크 전환 추적: 클릭 식별자, 귀속 기간, 서버 이벤트

LinkProfit Team읽는 데 12분
  • conversions
  • analytics
  • attribution
  • link-shortener
이 페이지의 목차

모든 링크 보고서에는 자연스럽게 멈추는 지점이 있고, 대부분의 팀에게 그 지점은 클릭입니다. 대시보드는 지난달에 링크가 4,000번 열렸다고 알려 주고 국가와 기기, 브라우저, 소스로 나누어 보여 주며, 분석은 거기서 끝납니다. 그러나 클릭 4,000건은 여러분이 얼마를 썼는지를 말해 줄 뿐 얼마를 벌었는지는 말해 주지 않습니다. 퍼널의 값싼 절반이자, 스크린샷에서 가장 그럴듯해 보이는 절반입니다.

전환 추적은 리디렉션 시점의 식별자를 결국 주문을 기록하게 될 시스템까지 실어 나른 뒤 다시 돌려받는 방식으로 이 간극을 닫습니다. 설명하기는 쉬운 아이디어이지만, 몇 달이 지나서야 청구서와 맞지 않는 매출 보고서로 드러나는 방식으로 잘못되기도 쉽습니다. 이 글은 식별자, 귀속 기간과 그것이 왜 사업상의 결정인지, 서버 이벤트와 브라우저 이벤트의 차이, 돈을 정수로 다루는 이유, 중복을 처리하는 방식, 그리고 통제하지 못하는 시스템에서 전환이 일어날 때 무엇을 해야 하는지를 다룹니다.

클릭은 결과가 아니라 비용입니다

클릭까지만 보는 보고서가 사라지지 않는 이유는 클릭이 재기 쉬운 측정값이기 때문입니다. 리디렉션은 여러분이 통제하는 인프라에서 일어나므로 세는 데 누구의 협조도 필요 없지만, 그 아래에서 벌어지는 일은 모두 다른 곳에서 일어납니다. 링크 클릭이 실제로 추적되는 방식에서 클릭 이벤트 하나에 무엇이 담길 수 있는지 다루었는데, 요약하면 클릭이 일어났다는 사실은 알지만 그 뒤에 무슨 일이 있었는지는 전혀 모른다는 것입니다.

이 한계에는 실제 대가가 따릅니다. 두 게재 위치가 똑같은 클릭 물량을 만들어도 한쪽은 구매자를 보내고 다른 쪽은 3초 만에 이탈하는 사람을 보낼 수 있습니다. 클릭 기준으로는 인상적인 국가별 분류가 매출 기준으로는 뒤집히기도 합니다. 클릭률로 승패를 가른 분할 테스트는 더 자극적인 제목과 더 나쁜 결제 완료율을 가진 변형을 고르기 일쑤입니다. 같은 분류에 매출이 붙기 전까지 그런 판단은 모두 지표의 옷을 입은 추측입니다.

매출을 붙이는 데 필요한 것은 하나뿐입니다. 리디렉션에서 주문까지 가는 여정을 살아남는 값입니다.

식별자가 설계의 전부입니다

워커는 리디렉션할 때마다 토큰을 발급하고 그것으로 두 가지 일을 합니다. 여러분이 정한 파라미터 이름으로 목적지 주소에 토큰을 붙이는데 기본값은 lp_cid이고, 같은 값을 여러분의 리디렉션 도메인에 90일 동안 유효한 퍼스트파티 쿠키로 기록합니다.

사본이 둘인 이유는 어느 쪽이든 사라질 수 있기 때문입니다. 목적지는 쿼리 파라미터를 지웁니다. 주소를 깔끔하게 만들려고 일부러 그러기도 하고, 그쪽에서 일어난 리디렉션의 부수 효과로 그렇게 되기도 합니다. 한편 오늘 클릭한 뒤 사흘 지나 주소를 직접 입력해 돌아온 방문자에게는 파라미터가 남아 있지 않지만 쿠키는 그대로 있습니다. 어느 한쪽만으로는 믿을 수 없고, 둘을 합치면 구매에 이르는 현실적인 경로 대부분을 덮습니다.

쿠키가 퍼스트파티라는 점은 사소한 기술적 세부 사항이 아닙니다. 이 쿠키는 방문자가 실제로 이동해 간 주소, 즉 여러분 자신의 리디렉션 도메인이 설정하며, 이것이야말로 브라우저들이 그동안 제거하지 않고 남겨 둔 쿠키 범주입니다. 맞춤 도메인이 브랜딩 취향이기를 그만두고 측정 인프라가 되는 이유가 여기에 있습니다. 사업자와 공유하는 도메인에서는 그 쿠키가 사업자의 것입니다.

토큰에 담기는 것

토큰은 서명되어 있고, 서명이 덮는 범위는 클릭만이 아닙니다. 워크스페이스와 파트너 식별자가 서명된 페이로드의 일부이므로, 한 고객의 링크에서 발급된 토큰은 다른 고객의 워크스페이스에서 위조와 똑같이 거부됩니다. 여러 고객의 링크를 운영하는 쪽에서는 한 고객의 매출이 다른 고객의 보고서에 섞이지 않는 일이, 누군가 잊지 않고 걸어 둔 필터가 아니라 구조 자체로 보장됩니다.

토큰에 담기는 것은 일부러 좁게 정해 두었습니다. 클릭 시각, 링크, 분할 변형, 국가, 기기 등급, 트래픽 소스, 그리고 의심스러운 트래픽 표시입니다. 개인 정보는 없습니다. 매출 열이 쓸모 있어지는 이유도 바로 이 목록입니다. 각 필드가 곧 분석에서 매출을 나누어 볼 수 있는 차원이 되므로, 무엇과도 두 번째로 결합할 필요가 없습니다.

파라미터 이름과 켜고 끄는 스위치는 워크스페이스 설정에 있으며, 둘 중 무엇을 바꾸든 모든 링크의 캐시된 설정이 즉시 다시 기록됩니다. 미리 계획해 둘 만한 결과가 하나 있습니다. 요금제에 전환이 포함되어 있지 않으면 리디렉터는 식별자를 아예 발급하지 않으며, 나중에 켜더라도 이미 일어난 클릭에 대해 소급해서 식별자가 만들어지지는 않습니다.

귀속 기간은 사업상의 결정입니다

귀속 기간은 전환의 공을 인정받을 수 있는 클릭의 최대 나이입니다. 워크스페이스마다 정하는 설정이며, 여기 나오는 숫자 가운데 기본값으로 받아들이는 대신 한 번은 논쟁을 거쳐야 할 유일한 값입니다.

너무 짧게 잡으면 여러분이 진짜로 만들어 낸 매출을 버리게 됩니다. 지나치게 길게 잡으면 어차피 일어났을 구매까지 링크의 공으로 돌리게 되는데, 이것은 자신 있게 틀린 답이라 쓸모없는 것보다 더 나쁩니다. 이미 추적할 수 있는 주문에서 첫 접촉과 구매 사이의 간격을 재어서 정하십시오. 충동 구매는 몇 분 만에 끝나고, 숙고를 거치는 소비자 구매는 며칠이 걸리며, 결재 단계가 있는 기업 구매는 몇 주가 걸립니다.

이 설계가 피하려는 실패 방식은 조용한 거부입니다. 기간을 넘겨 도착한 전환은 attribution_expired로 거부되며, 이것은 invalid_click_id와 구분되는 코드입니다. 두 상황은 서로 완전히 다른 수정을 요구하고, 둘 다에 똑같이 두루뭉술한 오류를 받는 연동은 엉뚱한 곳을 일주일 동안 파헤치게 됩니다. 코드를 기록하고, 둘을 따로 세고, attribution_expired 비율이 올라가는 것은 귀속 기간이 더 이상 판매 주기와 맞지 않는다는 신호로 보십시오.

들어오는 두 경로의 상한도 서로 다릅니다. 쿠키는 90일 동안 살아 있으므로 쿠키에 의존하는 브라우저 쪽 보고는 그보다 오래갈 수 없습니다. 서버 쪽 보고는 식별자 자체를 저장하므로 워크스페이스의 귀속 기간에만 묶입니다.

들어오는 길은 둘, 규칙은 하나

두 경로 모두 같은 서비스를 지나므로 귀속 기간과 중복 제거, 외부 전송이 똑같이 동작합니다. 다른 것은 각 경로가 무엇을 견뎌 내는지, 그리고 여러분에게 무엇을 요구하는지입니다.

서버 이벤트

여러분의 백엔드가 식별자와 함께 목표, 주문 식별자, 금액, 통화를 전송합니다.

curl -X POST https://api.linkprofit.com/v1/conversions \
  -H "Authorization: Bearer lp_live_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-10241" \
  -d '{
    "click_id": "1.eyJ1aWQiOiJ...",
    "goal": "purchase",
    "order_id": "10241",
    "amount_cents": 4999,
    "currency": "usd"
  }'

키에는 conversions:write 스코프가 필요하며, 이것은 브라우저 경로에는 없는 비용을 뜻합니다. 발급하고 보관하고 교체해야 하는 자격 증명입니다. 스코프가 붙은 키를 어떻게 관리하는지는 API 인증에서 다루며, 이 키는 반드시 서버에 두십시오. 매출 데이터에 쓰기 권한을 가진 키는 페이지에 있을 물건이 아닙니다.

대신 얻는 것은 광고 차단기도, 스크립트 차단기도, 추적 방지 설정도, JavaScript 오류도 막을 수 없는 보고입니다. 여러분 자신의 시스템이 주문이 존재한다고 인정하는 순간 여러분 자신의 인프라에서 발사되므로, 버튼이 눌린 낙관적인 순간이 아니라 사기 검사를 마친 뒤의 사실을 반영합니다.

브라우저 이벤트

워커가 여러분 자신의 리디렉션 도메인에서 작은 스크립트를 제공하고, 감사 페이지가 그것을 호출합니다.

<script src="https://go.example.com/cv.js" defer></script>
<script>
  window.lpConversion({ goal: 'purchase', orderId: '10241', amountCents: 4999, currency: 'usd' });
</script>

스크립트는 URL이나 퍼스트파티 쿠키에서 식별자를 읽으므로 손으로 넘겨줄 것이 없습니다. 사슬 어디에도 서드파티 호스트가 없다는 점은 두 가지 의미가 있습니다. 개인정보 보호의 성질이자 화이트라벨의 성질입니다. 고객의 페이지가 그 아래에 있는 플랫폼의 이름을 드러내는 것을 아무것도 불러오지 않기 때문입니다.

대가는 클라이언트 쪽 측정이 늘 치르는 그 대가입니다. 차단기, 개인정보 보호 모드, 실패한 스크립트 로드, 그리고 0.5초 일찍 탭을 닫는 방문자가 모두 이벤트를 지우며, 그 손실은 고르지 않습니다. 기술 분야와 개인정보에 민감한 대상은 일반 소비자 대상보다 훨씬 많이 걷어 내므로, 브라우저만 쓰는 구성은 단순히 적게 세는 것이 아니라 세그먼트마다 다른 정도로 적게 셉니다.

둘 사이에서 고르기

서버가 주문을 알고 있는 곳이라면 어디서든 서버 경로를 쓰십시오. 돈이 오가는 곳은 거의 전부 여기에 해당합니다. 브라우저 경로는 브라우저 안에만 존재하는 결과나 서버 코드를 넣을 수 없는 곳에 쓰십시오. 태그 관리자로만 고칠 수 있는 페이지, 호스팅형 플랫폼에서의 가입, 여러분 소유가 아닌 고객의 랜딩 페이지가 그렇습니다.

하나의 결과에 두 경로를 함께 돌리는 것은 중복 제거 덕분에 안전하지만, 두 경로가 같은 order_id를 보낼 때만 그렇습니다. 그러지 않으면 측정 범위를 넓히는 것이 아니라 매출을 두 번 세는 것입니다.

목표 자체는 가볍습니다. 목표는 purchase, signup, trial처럼 이름이 붙은 결과이고, 금액 없이 도착한 전환을 위해 기본 금액과 통화를 지닐 수 있으며, 존재하기 전에 참조된 목표는 처음 쓰일 때 만들어집니다.

돈은 정수입니다

금액은 최소 단위의 정수입니다. 4999는 소수점 두 자리 통화에서 49.99를 뜻하고, 49.99라는 금액은 조용히 반올림되는 대신 문제가 된 필드를 짚어 거부됩니다.

이 규칙은 하루쯤 사람을 성가시게 하고 그 뒤로 몇 년을 구해 줍니다. 이진 부동소수점은 대부분의 십진 소수를 정확히 표현하지 못합니다. 두 금액을 더했더니 뜻밖의 끝자리가 붙은 세 번째 값이 나오더라는 그 유명한 시연은 신기한 구경거리가 아니라, 규모가 커진 매출 열의 모든 합계에서 실제로 벌어지는 일입니다. 소수점이 없는 통화도 100으로 나누면 언제나 맞는다는 가정을 깨뜨립니다.

경계에서 소수를 거부하면, 사람이 읽는 가격을 최소 단위로 바꾸는 정직한 환산 하나가 정확히 한 곳으로 모입니다. 여러분의 코드 안, 시험해 볼 수 있는 그 한 자리입니다.

중복은 데이터베이스가 맡습니다

중복 제거는 읽은 뒤 기록하는 방식이 아니라 하나의 원자적 삽입으로 일어납니다. 같은 order_id가 여러 번 전송되면 전환은 하나만 만들어지고 중복으로 표시되어 돌아옵니다.

이 구분은 학술적으로 들리지만 그렇지 않습니다. 확인한 뒤 삽입하는 방식에는 두 작업 사이에 틈이 있고, 성급한 발신자가 재시도한 웹훅은 두 호출을 바로 그 틈 안에 떨어뜨립니다. 둘 다 기존 기록을 보지 못하고 둘 다 하나씩 씁니다. 매출 보고서에 나중에 아무도 찾아내지 못하는 유령 10%가 자라나는 방식이 바로 이것입니다. 개별 기록만 보면 하나하나가 완벽하게 정당해 보이기 때문입니다.

실무적인 규칙은 여러분 시스템에서 안정적이고 유일한 주문 식별자를 고른 뒤, 그것을 만들어 내는 방식을 절대 바꾸지 않는 것입니다. 보통은 여러분 자신의 주문 번호가 맞습니다. 타임스탬프처럼 재시도할 때마다 다시 만들어지는 값은 정확히 틀린 선택입니다. 위 요청에서처럼 Idempotency-Key 헤더를 함께 보내면, 실패한 호출은 조사할 대상이 아니라 그냥 다시 보내면 되는 일이 됩니다.

의심스러운 트래픽은 감추지 않고 표시합니다. 분류기의 판단이 토큰 안에 함께 실려 다니므로, 데이터센터나 프록시에 귀속된 전환은 기록되는 순간 의심 대상으로 표시되고 보고서에서 자기 세그먼트로 나타납니다. 전환 200건과, 그중 40건이 한 시간 동안 어느 호스팅 대역에서 나온 전환 200건은 서로 다른 사실이며, 돈을 낼 가치가 있는 쪽은 하나뿐입니다. 전환 데이터와 트래픽 필터링이 별개의 기능이기를 그만두는 지점이 바로 여기입니다.

전환이 다른 곳에서 일어날 때

실무에서 어려운 부분은 대개 API가 아닙니다. 측정할 가치가 있는 순간이 호스팅형 스토어나 CRM, 결제 사업자 안에서 일어난다는 점이며, 여러분이 할 일은 클릭에서 나온 문자열 하나를 그 시스템에 넣었다가 다시 꺼내 오는 것입니다.

호스팅형 스토어. 플랫폼이 맞춤 주문 속성이나 메타데이터를 허용한다면 그것이 깔끔한 길입니다. 방문자가 도착할 때 식별자를 읽고, 숨은 필드로 결제 과정을 통과시키고, 주문에 저장해 두었다가, 버튼이 눌린 시점이 아니라 주문이 확정된 시점에 여러분 서버에서 전환을 전송하십시오. 맞춤 필드는 허용하지 않지만 확인 페이지에 스크립트를 넣을 수 있는 플랫폼이라면 대신 브라우저 경로를 쓰십시오. 이 선택지들은 이커머스 솔루션 페이지에서 더 자세히 다룹니다.

CRM과 영업이 개입하는 거래. 리드 폼의 숨은 필드로 식별자를 받아 레코드에 저장해 두었다가, 거래가 성사로 표시되면 전환을 전송하십시오. 여기서 함정은 시간입니다. 7주 만에 성사되는 거래에는 7주를 감당하는 귀속 기간이 필요하고, 식별자를 아는 곳이 CRM뿐이라면 그 CRM의 보관 기간과 내보내기 방식이 여러분의 귀속 아키텍처의 일부가 됩니다. 리드를 받는 시점에 signup 목표를, 성사 시점에 purchase 목표를 보내는 방법도 고려해 보십시오. 그러면 퍼널의 바닥이 한 분기가 걸리더라도 꼭대기는 측정됩니다.

청구와 구독. 결제 사업자의 웹훅을 방아쇠로 삼으십시오. 청구서가 결제되면 여러분 서버가 그 고객에게 저장해 둔 식별자를 찾아, 청구서 식별자를 주문 식별자로 삼아 전환을 전송합니다. 그러면 반복 결제는 자연스럽게 별개의 전환으로 도착하고, 첫 결제와 갱신은 목표로 계속 구분됩니다.

세 가지 모양 모두에서 패턴은 같습니다. 외부 시스템은 링크에 대해 아무것도 알 필요가 없습니다. 뜻을 알 수 없는 문자열 하나를 들고 있다가 여러분에게 돌려주면 그만입니다.

그 숫자가 그다음에 가는 곳은 일부러 평범하게 만들어 두었습니다. 서명된 conversion.created 이벤트가 평소의 웹훅 체계를 통해 나가고, 설정해 둔 광고 연동은 문서로 공개된 재시도 간격과 무한 재시도 대신 남기는 포기 표시를 갖춘 전송 큐를 거쳐 전환을 받습니다. 요금제는 UTC 기준으로 세는 달력 월마다 받아들이는 전환 수에 상한을 둘 수도 있는데, 그 상한을 넘으면 요금제 제한이 아니라 quota_exceeded로 답하므로 “요금제에 없음”과 “이번 달치를 다 씀”을 지원 티켓 없이 구분할 수 있습니다.

처음부터 제대로 하기

  1. 캠페인이 끝난 뒤가 아니라 시작하기 전에 전환을 켜십시오. 식별자는 리디렉션 시점에 발급되며 소급해서 만들 수 없습니다.
  2. 링크를 여러분 자신의 도메인에서 운영해 퍼스트파티 쿠키가 여러분의 것이 되게 하십시오.
  3. 귀속 기간은 직접 측정한 구매 주기에 맞춰 정하고, attribution_expired 비율이 움직이면 다시 살펴보십시오.
  4. 서버가 주문을 알고 있는 곳이라면 어디서든 서버 경로를 우선하십시오.
  5. 가격을 최소 단위 정수로 환산하는 일은 코드 안의 정확히 한 곳에서만 하십시오.
  6. 주문 식별자로는 실제 주문 번호를 쓰고, 모든 경로에서 똑같이 보내십시오.
  7. 거부 코드는 따로 기록하고, 기간마다 한 번은 청구 시스템과 대조해 차이를 평균으로 뭉개지 말고 조사하십시오.

전체 필드 레퍼런스는 전환 문서에 있고, 매출 열이 이미 여러분이 읽고 있던 보고서들에서 어떻게 동작하는지는 전환 추적 기능 페이지에서 다룹니다. 이것이 회계를 대신하지는 않습니다. 대신 회계가 답할 수 없는 더 좁은 질문에 답합니다. 어느 링크, 어느 국가, 어느 목적지, 어느 트래픽 소스가 돈을 만들었는가입니다.

많이 묻는 질문

클릭 식별자란 정확히 무엇이고 어디에 담깁니까?

리디렉션이 일어나는 순간 리디렉터가 발급하는 서명된 토큰입니다. 여러분이 정한 파라미터 이름으로 목적지 주소에 붙으며 기본값은 lp_cid이고, 같은 값이 여러분 자신의 리디렉션 도메인에 90일짜리 퍼스트파티 쿠키로도 기록됩니다. 사본이 둘인 이유는 어느 쪽이든 사라질 수 있기 때문입니다. 쿼리 파라미터를 지우는 목적지에서도 쿠키는 남아 있고, 며칠 뒤에 파라미터 없이 돌아온 방문자도 쿠키는 여전히 지니고 있습니다. 토큰은 서명되어 있고 발급된 워크스페이스와 파트너에 묶여 있으므로, 한 고객의 링크에서 나온 토큰은 다른 고객의 워크스페이스에서 위조와 똑같이 거부됩니다.

서드파티 쿠키 없이도 전환 추적이 동작합니까?

동작합니다. 이 사슬 어디에도 서드파티가 없기 때문입니다. 식별자는 목적지 URL에 실려 다니고, 백업 쿠키는 플랫폼 호스트가 아니라 여러분 자신의 리디렉션 도메인이 설정합니다. 감사 페이지에서 전환을 보고하는 브라우저 스크립트 역시 같은 리디렉션 도메인에서 제공되므로, 그 페이지는 다른 회사에 속한 것을 아무것도 불러오지 않습니다. 그동안 브라우저들이 제거해 온 장치는 방문자가 한 번도 이동한 적 없는 호스트가 설정하는 쿠키인데, 여기서는 그 장치를 쓰지 않습니다.

금액을 소수가 아니라 센트 단위 정수로 보내는 이유는 무엇입니까?

결제 경로 한가운데에서 즉흥적으로 만들어진 반올림 규칙이야말로 매출 보고서가 청구서와 조용히 어긋나기 시작하는 원인이기 때문입니다. 금액은 센트, 펜스, 코페이카처럼 최소 단위의 정수입니다. 49.99라는 금액은 그럴듯한 값으로 조용히 반올림되는 대신 문제가 된 필드를 짚어 거부됩니다. 부동소수점 연산은 대부분의 십진 소수를 정확히 표현하지 못하므로 수천 건을 더하면 값이 조금씩 밀리는데, 그 어긋남은 재무 쪽에서 대시보드와 장부가 몇백 단위 차이가 난다고 물어 오기 전까지 눈에 보이지 않습니다.

같은 주문을 시스템이 두 번 보고하면 어떻게 됩니까?

전환은 하나만 기록되고 두 번째 호출은 그 전환을 중복으로 표시해 돌려줍니다. 중복 제거는 읽은 뒤 기록하는 방식이 아니라 하나의 원자적 삽입이므로, 재시도된 웹훅에서 두 전송이 같은 순간에 도착해도 그대로 유지됩니다. 재시도가 안전한 이유가 바로 이것입니다. 직전 호출이 성공했는지 알 수 없는 연동이라면 같은 주문 식별자로 그냥 다시 보내면 됩니다.

귀속 기간은 어떻게 정해야 합니까?

광고 플랫폼의 숫자를 베끼는 대신, 여러분의 구매 주기가 실제로 얼마나 걸리는지 재어서 정해야 합니다. 실제 주문에서 첫 접촉과 구매 사이의 간격을 보십시오. 충동 구매는 몇 분 만에 끝나고, 숙고를 거치는 구매는 일주일이 걸리며, 기업 거래는 한 분기가 걸립니다. 실제 주기보다 짧은 기간은 여러분이 벌어들인 매출을 버리고, 지나치게 긴 기간은 아무 관련도 없는 구매까지 링크의 공으로 돌립니다. 기간을 넘겨 도착한 전환은 attribution_expired로 거부되며 이것은 invalid_click_id와 구분되는 코드이므로, 연동 쪽에서 “너무 늦음”과 “잘못된 식별자”를 짐작하지 않고 가려낼 수 있습니다.

내가 통제하지 못하는 스토어나 CRM에서 일어난 전환도 귀속시킬 수 있습니까?

대개 가능하며, 주문이나 레코드에 문자열 하나를 더 저장할 수만 있으면 됩니다. 방문자가 도착할 때 URL이나 퍼스트파티 쿠키에서 식별자를 받아 숨은 폼 필드나 맞춤 주문 속성에 넣어 두었다가, 주문이 확정되면 여러분 서버에서 되돌려 보내십시오. 맞춤 필드는 전혀 허용하지 않지만 확인 페이지에 스크립트는 넣을 수 있는 플랫폼이라면 브라우저 경로가 대신 동작합니다. 깔끔한 답이 없는 유일한 경우는 맞춤 데이터도 스크립트도 받지 않는 시스템이며, 이때 정직한 선택지는 결제 화면을 새로 만들거나 링크마다 별도의 랜딩 페이지를 두는 것입니다.