Elido
11 мин чтенияВозможности

Серверное отслеживание конверсий через короткие ссылки

Архитектура для передачи конверсий в Meta CAPI, GA4 Measurement Protocol и TikTok Events на стороне сервера: передача click_id, дедупликация, хеширование и семантика повторных попыток

Ana Kowalska
Marketing solutions engineering
Server-side conversion forwarding diagram: short link captures click_id, order webhook triggers fan-out to Meta CAPI / GA4 MP / TikTok Events with SHA-256 hashed identifiers and dedup event_id

Браузерный пиксель - это та часть атрибуции, которая ломается первой. Apple's Intelligent Tracking Prevention ограничивает сторонние куки и ухудшает передачу реферера; блокировщики рекламы удаляют сетевой вызов пикселя еще до того, как он покинет страницу; App Tracking Transparency в iOS 14.5 настолько снизила качество сигнала Meta на трафике iPhone, что сама Meta теперь рассматривает браузерный пиксель лишь как вспомогательный инструмент.

Серверное отслеживание конверсий - это решение, с которым согласны все. Но именно в реализации многие допускают ошибки. В этом посте мы разберем архитектуру, в которой сервис сокращения ссылок владеет click_id: что делает сокращатель, что делает ваш бэкенд, что ожидают рекламные платформы на своей стороне и как выглядит схема дедупликации, которая не позволяет учитывать конверсии дважды при одновременной работе браузерных и серверных событий.

Три платформы, на которые чаще всего настраивают передачу: Meta CAPI, GA4 Measurement Protocol и TikTok Events API. Mixpanel, Klaviyo и Pinterest принимают данные в схожем формате, но с вендорскими названиями полей. Я подробно остановлюсь на Meta и GA4, так как они осваивают большую часть рекламных бюджетов; остальные работают по тому же шаблону.

Почему серверное отслеживание#

Вкратце: браузер больше не является надежным источником сигнала. Более подробную версию стоит изучить, так как она определяет подход к настройке дедупликации.

Три фактора ухудшают отслеживание конверсий на стороне браузера:

Партиционирование кук и ограничения на время их жизни. Safari ITP разделяет куки по сайтам верхнего уровня и ограничивает время жизни основных кук (first-party), установленных скриптами, 7 днями (или 24 часами после обнаружения известного кросс-сайтового трекера). Total Cookie Protection от Firefox делает аналогичное разделение. Brave и другие браузеры, ориентированные на конфиденциальность, идут еще дальше. Поток атрибуции через основные куки, который работал в 2018 году, в 2026 году уже неэффективен.

Блокировщики рекламы. uBlock Origin, AdBlock Plus, Pi-hole, NextDNS и блокировщики на уровне сети по умолчанию содержат правила для connect.facebook.net, googletagmanager.com, analytics.tiktok.com и других поверхностей маркетинговых тегов. Пиксель никогда не срабатывает; конверсия не регистрируется.

iOS App Tracking Transparency и изменения в отслеживании ссылок в iOS 17. ATT снизила качество сигнала Meta. iOS 17 Link Tracking Protection распространила это на параметры запроса в приватном просмотре и Почте, удаляя fbclid, gclid и другие идентификаторы из списка до открытия ссылки.

Кумулятивный эффект для типичного магазина на Shopify с преобладающим iOS-трафиком: браузерные пиксели пропускают 25-40% конверсий. Точное число зависит от структуры вашего трафика; бренды косметики и одежды с большой долей пользователей iOS находятся на верхней границе. Математика возвращенного дохода - это то, что оправдывает инженерную работу: для магазина с оборотом €10 млн в год и 30% пробелом в атрибуции пикселя, восстановление даже половины этого пробела означает €1.5 млн атрибутированного дохода, возвращенного на платформы, которые его принесли.

Серверная передача конверсий закрывает большую часть этого пробела. Она не закрывает его полностью - существуют конверсии, где click_id никогда не фиксировался (органический поиск, прямой заход, брендовый поиск), и никакой CAPI их не восстановит - но она устраняет пробел, возникший из-за блокировок на стороне браузера.

Архитектура#

Поток данных состоит из четырех этапов: реклама → короткая ссылка → сайт → серверная передача.

Рекламная платформа → короткая ссылка. Целевой URL в объявлении Meta или Google Ads - это короткая ссылка. Пользователь кликает; обработчик на стороне сервиса сокращения фиксирует событие клика и перенаправляет на целевой URL с добавленным click_id.

Короткая ссылка → сайт. К целевому URL добавляется ?elido_click=<id> (настраивается для каждого воркспейса). Тег-менеджер сайта или код темы считывает его и записывает в основную куку или, что более важно, в кастомный атрибут корзины или заказа.

Сайт → заказ. Когда пользователь завершает оформление заказа (отправка корзины Shopify, создание заказа WooCommerce, конвертация headless-корзины), click_id находится в атрибутах или метаданных записи заказа. Это точка надежной передачи данных - как только click_id попадает в заказ, он больше не зависит от срока действия кук или времени жизни сессии браузера.

Заказ → серверная передача. С вашей коммерческой платформы поступает вебхук об оплате заказа. Ваш бэкенд (или Elido, если вы делегировали это ему) считывает click_id, находит учетные данные для передачи конверсий и отправляет POST-запрос с конверсией на каждую подключенную рекламную платформу. Платформы получают конверсию и засчитывают ее исходной кампании.

Роль сокращателя заключается в управлении click_id на этапе 2 и оркестрации на этапе 4. Первый этап прост; второй - это то, где интеграция доказывает свою ценность.

Четырехэтапный пайплайн: клик на рекламной платформе попадает на короткую ссылку, которая фиксирует click_id, затем переходит на сайт, записывается в заказ, а вебхук об оплате запускает серверную рассылку конверсий в Meta CAPI, GA4 MP и TikTok Events

Дедупликация: то, о чем никто не говорит до запуска в продакшн#

Самый частый инцидент в продакшне, который я вижу, - это двойной учет. Браузерный пиксель все еще на странице (команда не отключила его, чтобы иметь резервный вариант для трафика не из Safari), и серверная передача тоже срабатывает. Meta принимает оба события. Конверсия учитывается дважды, аллокатор бюджета перерасходует средства, а при следующем анализе бюджета кампании кто-то замечает: «Постойте, почему наш отчетный ROAS в три раза выше выручки?».

Решение - идентификатор дедупликации. Meta CAPI принимает event_id. GA4 Measurement Protocol принимает client_id и transaction_id. TikTok Events принимает event_id. Если и браузер, и сервер отправляют одно и то же событие с одинаковым ID для дедупликации, платформа учитывает одно и игрирует второе.

ID для дедупликации должен иметь одинаковое значение на обеих сторонах. Для событий покупки (purchase) подходит ID заказа - его видят и браузерный пиксель, и серверная передача. Для предшествующих событий (лид, добавление в корзину, просмотр контента), когда заказа еще не существует, подходит click_id.

Документация Meta по дедупликации описывает окно сопоставления: события, полученные в течение 48 часов друг от друга с одинаковым event_id, считаются дубликатами. Дедупликация на основе client_id в GA4 аналогична по принципу, хотя и менее подробно документирована.

Операционное правило: каждая серверная конверсия должна содержать ID для дедупликации, и этот ID должен совпадать с тем, который отправил браузерный пиксель. Игнорирование этого правила - разница между работающей интеграцией CAPI и той, которая незаметно раздувает ваши отчетные показатели в течение трех месяцев, пока кто-то не заметит подвох.

Схема дедупликации: браузерный пиксель и серверная передача отправляют event_id order-001847; платформа засчитывает одно событие в 48-часовом окне и отбрасывает дубликат, тогда как несовпадающие ID приводят к двойному учету

Требования к хешированию#

И Meta CAPI, и TikTok Events требуют, чтобы идентификаторы электронной почты и телефона были хешированы с помощью SHA-256 перед передачей. GA4 строго этого не требует, но принимает. Хеширование выполняется для идентификаторов клиентов - em (email), ph (phone), fn (first name), ln (last name), ge (gender), db (date of birth), ct (city), st (state), zp (zip), country (country) - а не для метаданных события.

Есть два нюанса. Во-первых, формат должен быть нормализован перед хешированием: нижний регистр, отсутствие пробелов, удаление кода страны из телефона, удаление дефисов. Хеширование [email protected] даст результат, отличный от хеширования [email protected]; платформы ожидают последний вариант. На странице требований к параметрам Meta перечислены правила нормализации для каждого поля.

Во-вторых, хеш должен быть в виде шестнадцатеричной строки в нижнем регистре без пробелов. SHA256("[email protected]") выдает a3b6...; API ожидает a3b6..., а не A3B6... и не \xa3\xb6.... Большинство SDK языков программирования возвращают шестнадцатеричное значение в верхнем регистре по умолчанию; вам нужно привести результат к нижнему регистру.

Если вы используете эндпоинт Elido POST /v1/conversions, хеширование выполняется на стороне платформы - вы отправляете необработанные email/телефон, Elido выполняет нормализацию и хеширование в соответствии с требованиями платформ и пересылает данные. Преимущество в том, что вашему бэкенду нужно поддерживать только один набор правил нормализации вместо трех. Недостаток - вы доверяете Elido необработанные PII в момент передачи; запрос шифруется при транзите и не сохраняется на сервере, но эту модель доверия стоит изучить перед настройкой.

Пример Meta CAPI POST-запроса#

Что на самом деле ожидает платформа. Эндпоинт: POST https://graph.facebook.com/v21.0/{pixel_id}/events. Тело запроса - JSON.

{
  "data": [
    {
      "event_name": "Purchase",
      "event_time": 1716480000,
      "event_id": "order-acme-2026-05-23-001847",
      "action_source": "website",
      "event_source_url": "https://acme.example/checkout/thanks?order=001847",
      "user_data": {
        "em": ["a3b6...sha256 of email"],
        "ph": ["c4d7...sha256 of phone"],
        "client_user_agent": "Mozilla/5.0 ...",
        "client_ip_address": "203.0.113.42",
        "fbc": "fb.1.1716470000.AbCdEf",
        "fbp": "fb.1.1716470000.987654321"
      },
      "custom_data": {
        "currency": "EUR",
        "value": 89.5,
        "content_ids": ["sku-spring-jeans-32-blue"],
        "content_type": "product",
        "num_items": 1
      }
    }
  ],
  "test_event_code": "TEST12345",
  "access_token": "EAAxxxxxxx"
}

Три важных момента:

event_id - это ключ дедупликации. Установите в него ID вашего заказа; браузерный пиксель Purchase должен передавать то же значение. Meta выполнит дедупликацию в течение 48-часового окна.

fbc и fbp - это идентификаторы кук Meta. fbc - это идентификатор клика (fbclid из целевого URL с префиксом); fbp - идентификатор браузера из куки _fbp. Оба являются основными (first-party) с точки зрения вашего домена и могут быть зафиксированы на стороне сервера после того, как вы сохранили их при переходе на целевую страницу. Если их нет, коэффициент сопоставления Meta падает; если они есть, сопоставление работает отлично.

test_event_code позволяет отправлять тестовые события, которые не учитываются в рабочих отчетах. Всегда настраивайте это в первую очередь; проверяйте в Events Manager Test Events перед запуском рабочего трафика.

Эквивалент в API Elido: POST /v1/conversions с параметрами {click_id, event_name: "Purchase", value, currency, order_id, customer: {email, phone}}. Elido нормализует и хеширует данные согласно спецификации Meta, находит fbc/fbp воркспейса из события клика и формирует полезную нагрузку CAPI.

Пример GA4 Measurement Protocol POST-запроса#

Формат GA4 похож по структуре, но названия полей отличаются. Эндпоинт: POST https://www.google-analytics.com/mp/collect?measurement_id=G-XXX&api_secret=xxx.

{
  "client_id": "click-id-as-fallback-if-no-ga4-cookie",
  "user_id": "user-acme-12847",
  "events": [
    {
      "name": "purchase",
      "params": {
        "transaction_id": "order-acme-2026-05-23-001847",
        "value": 89.5,
        "currency": "EUR",
        "items": [
          {
            "item_id": "sku-spring-jeans-32-blue",
            "item_name": "Spring Jeans 32 Blue",
            "quantity": 1,
            "price": 89.5
          }
        ],
        "engagement_time_msec": 1
      }
    }
  ]
}

Примечания:

client_id - это значение _ga из куки GA4, если оно есть; если нет, click_id станет подходящим запасным вариантом (потому что GA4 создаст сессию на его основе).

transaction_id - ключ дедупликации. Установите ID вашего заказа, то же значение, что и у браузерного события gtag purchase. GA4 выполнит дедупликацию в рамках своего окна сессии.

engagement_time_msec должен присутствовать и быть положительным, чтобы событие учитывалось в атрибуции; значение 1 удовлетворяет этому требованию.

api_secret настраивается на уровне воркспейса. В документации GA4 MP описана процедура настройки учетных данных.

Семантика повторных попыток#

Платформы допускают повторные попытки (retries), но нельзя делать их вслепую. Эффективны три паттерна:

Идемпотентность по ID дедупликации. Если в качестве event_id / transaction_id платформы используется ID заказа, и вы повторно отправляете ту же нагрузку, платформа выполнит дедупликацию - вторая отправка будет незаметно проигнорирована. Это безопасно.

Экспоненциальная задержка при 5xx. И Meta, и GA4 иногда возвращают 5xx. Делайте повторные попытки с задержкой (1с, 2с, 4с, 8с до 60с, затем прекращайте). Повторы должны сохранять тот же event_id, чтобы платформа могла дедуплицировать данные в случае частичного успеха.

Не повторяйте при 4xx. Ответ 4xx означает, что данные неверны или учетные данные ошибочны. Повторные попытки ничего не изменят, они лишь израсходуют лимит запросов. Логируйте ошибку, настраивайте алерты и исправляйте причину на стороне источника.

Если вы используете Elido, повторы и задержки обрабатываются автоматически - POST /v1/conversions возвращает ответ немедленно, а рассылка на платформы происходит в фоновом режиме, причем статус повторов можно отследить через GET /v1/conversions/{id}. Если вы создаете собственное решение, логика повторов должна находиться на уровне очередей (RabbitMQ, Kafka, AWS SQS).

Диаграмма решений для повторных попыток: POST конверсии с ключом по ID заказа ветвится по классу ответа - 2xx помечает как выполнено, 5xx запускает экспоненциальную задержку и повторный POST с тем же event_id, 4xx останавливается с логированием и алертом

Тестовый режим и пробный запуск (dry-run)#

Самая большая ошибка, которую совершают команды, - это пропуск пробного запуска (dry-run).

В Meta есть Test Events. Вы устанавливаете test_event_code в запросе, события появляются в панели Test Events в течение нескольких секунд, и вы проверяете формат и дедупликацию. Рабочие события приходят на тот же эндпоинт, но без test_event_code.

В GA4 есть DebugView. Вы устанавливаете debug_mode: 1 в параметрах события, события появляются в DebugView, и вы проверяете их перед запуском рабочего трафика.

В TikTok есть аналогичный тестовый режим в интерфейсе Events Manager.

Чек-лист проверки короткий. Оформите тестовый заказ, проследите за вебхуком об оплате заказа, убедитесь в срабатывании серверной передачи и в том, что данные поступили в тестовую панель платформы. Подтвердите, что event_id совпадает с ID браузерного пикселя. Проверьте правильность значений, валюты и content_ids. После этого отключите тестовый режим и проследите за первыми десятью реальными заказами.

Если вы пропустите этот этап, то через три дня обнаружите, что интеграция сломана, а отчеты пусты. Пропуск пробного запуска - самая частая причина неудач, которую я наблюдаю.

Распространенные ошибки#

click_id отсутствует в заказе. Самая частая проблема. Мы уже разбирали это в статье о сокращателях ссылок для e-commerce; решение - пробросить click_id через корзину в заказ.

Несовпадение хешей. [email protected], хешированный без нормализации, дает значение, отличное от [email protected]. Платформы не находят совпадение, конверсия попадает в систему без привязки к идентификатору, и в отчетах Meta она помечается как «несопоставленная» (unmatched). Решение - правила нормализации из документации по параметрам Meta CAPI; более чистый вариант - делегировать хеширование сокращателю, чтобы правила хранились в одном месте.

fbc не зафиксирован. Когда пользователь переходит по рекламе Meta, URL содержит fbclid; страница должна зафиксировать его и сохранить (обычно в кастомных атрибутах заказа). Без fbc коэффициент сопоставления Meta существенно падает. Решение - этап тег-менеджера на целевой странице, который записывает fbc в основную куку или атрибут корзины.

Несогласованный ID дедупликации. Браузерный пиксель использует ID заказа, а серверная передача - UUID, сгенерированный в момент отправки. Оба события принимаются, но ни одно из них не дедуплицируется. Решение - убедиться, что серверная передача использует то же значение event_id, которое отправил браузерный пиксель (стандартный ответ - ID заказа для покупок).

Несовпадение валют. Браузер отправляет USD (потому что в конфиге gtag по умолчанию стоит USD), а сервер отправляет EUR (потому что заказ оформлен в евро). И GA4, и Meta в некоторых контекстах сопоставления рассматривают валюту как часть сигнатуры события, поэтому конверсии принимаются, но не агрегируются корректно. Решение - брать валюту из заказа, а не из конфигурации на уровне страницы.

Где это находится в плоскости данных#

Передача конверсий - это часть более широкого пайплайна атрибуции. Краеугольным камнем для сопутствующего пайплайна является статья Как отслеживать UTM-кампании сквозным методом без CDP - там подробно разобраны шаблоны UTM воркспейса, переопределения на уровне кампаний, массовый импорт и этап проверки dry-run. Этот пост - более глубокое погружение в серверную рассылку, которая замыкает цикл.

Для операционного руководства используйте документацию по передаче конверсий. Технические подробности того, как Elido осуществляет рассылку, не превышая лимиты платформ, описаны в посте про архитектуру обработки кликов.

Читайте в кластере#

Похожие статьи в кластере функций: Объяснение смарт-ссылок (базовая статья), Вебхуки для событий ссылок (общая структура событий) и Передача конверсий в Meta CAPI (более детальный разбор специфики Meta). Для маркетологов доступна страница solutions/marketers; описание продуктовой части - на странице функции отслеживания конверсий.

Похожее в блоге#

Попробуйте Elido

Вставьте URL - получите короткую ссылку

Без регистрации. Ссылка живёт 30 дней. Зарегистрируйтесь, чтобы оставить её навсегда.

Бесплатно, без регистрации · 2 в день

Попробуйте Elido

URL-сокращатель с хостингом в ЕС: собственные домены, глубокая аналитика, открытый API. Бесплатный тариф - без банковской карты.

Теги
server side conversion tracking
meta capi
ga4 server side
conversion api
tiktok events api
deduplication
click_id

Читать дальше