Настройка синхронизации заказов онлайн и оффлайн 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 и сразу пометить его оплаченным
- Или только списать остатки без создания заказа (если оффлайн-продажи не нужны в истории интернет-магазина)
Создание заказа через Битрикс 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 и учётной системы.







