전환 API 이벤트 중복 제거하는 법, event_id로 잡기

핵심 요약
  • 픽셀과 서버 API가 같은 전환을 두 번 보내 전환수가 부풀 수 있습니다.
  • 핵심은 event_id를 클라이언트와 서버 이벤트에 동일하게 부여하는 것입니다.
  • event_name·event_time까지 일치해야 중복 제거가 정상 적용됩니다.
  • Meta·Google·TikTok은 매칭 키 필드명이 서로 달라 플랫폼별로 확인해야 합니다.

전환 API 이벤트 중복 제거란 무엇인가

거래 영수증 두 장이 겹쳐있고 하나는 취소선이 그려진 모습.

전환 API(Conversion API, 이하 CAPI)는 브라우저의 자바스크립트 픽셀을 거치지 않고 서버에서 광고 플랫폼으로 전환 데이터를 직접 전송하는 API입니다. 문제는 대부분의 광고주가 브라우저 픽셀과 서버 API를 동시에 쓰기 때문에 같은 구매 1건이 두 경로로 각각 전송돼 전환수가 실제보다 부풀려 집계될 수 있다는 점입니다. 이를 막는 절차가 이벤트 중복 제거(event deduplication)이며, 핵심은 클라이언트(픽셀) 이벤트와 서버(API) 이벤트에 동일한 event_id(고유 이벤트 식별자)를 부여해 광고 플랫폼이 “같은 이벤트”임을 인식하게 만드는 것입니다.

즉 event_id·event_name(이벤트명)·event_time(발생 시각)이 서로 매칭되면 플랫폼이 둘 중 하나만 남기고 나머지는 자동으로 걸러냅니다. 이 매칭 로직을 정확히 설정하지 않으면 전환수가 실제보다 크게 부풀려 잡히면서 광고 성과 판단과 예산 배분이 왜곡됩니다.

왜 같은 전환이 두 번 집계될까

중복 집계는 대부분 “픽셀과 서버 API를 각각 붙였을 뿐 서로 연결하지 않았을 때” 발생합니다. 원인을 경로별로 나눠 보면 다음과 같습니다.

브라우저 픽셀 전송 경로의 한계

브라우저 픽셀은 사용자의 자바스크립트 실행 환경에 의존하기 때문에 다음과 같은 상황에서 데이터가 누락되거나, 반대로 이를 보완하려 서버 전송을 추가하면서 문제가 생깁니다.

  • ITP(Intelligent Tracking Prevention, 애플 사파리의 쿠키 추적 제한 기능)로 fbp/fbc 쿠키(Meta 픽셀이 발급하는 브라우저·클릭 식별자) 수명이 짧아짐
  • 애드블록·프라이버시 확장 프로그램이 픽셀 스크립트 자체를 차단
  • 페이지 이탈이 빨라 픽셀 이벤트가 전송되기 전에 사용자가 페이지를 떠남

서버 사이드 API 전송 경로의 특성

이런 누락을 보완하기 위해 서버에서 결제 완료 시점에 CAPI로 같은 이벤트를 다시 보내는 구조를 추가하는데, 이때 서버 이벤트에 픽셀 이벤트와 연결되는 식별자를 주지 않으면 플랫폼은 두 이벤트를 “서로 다른 두 번의 구매”로 인식합니다. 서버사이드 GTM(Google 태그매니저를 서버 컨테이너로 운영하는 방식)을 쓰는 경우도 마찬가지로, 클라이언트 컨테이너와 서버 컨테이너 사이에 event_id를 전달하는 로직이 빠지면 동일한 문제가 반복됩니다. 서버사이드 GTM 구성 자체를 아직 정하지 못했다면 sGTM 클라우드 호스팅 비교 완벽 가이드를 먼저 참고해 호스팅 방식을 정한 뒤 중복 제거 설정을 얹는 순서를 권장합니다.

중복 제거 핵심 원리: event_id 매칭

두 문서의 일치하는 고유 ID 코드를 돋보기로 강조한 모습

중복 제거는 결국 “두 이벤트가 같은 event_id와 event_name을 갖고 있는가”를 광고 플랫폼이 비교하는 절차입니다. 아래 조건 중 하나라도 어긋나면 매칭이 실패해 두 이벤트가 별개로 집계됩니다.

event_id와 event_name이 완전히 동일해야 중복 제거가 적용됩니다. 대소문자, 공백, 접두사 하나만 달라도 서로 다른 이벤트로 처리되어 중복 집계가 그대로 발생합니다.

매칭에 필요한 필드

플랫폼마다 필드명은 다르지만 요구하는 정보의 성격은 비슷합니다. 아래 표로 정리했습니다.

플랫폼 중복 제거 키 필드 매칭 조건
Meta(Facebook·Instagram) event_id / eventID event_id + event_name 동일
Google Ads(향상된 전환) transaction_id(거래 ID) 같은 transaction_id 값이어야 중복 제거(gclid는 매칭 조건이 아니라 오프라인 전환을 광고 클릭에 연결하는 별도 식별자)
TikTok event_id event_id + event 이름 동일

매칭이 실패하는 대표 상황

event_id를 만들어 넣었는데도 중복 제거가 안 된다면 대부분 다음 중 하나입니다. 주문번호만 event_id로 쓰다가 재시도 로직 때문에 같은 주문에서 서로 다른 이벤트명(예: AddToCart와 Purchase)이 같은 event_id를 공유하는 경우, event_time(이벤트 발생 시각)이 실제 발생 시점과 크게 차이 나게 기록되는 경우, 그리고 서버 전송이 픽셀 전송보다 지나치게 지연되는 경우입니다.

서버 이벤트 전송이 몇 시간 이상 지연되면 매칭 창(matching window)을 벗어나 중복 제거 대상에서 제외될 수 있습니다. 결제 완료 시점에 최대한 즉시 서버 이벤트를 전송하는 것이 안전합니다.

단계별 설정 방법

실제 구현은 아래 순서를 그대로 따르면 됩니다. 순서를 바꾸면(특히 ID 규칙을 나중에 정하면) 이미 나간 이벤트를 소급 수정할 수 없으므로 1단계부터 확정하고 진행하세요.

1단계. 이벤트 ID 생성 규칙 통일하기

가장 먼저 프런트엔드와 백엔드가 같은 규칙으로 event_id를 만들 수 있도록 정합니다. 실무에서는 “이벤트명_주문번호_타임스탬프” 조합처럼, 프런트엔드가 만들어서 백엔드로 넘기거나(주문 생성 시 발급), 반대로 백엔드가 주문번호 기준으로 만들어 프런트엔드에 내려주는 방식 중 하나를 팀 컨벤션으로 고정합니다.

2단계. 클라이언트(픽셀) 이벤트에 이벤트 ID 부여하기

결제 완료 페이지에서 픽셀 이벤트를 호출할 때 옵션 파라미터로 event_id를 함께 전달합니다.

// 클라이언트(브라우저) 픽셀 이벤트 - 서버와 공유할 고유 event_id 생성
const eventId = `purchase_${orderId}_${Date.now()}`;

fbq('track', 'Purchase', {
  value: 49000,
  currency: 'KRW'
}, { eventID: eventId }); // 세 번째 인자 옵션 객체의 eventID로 전달

// 이후 서버로 결제 완료를 알릴 때 같은 eventId를 함께 넘긴다
sendOrderToServer({ orderId, eventId });

3단계. 서버(CAPI) 이벤트 페이로드에 동일 ID 전달하기

서버에서 결제 완료를 확정한 뒤 CAPI로 전송하는 페이로드에도 클라이언트에서 받은 event_id를 그대로 넣습니다. event_name과 event_time도 클라이언트 쪽과 어긋나지 않게 맞춥니다.

{
  "data": [
    {
      "event_name": "Purchase",
      "event_time": 1755000000,
      "event_id": "purchase_ORDER1234_1755000000000",
      "action_source": "website",
      "user_data": {
        "em": "해시 처리된 이메일 값",
        "client_ip_address": "203.0.113.10",
        "client_user_agent": "Mozilla/5.0 ..."
      },
      "custom_data": {
        "currency": "KRW",
        "value": 49000
      }
    }
  ]
}

4단계. 테스트 도구로 매칭 여부 확인하기

각 플랫폼이 제공하는 이벤트 진단 도구(예: Meta 이벤트 관리자의 테스트 이벤트 화면, Google 태그 관리자의 미리보기 모드)로 실제 주문을 하나 발생시켜 event_id가 일치하는지, “중복 제거됨” 표시가 뜨는지 직접 확인합니다. 운영 반영 전 스테이징 환경에서 최소 1~2건은 반드시 눈으로 확인하는 것이 안전합니다.

  1. 테스트 주문 1건 생성
  2. 브라우저 개발자 도구 또는 플랫폼 이벤트 관리자에서 픽셀 이벤트의 event_id 확인
  3. 같은 시점에 서버 로그 또는 CAPI 응답에서 전송된 event_id 확인
  4. 두 값이 동일한지, 플랫폼이 “중복 제거됨” 또는 이에 준하는 상태로 표시하는지 확인

흔한 실수와 체크리스트

체크리스트와 경고 아이콘으로 검증 절차를 나타내는 시각 구성

중복 제거 설정을 붙였는데도 여전히 전환수가 이상하게 튄다면 아래 항목을 먼저 점검하세요. 어트리뷰션(광고 성과를 특정 채널·클릭에 배분하는 과정) 데이터 전반이 왜곡되는 문제이므로, 중복 제거를 정확히 잡는 작업은 광고 어트리뷰션 정확도 높이는 4단계 방법에서 다루는 어트리뷰션 정합성 확보의 전제 조건이기도 합니다.

구현 단계에서 자주 하는 실수

  • event_id를 서버에서만, 또는 클라이언트에서만 임의로 생성해 두 값이 애초에 다름
  • 같은 event_id를 여러 이벤트명(AddToCart, InitiateCheckout, Purchase)에 재사용
  • 새로고침·뒤로가기로 픽셀 이벤트가 한 주문에 2회 발생했는데 매번 새 event_id를 발급
  • 테스트 환경 event_id 규칙을 운영 배포 시 그대로 남겨 실제 주문과 충돌

운영 중 점검할 체크리스트

  • 주간 단위로 픽셀 단독 전환수 대비 CAPI 포함 전환수 증가율이 비정상적으로 크지 않은지 확인
  • 결제 시스템 재시도(타임아웃 후 재전송) 로직이 event_id를 매번 새로 만들지 않는지 확인
  • 서버 이벤트 전송 지연 시간이 짧게(초~분 단위) 유지되는지 로그로 모니터링

자주 묻는 질문

Q. event_id는 반드시 주문번호와 같아야 하나요?

아닙니다. event_id는 주문번호 자체가 아니라 “이 이벤트 1건”을 구분하는 별도 식별자입니다. 주문번호만 그대로 쓰면 같은 주문에서 여러 이벤트(장바구니 담기, 결제 시작, 구매 완료)가 발생할 때 서로 겹쳐버리므로, 이벤트명과 주문번호를 조합해 이벤트별로 고유하게 만드는 것이 안전합니다.

Q. 픽셀만 쓰고 서버 API(CAPI)는 안 붙이면 중복 제거를 신경 쓰지 않아도 되나요?

네, 전환 경로가 픽셀 하나뿐이면 중복 제거 설정 자체가 필요 없습니다. 다만 최근에는 브라우저 차단·쿠키 제한으로 픽셀만으로는 전환이 상당수 누락되기 때문에, 서버 API를 함께 붙이는 구조가 일반적으로 권장되며 이 경우 중복 제거 설정이 필수가 됩니다.

Q. 서버사이드 GTM을 쓰면 중복 제거를 따로 신경 쓸 필요가 없나요?

서버사이드 GTM을 쓰더라도 클라이언트 컨테이너에서 넘어온 event_id를 서버 컨테이너 태그가 그대로 전달하도록 설정을 해줘야 합니다. 컨테이너를 서버로 옮긴다고 event_id 매칭 로직이 자동으로 생기는 것은 아니므로, 태그 설정 단계에서 event_id 필드 매핑을 직접 확인해야 합니다.

Q. 이미 중복 집계된 과거 데이터는 소급해서 고칠 수 있나요?

플랫폼에 이미 전송·집계된 과거 이벤트를 사후에 병합해 재계산하는 기능은 일반적으로 제공되지 않습니다. 과거 리포트의 전환수 왜곡은 참고용으로만 남기고, 설정을 고친 시점 이후 데이터부터 정상 집계된 것으로 보고 성과를 재해석하는 것이 현실적인 대응입니다.

Q. 여러 광고 플랫폼(Meta, Google, TikTok)에 동시에 전송할 때 event_id를 공유해도 되나요?

플랫폼 간에는 event_id를 공유해도 서로 영향을 주지 않습니다. 중복 제거는 같은 플랫폼 안에서 클라이언트 이벤트와 서버 이벤트를 매칭하는 절차이므로, Meta·Google·TikTok에 동일한 event_id 문자열을 보내더라도 각 플랫폼은 자기 안에서만 매칭을 수행합니다. 다만 관리 편의를 위해 플랫폼별로 접두사를 붙여 구분하는 팀도 많습니다.

참고자료

관련 글 보기