1C-Bitrix Integration with Roistat
Roistat is a business analytics platform that builds end-to-end attribution from an advertising click through to a closed deal and revenue. Integration with 1C-Bitrix enables order and revenue data from an online store to be passed to Roistat, closing the loop of "ad spend → sales revenue." Without this connection, Roistat shows the cost per lead but cannot calculate the actual ROI of advertising channels.
How Roistat Tracking Works on a Bitrix Site
Roistat installs a JavaScript counter on the site that:
- Reads the traffic source from UTM parameters and other GET parameters
- Generates a unique visit identifier — roistat_visit (a numeric value)
- Stores it in the
roistat_visitcookie with a 7-day lifetime (configurable)
When an order is placed, the roistat_visit value from the cookie must be captured in the Bitrix order. This is the critical integration point: Roistat uses roistat_visit to link the order to its advertising source.
Passing roistat_visit to the Order
Add a hidden field to the checkout form, populated by JavaScript:
document.addEventListener('DOMContentLoaded', function() {
var rsVisit = getCookie('roistat_visit');
if (rsVisit) {
document.querySelectorAll('[name="roistat_visit"]').forEach(function(el) {
el.value = rsVisit;
});
}
});
On the Bitrix side, save the value to a custom order field UF_ROISTAT_VISIT. If using the sale.order.ajax component, subscribe to the OnSaleOrderBeforeSaved event:
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'sale', 'OnSaleOrderBeforeSaved',
function (\Bitrix\Main\Event $event) {
$order = $event->getParameter('ENTITY');
$rsVisit = $_REQUEST['roistat_visit'] ?? $_COOKIE['roistat_visit'] ?? '';
if ($rsVisit) {
$order->setField('UF_ROISTAT_VISIT', $rsVisit);
}
}
);
Sending Order Data to Roistat
Roistat accepts order data via API: POST https://cloud.roistat.com/api/v1/project/orders. Header: X-ApiKey: {project_api_key}.
Minimum payload:
{
"orders": [{
"id": "BITRIX_ORDER_123",
"visit": "4521890",
"creation_date": "2026-03-13 10:00:00",
"cost": 4990.00,
"revenue": 4990.00,
"currency": "RUB"
}]
}
The "visit" field is the roistat_visit value. The "cost" field is the order total. Based on this data, Roistat calculates revenue by advertising channel.
Transmit data via the OnSaleStatusOrderChange event handler: when an order transitions to "Paid" or "Fulfilled" status, send the data to Roistat. For order cancellations, send a separate cancellation request.
Order Updates on Status Changes
An order may be placed, then cancelled, then returned to fulfillment. Roistat must receive current statuses:
- New order:
status: "new" - Paid/fulfilled:
status: "confirmed", includerevenue - Cancelled:
status: "canceled", setrevenueto zero
Maintain the Bitrix status → Roistat status mapping in the integration module settings.
Phone Enquiries and Chats
For calls and chats — Roistat replaces the phone number on the site (call tracking). When a call comes in, Roistat automatically creates a lead with roistat_visit. If Bitrix24 is used as the CRM — configure deal transmission from Bitrix24 to Roistat via the Bitrix24 REST API: deal creation event → request to Roistat API with the amount and roistat_visit.
Common Issues
roistat_visit not captured in the order. The most common cause: the checkout form is rendered as an SPA (React component) and the hidden field is added before the Roistat script has loaded. Solution: initialize the field after the roistat:inited event fires.
Duplicate orders in Roistat. If the event handler fires multiple times (on every order change), Roistat receives duplicates. Use the order id as an idempotency key — re-sending with the same id updates rather than duplicates.
Estimated Timelines
| Task | Timeline |
|---|---|
| Basic integration: sending orders to Roistat | 3–5 days |
| + Status updates (payment, cancellation, refund) | +2–3 days |
| + Bitrix24 CRM integration with deals | +3–5 days |
Pricing is calculated individually after auditing the current tracking setup and order processing flow.







