Настройка объединения данных клиента из разных каналов 1С-Битрикс
Один и тот же человек оставляет след в пяти местах одновременно: заказывает на сайте, пишет в чат Битрикс24, звонит через телефонию, оформляет покупку на кассе и подписывается на email-рассылку. В каждом канале — отдельный идентификатор. Связать их в один профиль без потерь — техническая задача, которую стандартный модуль sale не решает из коробки.
Точки входа данных и их хранилища
В типовой инсталляции Битрикс данные клиента рассредоточены по нескольким независимым таблицам:
-
Веб-сайт:
b_user(зарегистрированные),b_sale_fuser(анонимы),b_sale_order_props_value(контакты в заказе) -
CRM Битрикс24:
b_crm_contact,b_crm_contact_phone,b_crm_contact_email— отдельные таблицы для мультизначных полей -
Email-рассылки:
b_subscribe_subscriberс привязкой кUSER_IDили просто к адресу без авторизации -
Телефония:
b_voximplant_callс полемCALLER_ID— номер телефона без связи сb_user -
Оффлайн-касса: данные приходят через обмен 1С в
b_iblock_element(если используется каталог) или во внешнюю таблицу через собственный модуль
Сопоставление по ключам идентификации
Объединение строится на цепочке детерминированных ключей. Основные: email, нормализованный номер телефона, cookie BITRIX_SM_SALE_UID (это и есть FUSER_ID), идентификатор мобильного устройства из b_push_sender_subscription.
Нормализация телефона — обязательный шаг. В b_crm_contact_phone номера хранятся в формате +7XXXXXXXXXX, в b_sale_order_props_value — в произвольном виде («8 (495) 123-45-67»). Для сопоставления нужна функция приведения к E.164:
function normalizePhone(string $phone): string {
$digits = preg_replace('/\D/', '', $phone);
if (strlen($digits) === 11 && $digits[0] === '8') {
$digits[0] = '7';
}
return '+' . $digits;
}
Граф идентификаторов
Эффективная архитектура объединения — таблица соответствий (identity graph). На уровне БД это отдельная таблица, например bl_customer_identity:
CREATE TABLE bl_customer_identity (
id SERIAL PRIMARY KEY,
master_uid INT NOT NULL, -- ID мастер-профиля в b_user
channel VARCHAR(50) NOT NULL, -- 'web', 'crm', 'voip', 'pos', 'email'
ext_id VARCHAR(255) NOT NULL, -- идентификатор в канале
created_at TIMESTAMP DEFAULT NOW(),
UNIQUE (channel, ext_id)
);
При каждом событии в любом канале (новый заказ, звонок, подписка) система ищет запись по (channel, ext_id). Если найдена — привязывает к существующему master_uid. Если нет — проверяет пересечения по другим ключам через b_crm_contact_phone и b_user.EMAIL, и только при полном отсутствии создаёт новый мастер-профиль.
Интеграция с модулем CRM
Битрикс24 предоставляет API для поиска дублей: CCrmContact::GetList() с фильтром по телефону. Метод CCrmContactHelper::FindDuplicate() ищет совпадения среди контактов и лидов. Однако он работает только внутри CRM и не затрагивает b_user.
Для двустороннего связывания: в b_crm_contact есть поле UF_CRM_WEB_USER_ID (пользовательское поле, его нужно создать через CUserTypeEntity::Add()). Заполнять его при каждом успешном сопоставлении — и обратный поиск «контакт → пользователь сайта» становится O(1) по индексу.
Обработка конфликтов при слиянии
Самый болезненный сценарий: два профиля с разными email, но один телефон — и оба с историей заказов. Нужна стратегия выбора мастер-записи. Рабочий подход: мастер = профиль с наибольшей суммой заказов в b_sale_order. Все остальные записи — alias, данные которых переносятся в мастер, а сами аккаунты деактивируются (ACTIVE = 'N' в b_user).
Что настраиваем
- Аудит существующих каналов и точек входа данных в системе
- Создание таблицы
bl_customer_identityи логики её наполнения - Функцию нормализации телефона и email для всех каналов
- Обработчики событий:
OnSaleOrderSaved,OnCrmContactAdd,OnVoximplantCallEnd - API-endpoint для мобильного приложения, передающего device ID при авторизации
- Административный интерфейс для ручного разрешения конфликтов слияния







