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

Электронная торговля в аналитике - события, покупка, сверка

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

Механика

Внешняя аналитика видит не заказы, а события браузера. Покупка для неё - это сообщение, отправленное со страницы благодарности, а не запись в базе. Отсюда все её особенности: пропущенное сообщение означает пропущенную покупку, а отправленное дважды - две покупки на один заказ.

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

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

Отдельно стоит вопрос доверия к числам. Блокировщики, отключённые скрипты и уход со страницы до отправки дают в аналитике меньше покупок, чем в базе. Расхождение в проценты - норма, в разы - повод разбираться.

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

Стоит заранее договориться, чьи это числа. Отчёт аналитики нужен маркетологу, а бухгалтерии нужна база заказов, и попытка свести их до копейки заканчивается неделей выяснений и выводом, что расхождение объясняется блокировщиками. Полезнее следить за динамикой: сегодняшнее расхождение сравнивают со вчерашним, а не с нулём.

Шаги

  1. Завести счётчик и цели в кабинете сервиса аналитики.
  2. Поставить код счётчика в шаблон сайта, вне кэшируемых блоков.
  3. Отправлять события просмотра и корзины из соответствующих мест витрины.
  4. Отдать покупку один раз на странице благодарности, с защитой от повтора.
  5. Исключить из отчётов свои визиты и тестовые заказы.
  6. Завести ежедневную сверку числа покупок с числом заказов в базе.

Код

Ставим счётчик в шаблон сайта:

// footer.php шаблона сайта, вне кэшируемых областей
$APPLICATION->AddBufferContent(function () {
return '<script>/* код счётчика из кабинета сервиса */</script>';
});
// в кэшируемой части он отработает один раз - при сборке копии страницы

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

Отправляем событие просмотра товара:

// шаблон карточки товара
$event = ['event' => 'view_item', 'items' => [[
'item_id' => $arResult['ID'],
'item_name' => $arResult['NAME'],
'price' => (float)$arResult['PRICE']['DISCOUNT_VALUE'],
'item_category' => $sectionName,
]]];
echo '<script>window.dataLayer=window.dataLayer||[];dataLayer.push('
. \Bitrix\Main\Web\Json::encode($event) . ');</script>';

Просмотр, корзина и оформление - разные события одной воронки. Набор полей у них общий, и именно по номеру товара отчёт связывает просмотр с последующей покупкой.

Отправляем добавление в корзину:

// в обработчике ответа на добавление товара
BX.addCustomEvent('OnBasketChange', () => {
dataLayer.push({ event: 'add_to_cart', items: [{ item_id: id, price, quantity }] });
});
// событие отправляют после успешного ответа сервера, а не по клику

Событие отправляют после успешного ответа сервера, а не по нажатию кнопки. Клик без ответа означает, что товар в корзину не попал, а в отчёте он уже посчитан.

Отдаём покупку на странице благодарности:

// шаблон sale.order.ajax, шаг подтверждения заказа
$orderId = (int)$arResult['ORDER_ID'];
if ($orderId && !isset($_SESSION['ECOM_SENT'][$orderId])) {
$_SESSION['ECOM_SENT'][$orderId] = true; // защита от повторной отправки
echo '<script>dataLayer.push(' . Json::encode($purchase) . ');</script>';
}
// без этой отметки обновление страницы даёт вторую покупку на тот же заказ

Покупку отправляют один раз. Отметка об отправке в сеансе - самая дешёвая защита: без неё каждое обновление страницы благодарности добавляет в отчёт ещё одну покупку с той же суммой.

Собираем состав покупки из заказа:

$order = \Bitrix\Sale\Order::load($orderId);
$items = [];
foreach ($order->getBasket() as $item) {
$items[] = ['item_id' => $item->getProductId(), 'price' => (float)$item->getPrice(),
'quantity' => (float)$item->getQuantity()];
}
$purchase = ['event' => 'purchase', 'transaction_id' => $order->getField('ACCOUNT_NUMBER'),
'value' => (float)$order->getPrice(), 'items' => $items];

Состав покупки берут из заказа, а не из параметров адреса. Данные из адресной строки теряются при переходах и подделываются вручную, а заказ в базе - источник, которому можно верить.

Сверяем отчёт с базой:

$cnt = \Bitrix\Sale\Internals\OrderTable::getList([
'select' => ['CNT' => new \Bitrix\Main\Entity\ExpressionField('CNT', 'COUNT(%s)', 'ID')],
'filter' => ['>=DATE_INSERT' => $dayStart, '!=STATUS_ID' => 'TEST'],
])->fetch();
printf("заказов за сутки: %s\n", $cnt['CNT']);
// это число сравнивают с числом покупок в отчёте сервиса

Число покупок в отчёте сверяют с числом заказов. Расхождение в несколько процентов объясняется блокировщиками, а в разы - сломанной отправкой, и заметить это стоит в тот же день.

Исключаем свои визиты и тестовые заказы:

// служебные заказы помечают статусом или свойством и не отдают в аналитику
if ($order->getField('STATUS_ID') === 'TEST' || $USER->IsAdmin()) {
return; // событие покупки не отправляем вовсе
}
// визиты сотрудников отсекают настройками счётчика в кабинете сервиса

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

Ограничения

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

Часть посетителей не отдаст событий никогда: блокировщики, отключённые скрипты, закрытая вкладка до отправки. Аналитика по устройству показывает меньше, чем есть на самом деле, и строить на её числах бухгалтерию нельзя.

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

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

Оплата на стороне банка уводит покупателя с сайта. Если он не вернётся на страницу благодарности, покупка не отправится вовсе, и такие случаи закрывают отправкой с сервера при отметке оплаты - отдельной задачей.

Типичные проблемы

В отчёте покупок вдвое больше, чем заказов.

Событие покупки отправляется при каждом показе страницы благодарности. Отметка об отправке покупки в сеансе посетителя закрывает этот повтор.

Покупки не приходят вовсе.

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

Суммы в отчёте не сходятся с заказами.

Состав покупки собран из параметров адресной строки, а не из заказа. Источником должен быть сам заказ в базе.

В отчёте есть заказы менеджеров.

Тестовые заказы и визиты сотрудников не исключены из учёта. Их отсекают статусом самого заказа и настройками счётчика в кабинете.

В аналитику уехали телефоны покупателей.

В событие попал весь массив свойств заказа целиком. В событиях оставляют только номер заказа и состав его корзины.

Частые вопросы

Почему в аналитике меньше покупок, чем в базе?

Часть посетителей не отдаёт событий из-за блокировщиков и закрытых вкладок. Расхождение в проценты - это норма.

Как проверить отправку сразу?

Режимом отладки в кабинете сервиса и консолью браузера. Ждать отчёта следующего дня не нужно.

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

Отправлять покупку с сервера при отметке оплаты. Это отдельная задача со своими сложностями.

Можно ли отправлять почту покупателя?

Не стоит: это персональные данные во внешнем сервисе. Номера заказа и состава корзины достаточно.

Нужны ли события просмотра и корзины?

Без них отчёт покажет покупки, но не покажет, где теряются посетители. Воронка и есть главная польза.

Смежное

Первоисточник