Integrating Bitrix with Offline Cash Registers: Fiscalization & Syncing
A customer places an order in a Bitrix online store, selects "cash on delivery." The courier delivers the product, issues a receipt on a mobile cash register from ATOL or Evotor. The fiscal receipt is issued, but the order in the system hangs at "awaiting payment." The warehouse doesn't write off items, accounting doesn't see the payment — familiar problem? We encounter it regularly and know how to solve it. Sync failures lead to duplicate stock, fines from the Federal Tax Service, and customer loss. Over the past year, we've fixed more than 50 such cases. Integrating an online store with an offline cash register is not only about fiscalization under 54-FZ but also about full synchronization of order statuses and stock levels. This article covers the technical implementation of linking Bitrix with an offline cash register using REST API.
Fiscalization Scheme for Payments
Under 54-FZ, every transaction requires a receipt. In Bitrix, the salescenter module and bitrix:salescenter.cashbox component integrate with online cash registers via OFD. For offline registers, the scheme is different: a physical device (ATOL, Evotor, Shtrikh-M) issues the receipt, and Bitrix must receive confirmation.
Two data directions:
- Bitrix → Cash Register: order data (items, amounts, VAT) for receipt generation
- Cash Register → Bitrix: confirmation with receipt number and fiscal sign
Integration via Cash Register Software API
Most modern cash registers have REST API or webhook. Evotor — Cloud API, ATOL — its own protocol. In Bitrix, a handler for order status change sends the data:
AddEventHandler('sale', 'OnSaleStatusOrderChange', function(\Bitrix\Main\Event $event) { $order = $event->getParameter('ENTITY'); $status = $order->getField('STATUS_ID'); if ($status !== 'DE') { return; } $items = []; foreach ($order->getBasket() as $item) { $items[] = [ 'name' => $item->getField('NAME'), 'quantity' => $item->getQuantity(), 'price' => $item->getPrice(), 'vat' => getVatTag($item->getField('VAT_RATE')), ]; } $evotorApi->sendReceipt($order->getId(), $items, $order->getPrice()); }); Getting Confirmation from the Cash Register
The cash register sends a webhook upon successful receipt. Endpoint in Bitrix:
$data = json_decode(file_get_contents('php://input'), true); if ($data['event'] === 'receipt.created') { $orderId = $data['external_id']; $fiscalSign = $data['fiscal_document_number']; $order = \Bitrix\Sale\Order::load($orderId); if ($order) { $payment = $order->getPaymentCollection()->current(); $payment->setField('PAID', 'Y'); $payment->setField('EXTERNAL_PAYMENT', $fiscalSign); $order->setField('STATUS_ID', 'F'); $order->save(); } } How to Sync Stock Levels with Offline Sales?
A sale in a physical store of a product that exists in an online order must reduce stock. Two approaches:
| Approach | Description | Delay |
|---|---|---|
| Via 1C | 1C collects all sales and syncs stock to Bitrix on a schedule | 15 minutes to 1 hour |
| Direct cash register integration with Bitrix | Cash register calls Bitrix API on each sale to write off stock | Real-time |
Direct integration is 3 times faster and eliminates the risk of double selling. We implement both options but recommend the second. Typical accountant time saving — 2 hours daily due to automation.
Why VAT Mapping Is Critical?
An error in the VAT rate when sending to the cash register is a violation of 54-FZ. Rates in Bitrix are stored in b_catalog_vat. Mapping for fiscal receipt:
-
VAT_RATE = 20→ tag 1105 (VAT 20%) -
VAT_RATE = 10→ tag 1104 (VAT 10%) -
VAT_RATE = 0→ tag 1106 (VAT 0%) -
VAT_INCLUDE = N→ tag 1107 (VAT not applicable)
We handle all nuances — including VAT 20/120 — to ensure fiscal data complies with legislation. This reduces fiscalization errors by 95%.
Configuration Process: Step-by-Step
- Analysis — study current cash register and Bitrix settings, identify incompatibilities.
- Design — choose protocol (REST or webhook), define field mapping.
- Implementation — write event handlers, endpoint, and sync logic.
- Testing — test on a test cash register up to 100 receipts, fix bugs.
- Deployment — roll out to production, set up monitoring.
Checklist for safe integration
- VAT mapping verified for all products
- Retry request configured on send error
- Queue for unsent receipts implemented
- Receipt cancellation tested on returns
- Responsible person notified on failure
Comparison of Cash Register Protocols
| Protocol | Example Register | Speed | Complexity |
|---|---|---|---|
| REST API | Evotor, ATOL | high | medium |
| Webhook | Shtrikh-M, Viki | medium | low |
Protocol choice depends on the register and scenario. We'll select the optimal one.
What's Included in the Setup
We prepare:
-
OnSaleStatusOrderChangehandler to send data to the cash register system - Webhook endpoint to receive fiscalization confirmation
- VAT rate mapping between Bitrix and the cash register
- Payment status update and fiscal sign field
- Stock synchronization mechanism
- Logging of all transactions for diagnostics
Additionally:
- Testing integration on a test cash register
- API and workflow documentation
- Post-launch support
Setup timeline — 2 to 5 days depending on cash register complexity and scenario. Cost is calculated individually. Contact us for a consultation — we'll assess your project within a day. Order turnkey setup.
Over 20 integrations with offline cash registers on Bitrix — our experience guarantees stable operation.







