Налаштування синхронізації замовлень онлайн і офлайн 1С-Бітрікс
У роздрібній мережі замовлення надходять із трьох місць: інтернет-магазин, POS-термінали в точках і дзвінки операторам. Без синхронізації — три ізольованих потоки, одні й ті самі залишки резервуються тричі, менеджер в офісі не бачить онлайн-замовлення, кур'єр везе товар, якого вже немає в наявності. Синхронізація онлайн/офлайн у Бітрікс — це передусім робота з b_sale_order, складськими залишками і каналом передачі даних у 1С або іншу облікову систему.
Архітектура потоків замовлень
Центральна система обліку визначає всю логіку. Типові варіанти:
1С як мастер — 1С є джерелом правди по замовленнях і залишках. Бітрікс передає онлайн-замовлення в 1С, офлайн-продажі фіксуються там само, залишки синхронізуються назад.
Бітрікс як мастер — всі замовлення (онлайн і офлайн через POS) збираються в Бітрікс, 1С отримує дані для бухгалтерії.
Гібридна схема, де немає чіткого мастера — джерело хаосу. Вибір робиться до початку розробки.
Синхронізація через CommerceML
Стандартний обмін 1С-Бітрікс (/bitrix/admin/1c_exchange.php) покриває базовий сценарій: замовлення з Бітрікс йдуть у 1С, статуси повертаються назад. Налаштування в модулі sale:
Адміністрування → Інтернет-магазин → Налаштування → Вкладка «1С»
Обмеження: стандартний обмін — пакетний, раз на N хвилин. Для синхронізації в реальному часі потрібні вебхуки або черги.
Офлайн-замовлення: як передати в Бітрікс із POS
Коли касир оформлює продаж через POS (Еватор, 1С:Роздрібна торгівля), потрібно або:
- Створити замовлення в Бітрікс через API і одразу позначити його оплаченим
- Або лише списати залишки без створення замовлення (якщо офлайн-продажі не потрібні в історії інтернет-магазину)
Створення замовлення через Bitrix REST API (/rest/v1/sale.order.add) або через PHP:
// Створення офлайн-замовлення в Бітрікс
\Bitrix\Main\Loader::includeModule('sale');
\Bitrix\Main\Loader::includeModule('catalog');
$order = \Bitrix\Sale\Order::create(SITE_ID, $userId);
$order->setField('CURRENCY', 'RUB');
$order->setField('USER_DESCRIPTION', 'Продаж у магазині: ' . $storeName);
$basket = \Bitrix\Sale\Basket::create(SITE_ID);
foreach ($items as $item) {
$basketItem = $basket->createItem('catalog', $item['PRODUCT_ID']);
$basketItem->setFields([
'QUANTITY' => $item['QUANTITY'],
'CURRENCY' => 'RUB',
'LID' => SITE_ID,
'PRODUCT_PROVIDER_CLASS' => '\CCatalogProductProvider',
]);
}
$order->setBasket($basket);
// Позначаємо джерело замовлення
$order->setField('STATUS_ID', 'F'); // Виконано — офлайн-продаж завершено
$order->setField('ADDITIONAL_INFO', json_encode([
'source' => 'offline',
'store' => $storeId,
'pos_transaction_id' => $transactionId,
]));
$result = $order->save();
Резервування залишків при онлайн-замовленні
Критична точка: коли резервувати товар під онлайн-замовлення? При додаванні до кошика — резервуємо надто рано (багато покинутих кошиків). При оплаті — ризик продати те, що вже розібрали в магазині.
Бітрікс керує резервами через b_catalog_store_product і b_sale_product_reserve:
// Резервування товару в момент оформлення замовлення
\Bitrix\Catalog\StoreProductTable::reserveProduct(
$productId,
$storeId,
$quantity,
$orderId
);
// Зняття резерву при скасуванні
\Bitrix\Catalog\StoreProductTable::releaseProductReserve(
$productId,
$orderId
);
Для Click & Collect логіка відрізняється: резервуємо на конкретному складі (точці самовивозу), не в загальному пулі.
Синхронізація залишків у реальному часі
Зміна залишків на будь-якій стороні (онлайн-замовлення, POS-продаж, прихід від постачальника) повинна миттєво відображатися скрізь. Для цього — черга подій:
// При зміні залишків — додаємо до черги
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'catalog', 'OnProductUpdate',
function (\Bitrix\Main\Event $event) {
$productId = $event->getParameter('ID');
$fields = $event->getParameter('FIELDS');
if (isset($fields['QUANTITY'])) {
// Ставимо до черги синхронізації з 1С
\Local\Queue\InventorySync::push([
'product_id' => $productId,
'quantity' => $fields['QUANTITY'],
'timestamp' => time(),
]);
}
}
);
Черга обробляється агентом Бітрікс або воркером (supervisor + PHP-скрипт), який пакетно надсилає зміни в 1С або іншу систему обліку.
Конфлікти: одночасні продажі
Залишок = 1, одночасно оформлюється онлайн-замовлення і продаж через POS. Обидва потоки бачать залишок = 1 і приймають замовлення. Рішення — оптимістичне блокування на рівні БД:
-- Атомарне списання з перевіркою
UPDATE b_catalog_store_product
SET QUANTITY = QUANTITY - 1
WHERE PRODUCT_ID = ? AND STORE_ID = ? AND QUANTITY >= 1;
-- Якщо affected_rows = 0 — залишку немає, відхиляємо замовлення
У Бітрікс це реалізується через CCatalogProductProvider з перевіркою кількості в транзакції.
Терміни налаштування
Налаштування двостороннього обміну замовленнями (онлайн ↔ офлайн) з резервуванням залишків і синхронізацією через чергу — 5–10 робочих днів залежно від типу POS та облікової системи.







