Configuring Bidirectional Synchronization Between 1C and 1C-Bitrix
Bidirectional synchronization is technically the most complex exchange scheme: changes in either system must reach the other without data loss and without version conflicts. Standard CommerceML partially addresses this (catalog from 1C + orders to 1C), but a fully bidirectional exchange requires clearly defined priority rules.
Priority Rules — the Foundation of Bidirectional Exchange
Answer these questions before starting development:
| Field | Master system | Rationale |
|---|---|---|
| Price | 1C | Financial accounting is in 1C |
| Stocks | 1C | Warehouse accounting is in 1C |
| Product description | Site | SEO content is written on the site |
| Product photo | Site | Photos are uploaded to the site media library |
| Order status | 1C | Order fulfillment happens in 1C |
| Delivery address | Site | The buyer enters it on the site |
| Buyer details | 1C | Legally significant data is in 1C |
Violating these rules leads to data "flickering": 1C overwrites the description → an editor corrects it → 1C overwrites it again.
Implementation via Event Handlers
On the site side — controlling fields during import from 1C:
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'iblock',
'OnIBlockElementBeforeUpdate',
function(\Bitrix\Main\Event $event) {
$fields = $event->getParameter('fields');
$elementId = $event->getParameter('id');
// Get the list of protected fields for this element
$protected = getProtectedFields($elementId);
foreach ($protected as $fieldCode) {
unset($fields[$fieldCode]);
}
return new \Bitrix\Main\EventResult(
\Bitrix\Main\EventResult::SUCCESS,
['fields' => $fields]
);
}
);
Conflict Detection
A version conflict occurs when the same field has changed in both systems between exchange sessions. Detection via the timestamp of the last change:
// Store the time of the last site-side update in an additional element field
$lastSiteUpdate = $element['UF_LAST_SITE_UPDATE']; // timestamp
$lastExchangeUpdate = $element['UF_LAST_EXCHANGE_UPDATE']; // timestamp from 1C
if ($lastSiteUpdate > $lastExchangeUpdate) {
// Field was changed on the site after the last exchange — do not overwrite
}
Case Study: Bidirectional Synchronization for a Distributor
A distribution company with 15,000 SKUs. 1C manages prices and stocks; the site manages descriptions and SEO. Twice a year — a repricing in 1C: prices change on 80% of the assortment. Before bidirectional exchange was configured, repricing would update prices but simultaneously overwrite SEO descriptions written by copywriters.
Solution: the DETAIL_TEXT field was added to the "protected list" via the custom property UF_PROTECT_DESCRIPTION. During exchange, the handler checks the flag and skips overwriting the description while applying the price update. After deployment — zero cases of SEO content loss over 8 months of operation.
Image Synchronization
Images are a separate challenge in bidirectional exchange. If 1C transmits images via CommerceML (<Картинки>) and the site has an additional gallery with retouched photos:
- Main image (
PREVIEW_PICTURE) — protect if a "processed by photographer" flag is present - Additional images from 1C — add them, but do not delete site photos
Setup Timeline
| Task | Duration |
|---|---|
| Bidirectional exchange with priority rules | 2–4 days |
| + version conflict detection | +1–2 days |
| + bidirectional user synchronization | +1–2 days |







