Перейти к содержимому

ГайдыРекламные платформы11 мин чтения

Meta Pixel, Conversions API или оба сразу в Shopify: что каждый на самом деле измеряет

Что видит браузерный Pixel Meta, что отправляет Conversions API только с сервера и почему рекомендованная схема в Shopify запускает оба с общим event_id.

Опубликовано
Проверено
Браузерные события, события бэкенда и парная реализация.

Daniil MaximkinРазработка продуктов и интеграций

Короткий ответ

Meta может получать ваши события Shopify тремя способами: только браузерный Pixel, только серверный Conversions API или оба сразу. Pixel видит то, что выполняет страница, сервер видит то, что знает ваш бэкенд, а рекомендованная схема с двумя источниками отправляет оба потока с общим event_id, чтобы Meta свернула пару в одно учтённое событие. Каждый способ закрывает свою часть воронки.

Даниил

Главное

  • Только браузерный Pixel непосредственно видит события уровня страницы: ViewContent, AddToCart, InitiateCheckout, потому что они происходят в браузере покупателя.
  • Только серверный Conversions API подходит для событий Purchase уровня заказа, включая заказы, которые браузер не довёл до конца. Но он не видит события страницы, а fbp и fbc нужно получить в браузере.
  • Схему с двумя источниками рекомендует Meta: одинаковые event_name и event_id с обеих сторон, полученные в пределах окна сопоставления, чтобы одна покупка считалась один раз.
  • Дедупликация работает только по правилу сопоставления, а не сама по себе. Разные id, разные названия событий, отсутствие id с одной стороны или слишком большой разрыв по времени оставляют два события.
  • Ни один из трёх вариантов не решает проблемы согласия, блокировщиков или неверного определения конверсии. Они меняют то, что получает Meta, а не то, что записал Shopify.
В этом гайде

Meta может получать события вашего магазина на Shopify из браузерного Pixel, из серверного вызова Conversions API или из обоих сразу. Это не конкурирующие продукты, а три уровня охвата одной и той же воронки, и различие в том, что способен увидеть каждый источник.

Этот гайд для продавца Shopify или маркетолога в штате, которые решают, как Meta должна получать события, и для разработчика, который это внедряет. Он сравнивает три способа по принципу работы: где срабатывает событие, какие параметры передаются, как соблюдается согласие, как работает дедупликация и что каждый даёт для сверки с заказами Shopify. Он не выбирает победителя, не называет стоимость и не обещает улучшения качества сопоставления: это зависит от вашего трафика, каталога, доли согласий и команды.

Что на самом деле измеряет браузерный Meta Pixel?

Браузерный Pixel измеряет то, о чём может сообщить страница покупателя: просмотры страниц и действия на странице, которые в браузере запускает ваша тема или веб-пиксель Shopify. Он непосредственно видит ViewContent, AddToCart и InitiateCheckout и теряет любое событие, которое браузер так и не выполнил.

Базовый код устанавливается один раз, после чего Pixel отправляет данные через fbq('track', ...). При каждой загрузке Pixel сам вызывает fbq('track', 'PageView'), поэтому просмотры страниц не зависят от того, пишете ли вы код событий. Стандартные события покрывают воронку: ViewContent на странице товара, AddToCart, когда товар попадает в корзину, InitiateCheckout, когда начинается чекаут, и Purchase на странице подтверждения, или «Спасибо». Каждое принимает объект параметров (content_ids, contents, currency, value, content_type), чтобы передать в событии товар и его стоимость.

Помимо запуска события важны две детали. Первая: Advanced Matching. Значения, которые вы передаёте в fbq('init'), Pixel хеширует SHA-256 до того, как они покинут браузер, поэтому хешированный email может уйти без исходного значения. Вторая: пара идентификаторов _fbp и _fbc. Pixel ставит идентификатор браузера (_fbp) и формирует идентификатор клика (_fbc) из fbclid в клике по рекламе, который привёл посетителя. Эти значения связывают событие браузера с кликом.

Раз всё происходит в браузере, браузер же и задаёт ограничения. Блокировка по согласию останавливает Pixel у покупателей, которые отказались от маркетинговых целей. Блокировщики рекламы, страница, которая так и не отрисовалась, или вкладка, закрытая до страницы подтверждения, не дают события. В Shopify браузерная покупка зависит от checkout_completed, который срабатывает один раз на чекаут, обычно на странице «Спасибо» или на первой странице допродажи, если используются предложения после покупки, и не срабатывает вовсе, если эта страница не загрузилась. Защита приватности в браузерах может также сокращать или блокировать cookie, которые ставит скрипт, включая _fbp. Срок их жизни нужно проверять тестом, а не предполагать.

По браузерному Pixel можно сверять только число покупок, которые видел браузер. Возврат, оформленный позже в бэк-офисе, вне его поля зрения.

// Browser: one id per purchase, derived from the order so the server can reproduce it
fbq('track', 'Purchase', {
  value: 129.00,
  currency: 'USD',
  contents: [{ id: 'SKU-123', quantity: 1 }],
  content_type: 'product'
}, { eventID: 'purchase_4512890' });

Что на самом деле измеряет настройка только с серверным Conversions API?

Только серверный Conversions API измеряет то, что знает ваш бэкенд. Он отправляет именованные события прямо в Meta из вашей инфраструктуры, поэтому сообщает о покупках, которые фиксирует ваша система, включая заказы, не завершённые в браузере, и не зависит от страницы покупателя в момент отправки.

Вы отправляете POST с массивом data на эндпоинт событий Meta для вашего Pixel, аутентифицируясь токеном доступа. Каждое серверное событие содержит обязательные поля: event_name (название стандартного или пользовательского события), event_time (когда оно произошло) и action_source, который объявляет, где произошла конверсия. Событие сайта должно также содержать event_source_url и client_user_agent, без них оно недействительно.

Поле action_source обязательно, его нельзя пропустить. Meta требует его в каждом событии; допустимые значения: website, app, email, phone_call, chat, physical_store, system_generated, business_messaging и other. Неверный выбор искажает, где произошла конверсия, а условия Meta возлагают на вас ответственность за его точность. Для покупки на витрине Shopify корректное значение здесь website, поэтому вместе с ним передаются event_source_url и user agent.

С пользовательскими данными у сервера есть и преимущества, и пробелы. Он может отправлять em и ph, нормализованные (например, у email удалены крайние пробелы, а буквы приведены к нижнему регистру) и хешированные SHA-256, а также external_id и client_ip_address. Может отправлять и fbc с fbp, но только если эти значения существуют. _fbc берётся из fbclid в URL посадочной страницы, а _fbp ставит браузер. Сервер, который не взаимодействует с браузером, не имеет ни того, ни другого и придумать их не может. Серверный пайплайн видит действия уровня страницы, такие как ViewContent и AddToCart, только если страница явно сообщает о них серверу, потому что наблюдает их один лишь браузер.

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

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

Что меняется, когда вы запускаете оба с дедупликацией по event_id?

Запуск обоих превращает две неполные записи в одну полную, но только когда Meta может их сопоставить. В рекомендованной схеме с двумя источниками Pixel и Conversions API отправляют одинаковые event_name и event_id, и Meta объединяет пару в одно событие.

Meta документирует схему с двумя источниками (отправлять все события из обоих источников) как рекомендованную конфигурацию при условии, что вы можете сгенерировать постоянный event_id для обоих. Правило точное: eventID в Pixel должен совпадать с event_id на сервере, а event в Pixel должен совпадать с event_name на сервере. Когда совпадают обе пары и второе событие приходит в течение 48 часов после первого, Meta оставляет первое и отбрасывает дубль. Если два события приходят с разницей около пяти минут, Meta отдаёт предпочтение браузерному событию.

Есть задокументированный запасной вариант: сопоставление по event_name плюс fbp и/или external_id. У него есть условия: он обычно работает, только когда первым приходит браузерное событие, а серверное следует за ним, и серверное событие не отбрасывается лишь потому, что позже появился идентичный браузерный.

Итак, для дедупликации нужен стабильный id, который обе стороны могут получить независимо. Обычно для этого берут номер заказа или ID транзакции: браузер читает его на странице подтверждения, а сервер уже им располагает. Ломает дедупликацию любое расхождение: id, генерируемый заново при каждой загрузке страницы, id, который есть с одной стороны и отсутствует с другой, разница в регистре или написании названия события (purchase вместо Purchase), разрыв больше окна сопоставления или настройка, где работает только один источник. Каждый случай оставляет два события, а два события читаются как две покупки.

Результат показывает Events Manager. Test Events показывает входящие события с их источником: совпавшая пара отображается как дедуплицированная, а не как две отдельные конверсии, а в подробностях события видно, как пришло каждое. Сводная панель показывает только итоги, а итоги скрывают дублирование, которое вы ищете.

{
  "data": [{
    "event_name": "Purchase",
    "event_time": 1690000000,
    "event_id": "purchase_4512890",
    "action_source": "website",
    "event_source_url": "https://store.example/checkout/thank-you",
    "user_data": {
      "em": ["<sha256 of the normalized email>"],
      "fbp": "fb.1.1690000000.1234567890",
      "fbc": "fb.1.1690000000.AbCdEfGh"
    },
    "custom_data": { "value": 129.00, "currency": "USD" }
  }]
}

Сравнение вариантов

Таблица сравнивает три варианта по критериям, которые определяют работу большинства настроек в Shopify. Она описывает компромиссы, а не ранжирует, и в ней нет цен вендоров.

КритерийТолько браузерный PixelТолько Conversions APIОба, с event_id
Источник событийБраузер покупателя, на страницеВаш сервер или бэкендОба, описывающие одно и то же действие
Охват покупок и возвратовPurchase, когда выполняется страница подтверждения; возвраты не видныПокупки из бэк-офиса; возвраты можно представить по данным заказаPurchase передаётся дважды и учитывается один раз; возвраты по-прежнему требуют вашего решения
ДедупликацияНе применяется: один источникНе применяется: один источникСопоставление по event_id и event_name
Обработка согласияБлокируется в браузере инструментом согласияВаш пайплайн должен передавать сигнал согласия и блокировать события при отказеОбе стороны должны соблюдать один и тот же сигнал
Владение даннымиДанные события собирает и отправляет браузерДанные события собирает и отправляет ваша инфраструктураРазделено: собирает браузер, пересылает сервер
Зависимость и привязкаЗависит от выполнения страницы и от защиты в браузереЗависит от вашего эндпоинта, токена и схемы idЗависит от того, что обе стороны остаются согласованными
Нагрузка на сопровождениеНизкая, пока изменение приватности или темы не сломает путьСхема id, повторы и мониторинг на васСамая высокая: два пути, которые должны совпадать
Кому подходитМагазинам, у которых достаточно браузерного сигнала и нет другого источника MetaМагазинам, у которых потери происходят в браузере и которые могут поддерживать пайплайнМагазинам, которым нужен охват всей воронки и одна учтённая покупка

Таблица решений

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

Если ваша ситуация такая …Выбирайте …
Вы оптимизируете кампании только под Purchase, и браузерный путь его уже покрываетТолько браузерный Pixel
Вам нужны сигналы верхней воронки (просмотр, добавление в корзину), а не только покупкиБраузерный Pixel плюс Conversions API с дедупликацией по event_id
Вам нужны покупки, которые браузер не довёл до конца: ручные заказы, чекауты вне сайта, некоторые допродажиConversions API, а браузерный Pixel оставьте для событий страницы
Другая система уже отправляет Meta Purchase (канал продаж или приложение)Решите, какой один путь отвечает за Purchase, а остальное дедуплицируйте по общему event_id
Вам нужно контролировать, какие пользовательские параметры уходят и когда согласие разрешает отправкуConversions API, обычно через серверный сбор
Вы не можете поддерживать id, который сохраняется при перезагрузкахТолько браузерный Pixel, и примите ограничения его охвата
Meta и Shopify расходятся по итогамСначала сверка: расхождение может быть в правилах подсчёта, а не в охвате

Когда каждый вариант не подходит

Только браузерный Pixel не подходит, когда потери происходят при передаче. Только серверная схема не подходит, когда никто не поддерживает схему id. Запуск обоих не подходит, когда никто не может добиться совпадения id. Ни один из трёх не годится как обход согласия.

Не выбирайте только браузер, когда:

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

Не выбирайте только сервер, когда:

  • Вашим кампаниям нужны ViewContent и AddToCart для каталожных аудиторий или ретаргетинга: сервер их не видит, если страница их не отправляет.
  • У вас нет способа получить fbclid и идентификаторы браузера, поэтому fbp и fbc будут отсутствовать, а связи с кликом не останется.
  • Никто не возьмёт на себя токен, повторы и мониторинг. Сбой серверного пути может остаться незамеченным.

Не выбирайте оба, когда:

  • Никто не может определить один стабильный id, который обе стороны получают сами. Два несопоставленных источника завышают число покупок сильнее, чем один несовершенный.
  • Второй источник нельзя изменить: это приложение канала, которое генерирует собственный id. Лучше объединить отправку в один путь, чем добавлять третий.

И ни один из трёх не исправляет:

  • Согласие. Правильно построенный серверный путь всё равно подавляет события для посетителей, которые отказались. (Речь о технической реализации, это не юридическая консультация.)
  • Неверное определение конверсии или отсутствующее событие покупки.
  • Структурный разрыв между подсчётом Meta и заказами Shopify: это сверка заказов, а не новый источник событий.

Как я проверяю это в реальных внедрениях

Я проверяю подсчётом и сопоставлением, а не чтением панелей: подтверждаю действующие источники, смотрю реальное событие в Test Events Meta, проверяю id и сверяю число с выгрузкой заказов Shopify.

  1. Инвентаризация всех источников, которые могут отправлять события в Meta. Канал продаж, приложения, веб-пиксель, код темы, серверный пайплайн. Дублирование начинается с источника, о котором никто не помнил.
  2. Проверьте поступающее событие. Используйте Test Events в Events Manager и отправьте серверное событие с test_event_code, чтобы оно появилось рядом с браузерным. DebugView относится к GA4, события Meta он не покажет.
  3. Проверяйте ключ, а не только факт прихода. Убедитесь, что eventID в браузере и event_id на сервере представляют собой одну и ту же строку и что оба названия событий совпадают точно. Нужный сигнал: дедуплицированная пара. Две отдельные конверсии означают ошибку.
  4. Подтвердите охват с обеих сторон. Проверьте, что ViewContent, AddToCart и InitiateCheckout приходят из браузера, а Purchase по одному и тому же заказу приходит из обоих источников.
  5. Подтвердите, что идентификаторы доходят. Если данные были получены в браузере, проверьте, что fbp и fbc есть в серверном событии. Где его не было, ничего не предполагайте.
  6. Сверьтесь с закрытым периодом. Сравните число событий покупки с выгрузкой заказов Shopify за фиксированный период.
  7. Проверьте и отказ, и выдачу согласия. При отказе от маркетингового согласия убедитесь, что ничего не срабатывает. При его выдаче убедитесь, что события идут.

Типичные сценарии сбоев

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

  • Id, генерируемый заново при каждой загрузке страницы. event_id, созданный при рендере из нового UUID или метки времени, никогда не совпадёт с серверной парой.
  • Id, полученный только с одной стороны. Pixel и сервер отправляют разные строки для одного заказа, поэтому Meta видит два события.
  • Расхождение в названии события. Purchase с одной стороны, purchase или пользовательское название с другой. Id могут совпадать идеально, но сопоставление всё равно не сработает.
  • Id отсутствует с одной стороны. Сопоставлять не с чем.
  • Задержанная серверная отправка, которая попадает за пределы окна сопоставления.
  • Второй источник, оставленный включённым после миграции: каждая половина генерирует собственный id.
  • Серверное событие с website, но без event_source_url или client_user_agent: это недействительное событие сайта.
  • fbp/fbc считаются доступными без сбора в браузере. На сервере они есть, только если их передал браузер.
  • Согласие соблюдается в браузере, но не в серверном пайплайне.

Ограничения

Каждый вариант ограничен данными, которые получает. Браузерный Pixel не может сообщить о том, чего браузер не выполнил. Только серверная схема не видит события страницы, о которых ей не сказали. Запуск обоих не может сверить себя сам, потому что дедупликация зависит от идентификаторов, которые вы держите в порядке.

Ни один из вариантов не меняет правила подсчёта Meta и итоги заказов Shopify. fbp и fbc помогают сопоставлению, когда они есть, но серверный путь без сбора в браузере их не получит. Схема с двумя источниками также добавляет работу по сопровождению: два пути, которые должны согласовываться бессрочно. А обязательства по согласию и минимизации данных относятся ко всем трём, где бы ни собиралось событие. Если воспринимать каждый вариант как точку обзора воронки, они дополняют друг друга.

Альтернативы

Если проблема не в том, какой источник событий выбрать, а в том, что происходит с запросом по пути в Meta, нужно проверить доставку: серверный сбор через собственный (first-party) эндпоинт, описанный в услуге по серверному трекингу и разобранный с ограничениями в Серверный трекинг: преимущества, ограничения и архитектура.

Если вы выбираете пайплайн Meta, а не источник событий, сравнение вендоров приведено в Meta Conversions API в Shopify: нативное приложение, Stape или серверный GTM. Если симптом в том, что Meta завышает цифры, начните с диагностики дедупликации Meta CAPI и механики в Дедупликация в Meta CAPI: как на самом деле работает event_id. Об измерении Google для того же магазина см. Как исправить событие purchase в GA4 на Shopify и Почему выручка в GA4 не совпадает с Shopify. Базовые понятия описаны в event ID, Event Match Quality и Consent Mode v2.

Если гайд не решил вопрос25 000 ₽

Я провожу эту сверку на вашем магазине в режиме только чтения, за 25 000 ₽: письменный вывод через два рабочих дня после старта.

Вопросы

Вопросы, на которые отвечает этот гайд

Нужен ли браузерный Pixel, если я отправляю серверный Conversions API?

Обычно да, это соответствует рекомендациям самой Meta. Браузер видит события уровня страницы, которые сервер наблюдать не может: ViewContent, AddToCart, InitiateCheckout. И он получает идентификаторы fbp и fbc, которые приходят из визита и клика по рекламе. Серверный пайплайн без браузера их теряет, если страница не передаёт эту информацию дальше. Рекомендованная схема: оба источника с дедупликацией по общему event_id.

Что именно должно совпадать, чтобы дедупликация сработала?

Две пары полей. eventID в Pixel должен совпадать с event_id на сервере, а event в Pixel должен совпадать с event_name на сервере. Когда совпадают обе пары и второе событие приходит в окне сопоставления Meta, одно сохраняется, а другое отбрасывается. Если последовательно передавать event_name плюс fbp и/или external_id, можно опереться на этот запасной метод, но обычно он работает, только когда первым приходит браузерное событие.

Можно ли отправлять Conversions API без fbp и fbc?

Событие отправить можно, но этих полей в нём не будет, и связи с кликом, которую дал бы браузер, не будет. fbc получают из fbclid в URL посадочной страницы, а fbp ставит Pixel в браузере. Сервер, который не взаимодействует с браузером, не имеет ни того, ни другого и придумать их не может. Если они нужны в серверных событиях, их должен получить браузер и передать дальше.

Как проверить в Events Manager, работает ли дедупликация?

Используйте Test Events, а не сводную панель. Отправьте серверное событие с test_event_code, чтобы оно появилось рядом с браузерным, затем убедитесь, что пара показана как дедуплицированная, а не как две отдельные конверсии, и что eventID в браузере и event_id на сервере читаются как одна и та же строка. Сводный отчёт скрывает дублирование, а Test Events и подробности события показывают, как пришло каждое событие.

Daniil Maximkin

Здравствуйте, я Даниил.

Я сам разбираюсь в задаче, выполняю работу и передаю результат. Все вопросы вы обсуждаете напрямую со мной. Общаюсь на русском и английском. На испанском могу переписываться с помощью переводчика.

Попробовали и всё равно не выходит?

Опишите задачу

Отвечу в течение одного рабочего дня. Первый ответ бесплатный. Или напишите напрямую: next@taskfordaniel.com

Обсудить задачу

Расскажите, что нужно разработать, исправить или подключить.

Описать задачу next@taskfordaniel.com