Setting up synchronization of online and offline orders in 1C-Bitrix

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1175
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    747
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    976

Configuring Online and Offline Order Synchronization in 1C-Bitrix

In a retail network, orders come from three places: the online store, POS terminals at locations, and operator calls. Without synchronization, there are three isolated streams: the same stock is reserved three times, the office manager cannot see online orders, and a courier delivers a product that is already out of stock. Online/offline synchronization in Bitrix is primarily about working with b_sale_order, warehouse stock levels, and the data transfer channel to 1C or another accounting system.

Order Stream Architecture

The central accounting system defines all logic. Typical options:

1C as master — 1C is the source of truth for orders and stock. Bitrix passes online orders to 1C; offline sales are recorded there too, and stock levels are synchronized back.

Bitrix as master — all orders (online and offline via POS) are aggregated in Bitrix; 1C receives data for accounting.

A hybrid scheme with no clear master is a source of chaos. The choice is made before development begins.

Synchronization via CommerceML

The standard 1C–Bitrix exchange (/bitrix/admin/1c_exchange.php) covers the basic scenario: orders from Bitrix go to 1C, and statuses come back. Configuration is in the sale module:

Administration → Online Store → Settings → "1C" tab

Limitation: the standard exchange is batch-based, running every N minutes. For real-time synchronization, webhooks or queues are required.

Offline Orders: How to Push Them into Bitrix from a POS

When a cashier processes a sale through a POS (Evotor, 1C:Retail), the options are:

  • Create an order in Bitrix via API and immediately mark it as paid
  • Or only deduct stock without creating an order (if offline sales do not need to appear in the online store history)

Creating an order via the Bitrix REST API (/rest/v1/sale.order.add) or via PHP:

// Creating an offline order in Bitrix
\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', 'In-store sale: ' . $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);

// Mark the order source
$order->setField('STATUS_ID', 'F');  // Completed — offline sale is finalized
$order->setField('ADDITIONAL_INFO', json_encode([
    'source' => 'offline',
    'store'  => $storeId,
    'pos_transaction_id' => $transactionId,
]));

$result = $order->save();

Stock Reservation for Online Orders

The critical question: when to reserve a product for an online order? On add-to-cart — too early (many abandoned carts). On payment — risk of selling something already taken from the store shelf.

Bitrix manages reservations via b_catalog_store_product and b_sale_product_reserve:

// Reserve product at the time of order placement
\Bitrix\Catalog\StoreProductTable::reserveProduct(
    $productId,
    $storeId,
    $quantity,
    $orderId
);

// Release reservation on cancellation
\Bitrix\Catalog\StoreProductTable::releaseProductReserve(
    $productId,
    $orderId
);

For Click & Collect the logic differs: reserve at a specific warehouse (pickup location), not from the general pool.

Real-Time Stock Synchronization

A stock change on any side (online order, POS sale, supplier receipt) must be reflected everywhere immediately. For this — an event queue:

// On stock change — push to queue
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
    'catalog', 'OnProductUpdate',
    function (\Bitrix\Main\Event $event) {
        $productId = $event->getParameter('ID');
        $fields = $event->getParameter('FIELDS');

        if (isset($fields['QUANTITY'])) {
            // Queue for synchronization with 1C
            \Local\Queue\InventorySync::push([
                'product_id' => $productId,
                'quantity'   => $fields['QUANTITY'],
                'timestamp'  => time(),
            ]);
        }
    }
);

The queue is processed by a Bitrix agent or a worker (supervisor + PHP script), which sends changes in batches to 1C or another accounting system.

Conflicts: Simultaneous Sales

Stock = 1, an online order and a POS sale are placed simultaneously. Both streams see stock = 1 and accept the order. The solution — optimistic locking at the DB level:

-- Atomic deduction with a check
UPDATE b_catalog_store_product
SET QUANTITY = QUANTITY - 1
WHERE PRODUCT_ID = ? AND STORE_ID = ? AND QUANTITY >= 1;

-- If affected_rows = 0 — no stock, reject the order

In Bitrix this is implemented via CCatalogProductProvider with quantity checked inside a transaction.

Setup Timeline

Setting up bidirectional order exchange (online ↔ offline) with stock reservation and queue-based synchronization — 5–10 business days depending on the POS type and accounting system.