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

Источник заказа - метки в адресе, хранение, отчёт

Узнаём, откуда пришёл заказ: перехват меток в адресе, хранение между визитами, запись в свойство заказа и простой отчёт по источникам.

Что нужно знать заранее

Метки источника приходят в адресе первой страницы визита. Дальше посетитель ходит по сайту без них, поэтому значение надо перехватить сразу и сохранить на своей стороне.

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

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

Шаги

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

Решение

Перехватываем метки на входе:

// /local/php_interface/init.php, до вывода страницы
$marks = array_intersect_key($_GET, array_flip(['utm_source', 'utm_medium', 'utm_campaign']));
if ($marks) {
$value = mb_substr(http_build_query($marks), 0, 250); // ограничиваем длину значения
$response = \Bitrix\Main\Context::getCurrent()->getResponse();
$response->addCookie(new \Bitrix\Main\Web\Cookie('last_source', $value, time() + 2592000));
if (empty($_COOKIE['first_source'])) {
$response->addCookie(new \Bitrix\Main\Web\Cookie('first_source', $value, time() + 31536000));
}
}

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

Записываем источник в заказ:

\Bitrix\Main\EventManager::getInstance()->addEventHandler('sale', 'OnSaleOrderBeforeSaved',
static function (\Bitrix\Main\Event $event) {
$order = $event->getParameter('ENTITY');
setOrderProp($order, 'FIRST_SOURCE', $_COOKIE['first_source'] ?? '');
setOrderProp($order, 'LAST_SOURCE', $_COOKIE['last_source'] ?? ''); // до сохранения
});

Записывают значения до сохранения заказа, а не после. Обработчик после сохранения потребует второго сохранения, и в журнале заказа появится лишнее изменение без причины.

Ищем свойство заказа по коду:

$propertyCollection = $order->getPropertyCollection();
foreach ($propertyCollection as $prop) {
if ($prop->getField('CODE') === 'LAST_SOURCE') { $prop->setValue($value); }
}
// свойство ищут по символьному коду: идентификаторы на стендах различаются

Строим отчёт по источникам:

SELECT p.VALUE AS source, COUNT(*) AS orders, SUM(o.PRICE) AS total
FROM b_sale_order o
JOIN b_sale_order_props_value p ON p.ORDER_ID = o.ID
JOIN b_sale_order_props pr ON pr.ID = p.ORDER_PROPS_ID AND pr.CODE = 'LAST_SOURCE'
WHERE o.DATE_INSERT >= '2026-08-01'
GROUP BY p.VALUE ORDER BY total DESC;

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

Проверяем, что метки доезжают до заказа:

$order = \Bitrix\Sale\Order::load($orderId);
foreach ($order->getPropertyCollection() as $prop) {
printf("%-16s %s\n", $prop->getField('CODE'), $prop->getValue());
}

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

У всех заказов один и тот же источник.

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

Метки теряются при переходе на поддомен.

Кука записана без явного указания домена и потому не видна на поддомене. Домен куки задают явно, с точкой перед основным доменом сайта.

Свойство заказа осталось пустым.

Свойство не заведено в настройках модуля продаж или его код не совпадает. Свойства ищут по символьному коду, а не по числовому идентификатору.

Значение обрезано или сломало запись заказа.

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

В журнале заказа лишние изменения.

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

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

Зачем хранить источник, если есть внешняя аналитика?

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

Что считать источником: первый или последний?

Оба: первый показывает, кто привёл человека, последний - кто довёл до покупки. Хранят обе метки и смотрят по задаче.

Как быть с прямыми заходами?

Оставлять значение пустым и считать это отдельной группой в отчёте. Подставлять «прямой заход» вместо пустого значения удобно, но честнее хранить как есть.

Сколько хранить метку?

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

Нужно ли спрашивать согласие на такие куки?

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

Смежное

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