광고가 '매출'을 학습하게 만드는 법
오프라인 전환 추적 실전기
광고가 매출을 학습하게 만들려면, 전환을 끝까지 추적해야 합니다. 그런데 우리 매출은 며칠 뒤 오프라인에서 확정됩니다. 픽셀 하나로는 안 되는 오프라인 전환 추적을, 헤매고 과하게 가다 멈추고 다시 푼 실전 기록입니다.
답을 못 한 질문
매달 광고비가 빠져나갔다. 네이버에, 구글에, 메타에. 통장에서 숫자가 줄어드는 건 매번 또렷했다.
흐릿한 건 그 반대편이었다. 그 돈이 무엇이 되어 돌아오는지가 보이지 않았다.
어느 날, 질문을 받았다.
"그래서, 어느 광고가 돈을 벌어줬어?"
간단한 질문이었다. 나는 답을 못 했다.
폼이 몇 건 들어왔는지는 화면에 떠 있었다. 하지만 폼은 매출이 아니다. 우리 매출은 '개통'에서 나온다. 통신·렌탈을 비교해 가입을 붙이는 사업이라 그렇다. 신청이 들어오고, 상담을 하고, 며칠 뒤 실제로 개통이 되어야 그제야 수수료가 들어온다.
개통은 화면 밖에서 일어난다. 그것도 며칠 뒤에. 광고를 클릭한 순간과, 그게 돈이 되는 순간 사이가 그렇게 끊겨 있었다. 나는 그 끊긴 구간을 한 번도 제대로 들여다본 적이 없었다.
이 글은 그 구간을 잇는 이야기다. 깔끔한 정답이 아니라, 헤매고 과하게 가다 멈추고 다시 푼 기록이다.
왜 답을 못 했나: 전환이 둘로 쪼개진다
이커머스라면 이런 고민이 없다. 클릭하고, 장바구니에 담고, 결제한다. 전환도 금액도 그 순간 브라우저 안에서 다 잡힌다. 그래서 픽셀 하나면 끝난다. 픽셀은 광고 매체에 "이 사람이 전환했다"를 알려주는 추적 코드다. 결제가 일어나면 픽셀이 메타에, 구글에 곧장 신호를 보낸다. 매체는 그 신호로 "이런 사람을 더 데려와야겠다"를 학습한다.
나는 오래 이게 표준인 줄 알았다. 아니었다. 이커머스가 운 좋게 쉬운 예외였다.
우리는 전환이 두 동강이다. 폼 제출은 지금, 브라우저 안에서 일어난다. 개통은 며칠 뒤, 서버 안에서 확정된다. 그 사이가 비어 있다. 이 빈 구간을 나는 '갭'이라고 부른다. 앞으로 나올 모든 고생이 이 한 글자에서 나왔다.
여기서부터가 진짜다. 광고가 매출을 학습하게 만들려면, 갭 건너편의 개통을 다시 광고 쪽으로 돌려보내야 한다. 그러려면 먼저, 갭 양쪽이 같은 사람인지를 이어야 한다. 말은 쉽다. 실제로는 그게 가장 어려웠다.
첫 다리: 개통을 웹에 잇기
직접 만들기 전에, 사 오는 길부터 따져봤다. 이런 거 파는 도구가 왜 없겠나. GA4에는 오프라인 전환 가져오기가 있고, 전화를 추적해 주는 콜트래킹 SaaS도 많다. 그런데 둘 다 우리 갭의 절반만 메운다. GA4 오프라인 가져오기는 개통을 GA4에 넣어줄 뿐, 전화·렌탈·키워드를 한 사람으로 묶어주진 않는다. 콜트래킹 SaaS는 전화는 보지만, 며칠 뒤 서버에서 확정되는 개통과는 못 잇고 매달 비용이 나간다. 결국 '한 사람으로 묶는 일'은 누구도 대신 해주지 않았다. 그래서 이미 굴러가던 BigQuery 위에 직접 이었다. 1인이, 몇 주에 걸쳐.
가장 먼저 풀 문제는 분명했다. 웹에서 폼을 낸 사람과, 며칠 뒤 개통한 사람을 잇는 것. 둘이 같은 사람이라는 걸 무엇으로 증명하나.
제일 확실한 건 전화번호다. 같은 번호면 같은 사람이다. 그런데 바로 벽에 부딪혔다. 전화번호는 개인정보다. GA4에도, 광고 픽셀에도 넣을 수 없다. 법으로도 막혀 있고, 플랫폼 정책으로도 막혀 있다. 가장 확실한 키를, 정작 가장 필요한 곳에 못 쓴다.
그래서 다리를 두 개 놨다.
첫째는 order_id다. 폼을 제출하면 서버가 리드 번호를 하나 돌려준다. 이 번호를 웹 전환 이벤트에 박는다. 개통 기록에도 같은 번호가 들어 있다. 나중에 둘을 이 번호 하나로 잇는다. 번호일 뿐 개인정보가 아니니, 광고에도 분석에도 마음껏 넣을 수 있다.
둘째는 해시 전화번호다. 전화번호를 SHA-256으로 단방향 변환한다. 원문은 그대로 복원되지 않는다. 다만 이건 '개인정보가 아니게 되는' 게 아니라, 원문을 노출하지 않고 매칭에만 쓰는 가명처리다(엄밀히는 가명정보이므로 안전조치와 동의 범위는 따로 지킨다). 같은 사람이면 같은 해시가 나오니, 이걸로 웹에서 온 사람, 전화로 온 사람, 렌탈로 온 사람을 한 명으로 묶는다.
하나 더. 전화번호가 늘 있는 건 아니다. 폼도 안 내고 사이트만 둘러본 사람에겐 해시할 번호가 없다. 그래서 한 사람을 가리키는 키(person_id)는 '있으면 해시 전화번호, 없으면 device_id(브라우저 식별자)' 순으로 정한다. 나중에 전화번호가 나타나면, 그동안 device_id로 쌓인 흔적이 그 사람에게 합쳐진다. 이 우선순위가 어긋나면 한 사람이 둘로 쪼개지거나, 남남이 하나로 뭉친다. 사람을 세는 일은 생각보다, 누가 '같은 사람'인지 판정하는 규칙 싸움이다.
두 다리를 놓고 나니 원칙 하나가 분명해졌다. 전화번호 원문은 서버에만 둔다. 광고와 분석에는 번호(order_id)와 가명화된 해시 키만 흘려보낸다. 개인정보는 안에 가두고, 잇는 데 필요한 열쇠만 밖으로 내보내는 셈이다.
예를 들어, 김지훈님이 네이버 검색광고로 들어왔다. 키워드는 '인터넷 가입'. 상담폼을 냈다. 서버가 order_id 84213을 돌려줬고, 웹 전환에 db_id=84213이 박혔다. 사흘 뒤, KT가 개통됐다. 수수료 30만원. CRM 개통 기록에도 order_id 84213이 그대로 남아 있다. BigQuery에서 두 기록을 같은 번호로 이었다. 그 순간 비로소 한 문장이 만들어진다. "이 30만원은, 네이버 '인터넷 가입'이라는 키워드가 데려온 손님이 만든 매출이다." 광고가 학습할 수 있는 건, 바로 이 문장이다.
잇기 전에 손볼 게 하나 더 있었다. 같은 사람이 폼을 두 번 내면 전환도 두 번 잡힌다. 그래서 같은 order_id에서 온 같은 이벤트는 한 건으로 접는다(중복 제거). 사소해 보이지만, 이걸 빼먹으면 '개통보다 전환이 많은' 이상한 표가 나오고, 그 표를 믿고 내린 결정이 줄줄이 어긋난다. 정합성은 화려하지 않지만, 틀린 숫자 위에 쌓은 분석은 통째로 무너진다.
다리를 놓으니, 다음 문제가 보였다
웹 폼은 풀렸다. 그런데 고객을 들여다보니, 상당수가 폼을 안 썼다. 그냥 전화를 걸었다.
전화는 브라우저 밖이다. GTM도 GA4도 브라우저 안만 본다. 누가 어디서 보고 전화했는지, 화면엔 아무 흔적이 없다. 폼은 풀었는데 전화는 통째로 깜깜했다. 솔직히 한동안 막막했다.
해법은 의외로 단순했다. 채널마다 다른 전화번호를 쓴다. 네이버에서 들어온 사람은 네이버 번호를 보고, 구글에서 들어온 사람은 구글 번호를 본다. 그러면 걸려온 번호가 곧 채널이 된다. 콜센터 데이터를 BigQuery에 모으고, '번호 → 채널' 표와 잇는다. "어느 채널이 전화를 불렀나"가 그제야 보인다. 거창한 시스템도 필요 없었다. 표 하나면 됐다.
그런데 한 겹 더 들어가니 또 막혔다. 검색광고는 채널만으론 부족하다. '네이버'가 아니라 '어느 키워드'가 매출을 만들었는지를 알아야 예산을 옳게 쓴다. 그런데 전화엔 키워드가 없다. 키워드마다 번호를 따로 둘 수도 없다. 키워드가 수천 개인데 번호를 수천 개 살 수는 없으니까.
그래서 시간으로 이었다. 사람이 사이트에서 전화 버튼을 누른 시각이 있다. 콜센터에 전화가 걸려온 시각이 있다. 이 둘을 맞춘다. 같은 번호이고, 1~2분 안이면 같은 사람으로 본다. 우리 콜은 하루 300통 안팎, 그 80%가 모바일이다. 모바일은 버튼을 누르면 곧장 통화로 이어져 클릭과 통화 사이가 짧다. 게다가 번호가 스무 개뿐이고 콜이 9시간에 흩어져 있어, 같은 번호로 같은 1~2분 안에 두 통이 겹칠 일은 드물다.
예를 들어, 14시 32분 05초, 네이버 번호로 전화가 왔다. 직전 1~2분을 되짚는다. 같은 번호로 전화 버튼을 누른 기록이 딱 하나 있다. 14시 31분 50초, 키워드 '와이파이 설치'. 후보가 하나뿐이니 헷갈릴 게 없다. 이 전화에 그 키워드를 붙인다. 만약 이 사람이 사흘 뒤 개통하면? 첫 번째 다리(order_id·해시 전화)가 그걸 받아 잇는다. 그러면 "'와이파이 설치' 키워드 → 전화 → 개통 30만원"까지 한 줄로 닫힌다.
물론 시간 매칭이 늘 깔끔하진 않다. 같은 번호로 같은 1~2분 안에 두 사람이 누르면? 그땐 서버가 찍은 시각을 마이크로초까지 받아 가장 가까운 클릭에 붙인다. 그래도 애매하면 잇지 않고 비워 둔다. 틀리게 이은 한 건이, 비워 둔 열 건보다 분석을 더 망치기 때문이다. 그리고 이 매칭은 실시간일 이유가 없다. 개통이 어차피 며칠 뒤에 찍히니, 하루 한 번 몰아서 잇는 배치로 충분하다. 실시간 매칭 서버까지 세웠다면 그것도 과한 공사였을 것이다.
다리를 다 놓고 나니, 흩어져 보이던 한 사람의 흔적이 하나로 모였다. 며칠에 걸쳐 네이버로 왔다 메타로 돌아오고, 끝내 전화를 건 김지훈님. 웹에 남은 익명 기록과 걸려온 전화가 해시 전화번호 하나로 묶이자, 사흘 뒤 개통까지 한 줄로 이어졌다. 광고가 학습해야 할 '진짜 그림'이 이거였다.
여기서 한 가지가 더 보인다. 김지훈님은 네이버로 왔다 메타로 돌아와 전화를 걸었다. 그럼 이 개통은 누구 공인가? 픽셀만 쓰던 시절엔 이걸 고를 수조차 없었다. 마지막으로 클릭된 매체가 공을 통째로 가져갔다(라스트클릭). 이제 전체 경로가 한 줄로 보이니, 비로소 우리가 고를 수 있다. 첫 접점에 줄지, 마지막에 줄지, 나눠 줄지. 추적이 안 될 땐 매체가 멋대로 정하던 크레딧을, 추적이 되니 우리가 정한다. 픽셀 한 줄과 갭을 건넌 추적의 진짜 차이가 여기다.
하마터면, 과하게 갈 뻔했다
여기서 일을 키울 뻔했다.
전화를 훨씬 더 정밀하게 추적하는 방법이 있다. '풀 DNI'라고 부른다. 방문자 한 명 한 명에게, 그때그때 다른 번호를 동적으로 배정하는 방식이다. 번호 풀을 임대하고, 번호 재사용이 충돌하지 않게 상태 기계를 돌리고, 신뢰도를 매겨 거른다. 머릿속으로 설계까지 다 그렸다. 꽤 그럴듯해 보였다.
그러다 멈췄다.
오해는 마시길. 우리는 광고를 네이버·구글·메타 다 돌린다. 다만 추적을 한꺼번에 다 붙이려던 게 아니었다. 네이버부터 붙이고, 나머지는 추후로 미뤄둔 단계였다. 그 첫 단계에, 방문자마다 동적 번호를 뿌리는 묵직한 시스템을 지금 만든다고?
질문 하나가 그 손을 멈춰 세웠다. "지금 이게 정말 필요한가?"
필요 없었다. 시간창 매칭으로 충분했다. 비싼 번호 풀 없이, 데이터를 시각으로 잇는 것만으로 모바일 전화의 대부분이 잡혔다. 개통을 광고로 되먹여 입찰을 자동으로 최적화하는 것도 마찬가지였다. 멋있어 보였다. 하지만 지금 우리에게 필요한 건 '측정'이지 '자동화'가 아니었다. 그것도 접었다.
나중에야 깨달았다. 더 만드는 결정보다, 덜 만드는 결정이 더 어렵다. 만들 줄 아는 걸 안 만들기로 정하는 데에는, 만드는 것과는 다른 종류의 자제가 든다. 안 해도 되는 걸 알아채는 게 일의 절반이었다.
'추적 불가'였던 게, 사실은 우리 것이었다
렌탈에서는 헛다리를 한 번 짚었다. 부끄럽지만 적어둔다. 그 실수에서 가장 많이 배웠으니까.
렌탈 상담 폼은 외부 업체 사이트를 iframe으로 띄운다. iframe은 우리 페이지 안에 박힌, 다른 사이트다. 보안 규칙상 부모 페이지는 다른 출처의 iframe 안을 들여다볼 수 없다. 그래서 나는 문서에 한 줄 적었다. "렌탈은 추적 불가."
며칠 뒤, 그 폼을 다시 열어봤다. 그런데 자세히 보니, 그 페이지가 남의 것이 아니었다. 우리가 만든 cafe24 페이지였다. 우리가 고칠 수 있는 우리 자산이었다.
헛웃음이 났다. 막힌 줄 알고 포기 도장을 찍었던 벽이, 처음부터 내 벽이었다. 폼을 제출하는 순간 부모 페이지로 신호 한 번만 보내게 고치니, 그걸로 끝이었다.
그날 배운 건 기술이 아니었다. "안 된다"고 적기 전에 한 번 더 확인할 것. 막힌 줄 알았던 벽이, 알고 보면 내가 열쇠를 쥔 문일 때가 있다.
안 되는 건, 솔직히 못 한다고 적었다
다 풀지는 못했다. 그리고 못 푸는 걸 푼 척하지 않았다. 명확히 미뤘다.
하나는 웹에 흔적도 없이 전화만 건 사람이다. 버튼을 누른 적도 없으니, 시각으로 맞출 클릭이 없다. 이 사람은 키워드까지 못 잇는다. 채널까지만 본다. 방법이 아예 없는 건 아니다. 다만 들이는 비용이 얻는 값어치를 넘어선다. 그래서 지금은 접어둔다.
또 하나, 정직하게 털어놓을 게 있다. 앞에서 "모바일 전화의 대부분이 잡힌다"고 했다. 그 '대부분'은 실측이 아니다. 번호 하나에 하루 몇 통이 오는지로 계산한 기대치다. 실제로 돌려봐야 진짜 숫자가 나온다. 대충 "잘 될 거예요"라고 넘어갔으면, 나중에 누군가 "이 숫자 왜 안 맞아요"라고 물었을 때 할 말이 없었을 것이다. 모르는 걸 추정으로 메우는 것보다, 모른다고 적어두는 게 낫다.
그래서, 우리는 어디쯤인가
한참을 헤매고 나니, 어려움의 정체가 보였다. 결국 한 가지로 갈린다. "브라우저에서 닫히는 깔끔한 고리가, 어디서 깨지느냐."
가장 어려운 도메인은 어려움을 한 번에 여러 개 밟는다. B2B 엔터프라이즈를 보자. 거래는 오프라인에서 마감되고, 여정은 몇 달씩 끌고, 한 거래에 결정권자가 여럿이다. 세 가지 어려움을 동시에 짊어진다. 헬스케어도 그렇다. 개인정보 규제가 극단적인데, 전환마저 오프라인(병원·처방)에서 일어난다.
그에 비하면 우리는 오프라인 갭 하나, 익명 전화가 약간이다. 정공법으로 어렵긴 해도, 여러 어려움이 한꺼번에 겹친 자리는 아니다. 우리가 헤맨 만큼, 더 위에 있는 사람들은 더 헤맨다는 뜻이기도 하다.
다만 정직하게 덧붙인다. 내가 직접 해본 건 리드젠 하나다. B2B와 헬스케어는 살아본 게 아니라 들은 것이고 추론이다. 그 자리에 계신 분들껜 이 지도가 얕게 보일 수 있다.
당신 사업이라면
여기까지 읽었다면, 당신 사업에 대입할 질문은 하나로 충분하다.
전환이 브라우저에서 끝나는가? 아니면 며칠 뒤, 화면 밖에서 확정되는가?
앞이라면 축하한다. 픽셀 하나면 된다. 뒤라면, 픽셀만으론 안 된다. 갭을 건널 다리가 필요하다. 우리가 놓은 순서를 그대로 옮기면 이렇다. 비싼 도구부터 사지 말고, 위에서부터 하나씩 내려가면 된다.
- 웹 전환과 '결과(개통)'를 이을 비-개인정보 키 하나를 정한다 (우린 order_id)
- 채널과 사람을 묶을 해시 전화번호를 서버에 쌓는다
- 전화는 채널별 번호로 출처를 가른다 (걸려온 번호 = 채널)
- 키워드까지 필요하면 시각으로 콜과 클릭을 잇는다 (비싼 번호 풀 없이)
- 안 되는 건 추정으로 메우지 말고 '아직 못 함'으로 적는다
- 크게 만들기 전에 매번 묻는다: "지금 규모에, 이게 정말 필요한가?"
이제 진짜 '학습'을 시작한다
여기까지가 '배관 공사'다. 흩어진 접점을 한 사람으로 잇고, 개통까지 한 줄로 꿰었다. 그런데 솔직히 말하면, 광고가 아직 매출을 '학습'한 건 아니다. 학습할 재료를 겨우 갖췄을 뿐이다.
마지막 한 걸음이 남았다. 이렇게 이은 개통을, 측정 프로토콜(MP)과 전환 API(CAPI)로 다시 매체에 돌려보내는 일이다. 그러면 네이버·구글·메타가 '폼 채운 사람'이 아니라 '진짜 개통한 사람'을 기준으로 입찰을 최적화하기 시작한다. 그게 제목이 약속한 '학습'이다.
성공은 느낌이 아니라 숫자로 잰다. 키워드별 개통 ROAS. '인터넷 가입'이라는 키워드가 쓴 광고비 대비 실제 개통 매출이 얼마인가. 그 숫자가 나오면 돈 버는 키워드에 예산을 몰고, 안 되는 키워드는 끈다. 그 전후 비교가 이 모든 공사가 값했는지에 대한 진짜 답이다.
아직 그 숫자는 없다. 이제 막 재료를 다 이었으니까. 하지만 처음으로, 그 숫자를 '잴 수 있는' 자리에는 섰다.
마무리
어트리뷰션이 어렵게 느껴졌다면, 문제가 원래 어려운 거다. 어트리뷰션은 어느 광고가 성과를 냈는지 귀속시키는 일이다. 이커머스가 쉬웠던 건 실력 때문이 아니라, 고리가 운 좋게 브라우저 안에서 닫혔기 때문이다. 현실의 사업 대부분은 그 행운을 누리지 못한다.
나는 이제 그 질문에 답할 수 있다. 여전히 깔끔하진 않다. 익명 전화는 못 잇고, '대부분'이라는 숫자는 아직 실측으로 확인해야 한다. 그래도 "어느 광고가 돈을 벌었는가"의 큰 줄기는 보인다. 광고가 폼이 아니라 매출을 학습하기 시작했다. 거기까지 오는 길이, 그대로 이 글이다.
비교원 통신·렌탈 비교가입 서비스의 전환 추적 구축 기록. 결정과 근거와 한계를 전부 남겨, 다음엔 같은 길을 다시 헤매지 않는다.
이 글이 도움이 되었다면 공유해주세요
최신 인사이트
카카오톡 공유 썸네일 안 나올 때 해결법 (Kakao JavaScript SDK 2025)
카카오톡 공유하기에서 썸네일 이미지가 안 나오는 원인과 scrapImage로 KAGE URL을 변환해 해결하는 방법을 단계별로 설명합니다. 지금 확인하세요.
Claude Code 서브에이전트로 CRM 사용자 설명서 20분 만에 완성하는 방법
Claude Code 서브에이전트를 활용해 CRM 코드베이스에서 사용자 설명서와 비주얼 가이드북을 20분 만에 자동 생성한 실전 사례를 공유합니다. 지금 확인하세요.
GEO 생성형 엔진 최적화: 2025년 AI 마케팅 전략 완전 가이드
GEO 생성형 엔진 최적화란 무엇이며 기존 SEO와 어떻게 다른지, 2025년 AI 마케팅 전략의 핵심 실행 방법 5가지를 데이터와 함께 알아보세요.
관련 프로젝트
새 글을 이메일로 받아보세요
마케팅, 분석, 개발 인사이트를 정리해서 보내드려요.