Источник заказа - метки в адресе, хранение, отчёт
Узнаём, откуда пришёл заказ: перехват меток в адресе, хранение между визитами, запись в свойство заказа и простой отчёт по источникам.
Что нужно знать заранее
Метки источника приходят в адресе первой страницы визита. Дальше посетитель ходит по сайту без них, поэтому значение надо перехватить сразу и сохранить на своей стороне.
Источников у одного заказа обычно два: первый и последний по времени. Первый привёл человека на сайт, последний привёл к покупке, и в отчётах их считают отдельно друг от друга.
В заказ метки попадают свойством заказа, а не сами по себе. Свойство заводят заранее в настройках модуля продаж, иначе записывать значение будет попросту некуда.
Шаги
- Завести свойства заказа под первый и последний источник самого посетителя.
- Перехватывать метки на любой странице сайта и складывать их в куку посетителя.
- Записывать значения в заказ на событии оформления, ещё до его сохранения.
- Ограничить длину значения и вычищать из него лишние служебные символы.
- Построить отчёт по свойству заказа обычной выборкой с группировкой по источнику.
Решение
Перехватываем метки на входе:
// /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 totalFROM b_sale_order oJOIN b_sale_order_props_value p ON p.ORDER_ID = o.IDJOIN 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());}Типичные проблемы
У всех заказов один и тот же источник.
Записывается последний источник, а первый вообще не сохраняется. Заводят две куки: одну на первый визит, другую на каждый визит с метками.
Метки теряются при переходе на поддомен.
Кука записана без явного указания домена и потому не видна на поддомене. Домен куки задают явно, с точкой перед основным доменом сайта.
Свойство заказа осталось пустым.
Свойство не заведено в настройках модуля продаж или его код не совпадает. Свойства ищут по символьному коду, а не по числовому идентификатору.
Значение обрезано или сломало запись заказа.
В метке пришла очень длинная строка со служебными символами внутри. Длину значения ограничивают и вычищают лишние символы прямо при перехвате.
В журнале заказа лишние изменения.
Свойства пишутся после сохранения и вызывают повторное сохранение всего заказа. Значения свойств ставят до сохранения, в обработчике перед самой записью.
Частые вопросы
Зачем хранить источник, если есть внешняя аналитика?
Свои данные лежат рядом с заказами и сверяются с бухгалтерией. Внешняя аналитика теряет часть визитов из-за блокировщиков и не знает отменённых заказов.
Что считать источником: первый или последний?
Оба: первый показывает, кто привёл человека, последний - кто довёл до покупки. Хранят обе метки и смотрят по задаче.
Как быть с прямыми заходами?
Оставлять значение пустым и считать это отдельной группой в отчёте. Подставлять «прямой заход» вместо пустого значения удобно, но честнее хранить как есть.
Сколько хранить метку?
Первый источник - год, последний - месяц: дольше значения теряют смысл. Сроки задают в куках при записи.
Нужно ли спрашивать согласие на такие куки?
Правила по стране и по типу данных различаются, и это вопрос юриста проекта. Технически метки хранят рядом с остальными служебными куками сайта.
Смежное
- Заказы и статусы - оглавление подтемы
- Отчёты по заказам: агрегаты, группировка, выгрузка - как считают такие отчёты
- Свойства заказа: чтение, запись и фильтрация по значению - куда попадает значение метки
- Электронная торговля в аналитике: события, покупка, сверка - внешняя аналитика и её данные
- Состояние посетителя в куках: запись, чтение, защищённая кука - как правильно писать куки
- События оформления заказа: свои проверки, запрет и допданные - куда встроить запись значений
- Каталог и продажи - устройство магазина целиком