Integration of 1C-Bitrix with Retail Rocket
Retail Rocket is a personalization platform for e-commerce: product recommendations, personalized email campaigns, behavioral analytics. Technical integration consists of two parts: transmitting user behavior data via JavaScript tracker and syncing product catalog via XML feed.
Product XML Feed
Retail Rocket accepts product feeds in Yandex.Market YML format or in its own XML format. Simplest is to use already-generated Bitrix YML feed — if it exists for Yandex.Market, it works for Retail Rocket too.
If separate feed is needed (with extra fields for segmentation), generate via component or agent:
// Minimal structure for Retail Rocket
function generateRetailRocketFeed(): string
{
$xml = '<?xml version="1.0" encoding="UTF-8"?><yml_catalog>';
$xml .= '<shop><name>' . htmlspecialchars(SITE_NAME) . '</name>';
$xml .= '<url>https://' . SITE_SERVER_NAME . '</url>';
$xml .= '<currencies><currency id="RUB" rate="1"/></currencies>';
$xml .= '<categories>';
// Categories
$sections = CIBlockSection::GetList(
['LEFT_MARGIN' => 'ASC'],
['IBLOCK_ID' => CATALOG_IBLOCK_ID, 'ACTIVE' => 'Y'],
false,
['ID', 'NAME', 'IBLOCK_SECTION_ID']
);
while ($section = $sections->GetNext()) {
$parentAttr = $section['IBLOCK_SECTION_ID']
? ' parentId="' . $section['IBLOCK_SECTION_ID'] . '"'
: '';
$xml .= '<category id="' . $section['ID'] . '"' . $parentAttr . '>'
. htmlspecialchars($section['NAME']) . '</category>';
}
$xml .= '</categories>';
$xml .= '<offers>';
// Products
$res = CIBlockElement::GetList(
[],
['IBLOCK_ID' => CATALOG_IBLOCK_ID, 'ACTIVE' => 'Y'],
false,
false,
['ID', 'NAME', 'DETAIL_PAGE_URL', 'PREVIEW_PICTURE', 'DETAIL_PICTURE',
'PREVIEW_TEXT', 'IBLOCK_SECTION_ID']
);
while ($el = $res->GetNextElement()) {
$fields = $el->GetFields();
$props = $el->GetProperties();
$price = CCatalogProduct::GetOptimalPrice($fields['ID']);
$priceVal = $price['PRICE']['PRICE'] ?? 0;
$imgId = $fields['DETAIL_PICTURE'] ?: $fields['PREVIEW_PICTURE'];
$imgUrl = '';
if ($imgId) {
$imgUrl = 'https://' . SITE_SERVER_NAME . CFile::GetPath($imgId);
}
$url = 'https://' . SITE_SERVER_NAME . $fields['DETAIL_PAGE_URL'];
$xml .= '<offer id="' . $fields['ID'] . '" available="true">';
$xml .= '<url>' . htmlspecialchars($url) . '</url>';
$xml .= '<price>' . number_format($priceVal, 2, '.', '') . '</price>';
$xml .= '<currencyId>RUB</currencyId>';
$xml .= '<categoryId>' . $fields['IBLOCK_SECTION_ID'] . '</categoryId>';
if ($imgUrl) {
$xml .= '<picture>' . htmlspecialchars($imgUrl) . '</picture>';
}
$xml .= '<name>' . htmlspecialchars($fields['NAME']) . '</name>';
if ($fields['PREVIEW_TEXT']) {
$xml .= '<description><![CDATA['
. strip_tags($fields['PREVIEW_TEXT']) . ']]></description>';
}
// SKU for linking with orders
$sku = $props['CML2_ARTICLE']['VALUE'] ?? $fields['ID'];
$xml .= '<param name="sku">' . htmlspecialchars($sku) . '</param>';
$xml .= '</offer>';
}
$xml .= '</offers></shop></yml_catalog>';
return $xml;
}
Feed is cached for 2–4 hours and updated via invalidation on product changes. Feed URL is provided in Retail Rocket dashboard.
JavaScript Tracker: Events
Retail Rocket provides JS library (rrpushdown), connected to all pages. In Bitrix template — in footer.php or via addExternalJs:
// Basic Retail Rocket code (inserted once)
var retailrocket = window.retailrocket || [];
(function(d, w) {
var rr = d.createElement('script');
rr.type = 'text/javascript';
rr.src = '//cdn.retailrocket.net/content/javascript/tracking.js';
d.head.appendChild(rr);
})(document, window);
Product view event. In catalog.element template:
// template.php
$productId = $arResult['ID'];
?>
<script>
retailrocket.push(['setAccountId', '<?= RETAIL_ROCKET_ACCOUNT_ID ?>']);
retailrocket.push(['track', 'view', { productId: '<?= $productId ?>' }]);
</script>
Add to cart event. In AJAX add handler:
// On successful product add to cart
retailrocket.push(['track', 'addToBasket', {
productId: String(productId),
quantity: qty
}]);
Order completion event. In "Thank you for order" template or via OnSaleOrderSaved handler:
// In order confirmation template
$orderId = $arOrder['ID'];
$orderPrice = $arOrder['PRICE'];
$items = []; // Array of order items
foreach ($arOrder['BASKET'] as $item) {
$items[] = [
'id' => $item['PRODUCT_ID'],
'qnt' => $item['QUANTITY'],
'price' => $item['PRICE'],
];
}
?>
<script>
retailrocket.push(['track', 'transaction', {
transaction: '<?= $orderId ?>',
revenue: <?= $orderPrice ?>,
lineItems: <?= json_encode($items) ?>
}]);
</script>
Search event:
retailrocket.push(['track', 'search', { searchPhrase: searchQuery }]);
Recommendation Blocks
Retail Rocket provides ready-made widgets with recommendations. After setup in dashboard — insert blocks in templates:
<!-- Home page: "We recommend" -->
<div data-retailrocket-markup-block="5f4a3b2c1d0e9f8e7d6c5b4a"
data-algorithm="popular">
</div>
<!-- Product card: "Also buy" -->
<div data-retailrocket-markup-block="5f4a3b2c1d0e9f8e7d6c5b4b"
data-algorithm="related"
data-item-id="<?= $arResult['ID'] ?>">
</div>
<!-- Cart: "You might like" -->
<div data-retailrocket-markup-block="5f4a3b2c1d0e9f8e7d6c5b4c"
data-algorithm="basket">
</div>
Widgets render on Retail Rocket side — they load list of product IDs and request display data from your catalog via JS.
User and Authorization
To link behavior with user profile, send email on login:
// In successful auth handler
if ($USER->IsAuthorized()) {
$email = $USER->GetEmail();
?>
<script>
retailrocket.push(['setEmail', '<?= htmlspecialchars($email) ?>',
function() { console.log('RR email set'); }
]);
</script>
<?php } ?>
Implementation Timeline
| Scope | Components | Timeline |
|---|---|---|
| Basic integration (feed + tracker) | Feed + 3 events + script | 1–2 days |
| Full integration (all events + recommendation blocks) | + widgets + email event + A/B test | 3–5 days |
| Personalized campaigns | + trigger scenarios via Retail Rocket Email | add 2–3 days |







