Налаштування об'єднання даних клієнта з різних каналів 1С-Bitrix
Одна й та ж людина залишає слід в п'яти місцях одночасно: замовляє на сайті, пише в чат Bitrix24, телефонує через телефонію, оформлює покупку на касі та підписується на email-розсилку. У кожному каналі — окремий ідентифікатор. Пов'язати їх в один профіль без втрат — технічне завдання, яке стандартний модуль sale не вирішує з коробки.
Точки входу даних та їх сховища
У типовій інсталяції Bitrix дані клієнта рассередоточені за кількома незалежними таблицями:
-
Вебсайт:
b_user(зареєстровані),b_sale_fuser(аноніми),b_sale_order_props_value(контакти в замовленні) -
CRM Bitrix24:
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
Bitrix24 надає 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 при авторизації
- Адміністративний інтерфейс для ручного розв'язання конфліктів злиття







