Setting up omnichannel customer analytics in 1C-Bitrix
A customer came from Instagram, put an item in the cart from a phone, paid from a laptop, and then called support. These are four touchpoints across three channels — and in Bitrix's standard report they will be scattered. Omnichannel analytics stitches these contacts into a single customer journey. The task is technically non-trivial: you need to link multiple user identifiers from different subsystems.
Customer identifiers in Bitrix
Each subsystem uses its own key:
| Subsystem | Identifier | Table |
|---|---|---|
| Website (authorized) | USER_ID |
b_user |
| Website (anonymous) | FUSER_ID |
b_sale_fuser |
| CRM | CONTACT_ID / LEAD_ID |
b_crm_contact |
| Telephony | PHONE |
b_crm_contact_detail |
EMAIL |
b_user / b_crm_contact_detail |
The connection between FUSER_ID and USER_ID is established during login: USER_ID appears in b_sale_fuser. CRM contact is linked to the website user via the UF_SITE_MEMBER_ID field (if the connection is configured) or by email match.
Building a unified customer profile
A unified profile is a summary record that aggregates all touchpoints. One approach is to create a custom table bl_customer_profile with fields:
customer_uuid — generated customer UUID
user_id — ID from b_user (NULL for pure anonyms)
fuser_ids — jsonb array of all FUSER_ID
crm_contact_id — CRM contact ID
email — normalized email
phone — normalized phone
first_seen — date of first contact
last_seen — date of last contact
channels — jsonb set of channels with dates
Merge occurs by rule: if email or phone matches — it's one customer. Merge is launched by an agent or trigger on each new contact.
Data collection by channel
Web sessions — events OnBeforeUserLogin and OnAfterUserAuthorize capture UTM parameters from $_GET and save the source in user fields b_uts_user or in bl_customer_profile.
CRM activities — the crm module writes activities to b_crm_activity. On incoming call, email or chat, a record is created with OWNER_ID (contact or lead) and TYPE_ID. You can link an activity to a customer profile via OWNER_ID → b_crm_contact → email/phone.
Email lists — if the subscribe module is used, opens and clicks are recorded in b_subscribe_log. For external ESPs (SendPulse, UniSender), you need a webhook that writes events to a custom table bl_email_events.
Analytical queries
After stitching data together, you can build reports on customer journeys. Example — number of orders by first acquisition source:
SELECT cp.first_channel, COUNT(DISTINCT o.ID) AS orders
FROM bl_customer_profile cp
JOIN b_sale_order o ON o.USER_ID = cp.user_id
WHERE o.CANCELED = 'N'
GROUP BY cp.first_channel
ORDER BY orders DESC;
For real-time analytics, results are aggregated hourly by an agent into bl_omni_stats table.
What we configure
- Table
bl_customer_profilewith merge mechanism for duplicates by email/phone - Event handlers for login to capture UTM parameters and channel
- Synchronization agent for CRM contacts with site profiles via
\Bitrix\Crm\ContactTableAPI - Dashboard in admin section with report by channels and conversion by sources







