Analytics and Reporting for 1C-Bitrix
Why 90% of Tracking Codes on Bitrix Sites Lie
You install a Metrica counter, connect GA4, add pixels — analytics seems to be in place. Then you look closer: e-commerce conversion isn't being sent, UTM tags get stripped on redirects, CRM leads have no source. The typical picture — the marketer looks at one report, the commercial director at another, the numbers don't match, and everyone makes decisions based on gut feeling.
We set up analytics on 1C-Bitrix projects — from correct dataLayer implementation to end-to-end analytics with ROI per campaign.
Yandex.Metrica: More Than Just a Counter
Basic Setup — and Why It's Usually Done Wrong
Everyone installs a Metrica counter. Few do it correctly.
- Installation via GTM, not by pasting into
header.php— otherwise the counter breaks when the template is updated - Goals: not abstract "button clicks," but specific ones —
basket_add, form submissionbx_form_submit, navigation to/personal/order/make/ - Webvisor — you enable it, but it records only 1% of sessions because sampling is on by default. You need to explicitly set the recording percentage and don't forget about GDPR compliance
- Internal traffic filtering — without this, office traffic adds 15–20% junk visits. We filter by IP, by cookie
_ym_debug, by headers
E-commerce — the Most Underrated Feature
The eCommerce module in Metrica transmits the complete buyer behavior chain. The problem is that in Bitrix, out of the box, it only works with the sale.order.ajax component — and even then poorly, losing remove_from_cart during AJAX cart updates.
What we push to dataLayer:
-
Product view —
id,name,brand,category,price. Without brand, Metrica can't build brand reports; without category — category reports. Obvious, but often forgotten -
Add to cart — we catch the
onBXAddToBasketevent via JS, not through the server-sideOnSaleBasketItemAddhandler. The server handler has no JS context -
Remove from cart — here's the trap: the standard
sale.basket.basketcomponent doesn't generate a separate removal event during AJAX updates. You need a custom observer -
Purchase — we send on
sale/order/complete/, including coupon and revenue with discounts applied
Data Sent to Metrica
| Parameter | Source | Pitfalls |
|---|---|---|
| Product ID | PRODUCT_ID from infoblock |
Don't confuse with trade offer ID — these are different entities |
| Category | Infoblock section chain | Metrica expects the format "Electronics/Smartphones", separator — / |
| Brand | Infoblock property | If it's a Highload reference — requires an additional query |
| Price | CATALOG_PRICE_1 or counterparty price type |
Send the final price, after discounts |
| Coupon | CSaleBasket::GetList → DISCOUNT_COUPON |
Can be empty — don't break the dataLayer |
GA4: Event-Based Model and Its Pitfalls
Why GA4 Is a Different Beast
GA4 is event-based, not hit-based. There are no "page views" in the traditional sense — page_view is just one of many events. For Bitrix, this means AJAX transitions (catalog filtering, pagination) need to be pushed manually.
Key e-commerce events:
view_item_list → select_item → view_item → add_to_cart → view_cart → begin_checkout → add_shipping_info → add_payment_info → purchase
Each event requires its own set of parameters. purchase without transaction_id won't be counted. add_to_cart without the items array is useless. GA4 silently swallows invalid data and shows empty reports. No console errors whatsoever.
Custom Parameters That Actually Matter
Don't send everything. Five parameters that deliver 80% of the value:
-
user_type —
guest/registered/wholesale. Behavior and conversion differ dramatically - user_group — user group from Bitrix. Enables segmentation by retail vs wholesale
- order_count — total number of user orders. First order and twentieth — different funnels
- cumulative_discount — accumulated discount. Affects average order value
-
first_source — UTM of the first visit. Stored in a cookie or in the user's
UF_SOURCEfield
End-to-End Analytics: Where's the Money
Metrica sees visits. CRM sees deals. The ad dashboard sees spend. But the connection between them is broken. A manager closed a 500K deal, but Metrica shows the source as (direct) because the client came via a bookmark, while the first contact was through paid search three months ago.
End-to-end analytics closes the loop: ad click → visit → CRM lead → deal → payment → ROI.
How We Build It
- UTM tags are stored in a cookie with a 90-day TTL and duplicated in
roistat_visit - When a lead is created in Bitrix24, UTMs are written to custom deal fields —
UF_CRM_UTM_SOURCE,UF_CRM_UTM_MEDIUM,UF_CRM_UTM_CAMPAIGN - Call tracking swaps the phone number and ties the call to the visit
- The manager moves the deal through the pipeline, closes it — the amount is tied to the source
- Roistat (or Calltouch, CoMagic) aggregates ad spend via advertising platform APIs
- ROI = (revenue - spend) / spend. Per campaign, ad group, keyword
Tools
| Platform | Strength | Weakness |
|---|---|---|
| Roistat | Multi-channel attribution, call tracking, Bitrix24 integration | Price — from 8K RUB/month |
| Calltouch | Best call tracking on the market | End-to-end analytics weaker than Roistat |
| CoMagic (UIS) | Calls + chat + analytics bundle | Interface from 2015 |
| Bitrix24 CRM Analytics | Free, built into CRM | No ad spend tracking, no call tracking |
Dashboards: Three Screens Instead of Ten Reports
We build dashboards in DataLens or Looker Studio. The key principle — don't overload. A director won't dig through 40 charts.
Director dashboard — revenue, order count, average order value, period-over-period comparison. Five widgets, hourly refresh.
Marketer dashboard — traffic by channel, CAC, campaign ROI, funnel conversion, promo code performance. Can go deeper — marketers know how to read data.
Commercial dashboard — manager conversion rates, order processing speed, repeat purchases. Here DataLens connects directly to Bitrix's PostgreSQL/MySQL via b_sale_order and b_sale_basket.
Funnel: Where Exactly Is the Leak
Typical Bitrix store funnel:
| Stage | What to measure | Where the problem usually is |
|---|---|---|
| Catalog → Product | Product CTR | Poor photos, no price in listing |
| Product → Cart | Add-to-cart rate | No "Buy" button above the fold |
| Cart → Checkout | Checkout initiation | Unexpected shipping cost |
| Checkout → Order | Completion rate | Mandatory registration, sale.order.ajax crashing |
A checkout drop-off is the most expensive. The user already wanted to buy, already added to cart, and then sale.order.ajax throws a 500 because the shipping handler isn't configured. Or the form requires a tax ID from an individual. Each such case — direct revenue loss.
Cohort Analysis and LTV
We group by first purchase month and track retention at 30, 60, 90 days. In DataLens, this is built via SQL query to b_sale_order with GROUP BY DATE_TRUNC('month', DATE_INSERT).
The key cohort analysis insight — which channel attracts high-LTV customers, not just cheap ones. Paid search may deliver cheap first orders but zero repeat rate. While SEO traffic converts worse initially but comes back.
Timelines
| Task | Timeline |
|---|---|
| Metrica + eCommerce (with correct dataLayer) | 3–5 days |
| GA4 + Enhanced E-commerce | 3–5 days |
| End-to-end analytics (Roistat/Calltouch + CRM) | 2–4 weeks |
| Dashboards in DataLens/Looker Studio | 1–2 weeks |
| Comprehensive system | 4–8 weeks |
Analytics on Bitrix is not "install a counter and forget." The dataLayer breaks after a sale module update, UTM tags get lost on SEF URL redirects, GA4 changes event formats. The system needs ongoing maintenance — and we handle that.







