Налаштування єдиного профілю клієнта в 1С-Bitrix
Клієнт розміщує замовлення на сайті під одним email, потім телефонує в call-центр і називає інший номер телефону, потім входить з мобільного додатку як гість. У результаті в базі три різних «клієнти», а менеджер не бачить повної історії. Це класична проблема дублювання профілів, яку вирішує єдиний профіль клієнта — Customer Data Profile — у зв'язці з модулем sale та CRM Bitrix24.
Як зберігаються дані користувача в Bitrix
Ядро працює з двома незалежними сутностями: користувач (b_user) та покупець (b_sale_person_type + b_sale_order_user). При розміщенні анонімного замовлення створюється запис в b_sale_order з USER_ID = 0 та контактними даними в полях b_sale_order_props_value. При реєстрації чи авторизації замовлення прив'язуються до конкретного USER_ID, але зв'язок «гостьовські замовлення → зареєстрований користувач» не будується автоматично.
Крім того, якщо на проекті підключено модуль crm, кожне замовлення через подію OnSaleOrderSaved створює або оновлює сутність CCrmContact та CCrmDeal. Дублювання на рівні b_user негайно порождає дублювання контактів у CRM.
Механізм злиття профілів
Єдиний профіль будується через три компоненти:
1. Ідентифікація за детермінованими полями. Email та телефон — основні ключі злиття. У таблиці b_user поля EMAIL та PERSONAL_PHONE мають бути унікальними (індекс UQ_USER_EMAIL). Проблема в тому, що за замовчуванням Bitrix не забороняє двом користувачам мати однаковий телефон, якщо той зберігається в користувацьких властивостях через b_user_field.
2. Злиття через API користувачів. При виявленні дублю викликається CUser::Merge() — метод переносить усі замовлення, підписки, бонусні бали на основний облік та дезактивує дубль. Важливо попередньо перевірити залежні таблиці: b_sale_order, b_sale_fuser, b_rating_vote, b_forum_user, b_subscribe_subscriber.
// Злиття: усі дані дублю переходять до основного користувача
$result = CUser::Merge($masterUserId, $duplicateUserId);
if (!$result) {
// Логування причини — найчастіше конфлікт поля UNIQUE в b_user
$GLOBALS['APPLICATION']->GetException();
}
3. Таблиця b_sale_fuser (fake user). Це ключова таблиця для анонімних сесій. Кожний гість отримує запис в b_sale_fuser з USER_ID = NULL. При вході метод CSaleUser::DoAutoLogin() має прив'язати FUSER_ID до справжнього USER_ID. Якщо цей крок пропущено — кошик та незавершені замовлення залишаються «підвішеними» і не потрапляють у профіль.
Користувацькі поля як джерело проблем
Додаткові атрибути клієнта (дата народження, стать, переваги) зберігаються в b_uts_user — автоматично створюваній таблиці для користувацьких полів (UserTypeEntity з ENTITY_ID = 'USER'). При злитті через CUser::Merge() ці дані не переносяться автоматично — метод копіює тільки поля основної таблиці b_user. Необхідно вручну перенести значення з b_uts_user перед викликом злиття.
Прив'язка гостьовських дій після авторизації
Стандартний обробник OnAfterUserAuthorize спрацьовує при кожному вході. В ньому зручно реалізувати:
AddEventHandler('main', 'OnAfterUserAuthorize', function($fields) {
if ($fields['USER_ID'] > 0) {
// Переносимо кошик гостя на авторизованого користувача
$fuserId = CSaleUser::GetAnonymousUserID();
CSaleBasket::TransferBasket($fuserId, $fields['USER_ID']);
// Прив'язуємо історію переглядів (b_catalog_viewed)
// Переносимо відкладені товари (b_sale_basket з LID = 'Y')
}
});
Що ми налаштовуємо
- Аудит таблиці
b_userна дублі за email та телефоном з пошуком черезGROUP BY+HAVING COUNT(*) > 1 - Скрипт дедупліцирації з пріоритизацією основного облику (за датою реєстрації чи кількістю замовлень)
- Перенос даних з
b_uts_user,b_sale_order,b_sale_fuserпри злитті - Обробник
OnAfterUserAuthorizeдля прив'язування гостьовських дій до профілю - Налаштування унікальних індексів на телефон, якщо він зберігається в
b_user_field - Інтеграція з CRM: дедупліцирація
CCrmContactзаPHONEчерезCCrmContactHelper::FindDuplicate()







