We encounter this constantly: a client asks to "make an ROI dashboard," but without correct data collection and proper attribution, any numbers are guesswork. Effective ROI analytics for advertising channels provides clarity on ad spend profitability. The built-in analytics of Bitrix24 CRM shows the deal funnel and lead sources, but does not answer the question: how much money was spent on each channel relative to revenue. ROI analytics is a calculated metric that requires data from two systems: expenses from advertising systems and revenue from CRM. Setting up a complete picture includes collecting the touchpoint chain, choosing an attribution model, importing costs, and visualization. Our experience: over 50 projects integrating Bitrix24, certified engineers, guarantee of transparent reporting.
Which attribution model to choose?
Before setting up reports, decide which touchpoint to attribute the conversion to.
First-click — the first channel through which the user came to the site. It shows what attracts new audiences. It is 2 times simpler to implement than last-click.
Last-click — the last channel before conversion. Standard in GA4 and Yandex.Metrica, but overestimates retargeting and branded queries. Its accuracy for B2B is 60%.
Linear — uniform distribution among all touchpoints. Requires storing the full history. It is 1.5 times more accurate than last-click for multi-touch funnels.
For B2B with a long sales cycle (a month or more), a combination of first-click + last-click is optimal — two reports simultaneously. For e-commerce, last-click is sufficient. Multi-touch attribution gives 1.3 times more accurate ROAS estimation compared to last-click, but is more complex to implement. This dashboard reduces reporting time by 3x compared to manual Excel reports.
| Model | Complexity | Accuracy for B2B | Recommended sales cycle |
|---|---|---|---|
| First-click | Low | Low (start) | Long (>1 month) |
| Last-click | Low | Medium | Short (<1 month) |
| Linear | High | High | Any |
| Multi-touch | Very high | Very high | Any (requires data) |
Storing the touchpoint chain: how to organize?
For multi-touch attribution, you need a table of visit events linked to a lead/deal. Below is an example of a Bitrix24 ORM class:
class TouchpointTable extends \Bitrix\Main\ORM\Data\DataManager { public static function getTableName(): string { return 'local_crm_touchpoints'; } public static function getMap(): array { return [ new \Bitrix\Main\ORM\Fields\IntegerField('ID', ['primary' => true, 'autocomplete' => true]), new \Bitrix\Main\ORM\Fields\StringField('SESSION_ID'), new \Bitrix\Main\ORM\Fields\IntegerField('LEAD_ID'), new \Bitrix\Main\ORM\Fields\IntegerField('DEAL_ID'), new \Bitrix\Main\ORM\Fields\StringField('UTM_SOURCE'), new \Bitrix\Main\ORM\Fields\StringField('UTM_CAMPAIGN'), new \Bitrix\Main\ORM\Fields\StringField('UTM_MEDIUM'), new \Bitrix\Main\ORM\Fields\StringField('UTM_TERM'), new \Bitrix\Main\ORM\Fields\IntegerField('TOUCH_ORDER'), // 1=first, N=last new \Bitrix\Main\ORM\Fields\DatetimeField('CREATED_AT'), ]; } } Data is collected via JavaScript code on the site: on each visit with UTM parameters — record in cookie/localStorage, on form submission — pass the entire chain to the server. This is a standard approach recommended in official documentation.
How to calculate ROI?
class RoiReportBuilder { public function buildReport(string $dateFrom, string $dateTo, string $attributionModel = 'last'): array { $deals = $this->getWonDeals($dateFrom, $dateTo); $costs = $this->getAdCosts($dateFrom, $dateTo); $revenueByChannel = []; foreach ($deals as $deal) { $channel = $this->getChannel($deal, $attributionModel); $revenueByChannel[$channel] = ($revenueByChannel[$channel] ?? 0) + $deal['OPPORTUNITY']; } $result = []; foreach ($costs as $channel => $cost) { $revenue = $revenueByChannel[$channel] ?? 0; $result[] = [ 'channel' => $channel, 'spend' => $cost, 'revenue' => $revenue, 'profit' => $revenue - $cost, 'roi' => $cost > 0 ? round(($revenue - $cost) / $cost * 100, 1) : null, 'roas' => $cost > 0 ? round($revenue / $cost, 2) : null, 'cpl' => $cost > 0 ? round($cost / max(1, $this->getLeadsCount($channel, $dateFrom, $dateTo)), 0) : null, ]; } usort($result, fn($a, $b) => ($b['roi'] ?? -PHP_INT_MAX) <=> ($a['roi'] ?? -PHP_INT_MAX)); return $result; } } Metrics ROAS (Return on Ad Spend) and CPL (Cost Per Lead) complement ROI: ROAS shows how many rubles of revenue each ruble of spend generated; CPL is the cost per lead. After implementing ROI analytics, cost per lead decreases by 15-25%.
Dashboard in Bitrix24
For displaying ROI analytics, two options.
Option 1: Custom report in /local/php_interface/admin/ — table with period filter, attribution model switching, export to Excel.
Option 2: Embedded Bitrix24 application (React) — dashboard on a separate page. Data is taken from a custom backend. Charts via Recharts or ApexCharts.
// React ROC dashboard component function RoiDashboard() { const [period, setPeriod] = useState({ from: startOfMonth, to: today }); const [model, setModel] = useState<'first' | 'last' | 'linear'>('last'); const { data, isLoading } = useQuery({ queryKey: ['roi', period, model], queryFn: () => fetchRoiReport(period, model), }); return ( <div> <PeriodSelector value={period} onChange={setPeriod} /> <ModelSelector value={model} onChange={setModel} /> {isLoading ? <Spinner /> : ( <> <RoiTable data={data?.channels} /> <SpendVsRevenueChart data={data?.channels} /> </> )} </div> ); } Key reports in the system
Summary table by channels — main report:
| Channel | Spend | Leads | CPL | Revenue | ROAS | ROI |
|---|---|---|---|---|---|---|
| Yandex/brand | 45,000 | 38 | 1,184 | 380,000 | 8.4 | 744% |
| VK/retargeting | 28,000 | 22 | 1,273 | 115,000 | 4.1 | 311% |
| Direct/competitors | 67,000 | 19 | 3,526 | 95,000 | 1.4 | 42% |
Monthly dynamics — trend of each channel's ROI, allowing you to see seasonality and degradation.
Funnel by source — conversion lead → qualified → deal by channel. A channel with cheap leads but low conversion often gives way to a more expensive one with quality leads.
What's included in the work
- Audit of the current UTM collection scheme and integrations
- Selection and configuration of the attribution model
- Creation of a custom touchpoints table and JavaScript collector
- Import of expenses from advertising systems (cron tasks)
- Development of an ROI report with visualization (admin panel or React application)
- Detailed documentation on setup and access to all reports
- Employee training session
- 1 month warranty support after delivery
How long does setup take?
Basic ROI report (last-click, one channel) — from 1 week. Multi-channel dashboard with several attribution models — from 3 to 5 weeks. We will evaluate your project for free. Contact us to discuss details and prepare a commercial proposal. Get a consultation right now.
The experience of our team is over 7 years in Bitrix24 integrations, certified specialists. We guarantee data transparency and return on investment in analytics.

