According to Federal Law No. 54-FZ, when refunding money to a customer, the cash register must print a receipt with the calculation sign "Return of receipt". We implement integration of returns with an online cash register in 1C-Bitrix turnkey: we analyze the current scheme, modify handlers, test all scenarios, and provide documentation. Without correct fiscalization of returns, the company risks a fine of up to 50% of each operation amount. According to statistics, 70% of fiscalization errors for returns are related to incorrect linking to the original sale receipt — we eliminate such problems during the audit stage. With high return volumes, potential fines can reach significant amounts, so automation pays off within weeks. Our experience includes 50+ projects integrating cash registers with Bitrix, including major online stores handling thousands of returns per day. Get a consultation for your configuration — we will assess the project and provide timelines.
How Bitrix Interacts with the Cash Register
The module sale.cashbox (bitrix/modules/sale/cashbox/) handles fiscalization. Receipts are sent via handlers (handlers) that inherit from \Bitrix\Sale\Cashbox\CashboxPaymaster or \Bitrix\Sale\Cashbox\CashboxAtol. Standard handlers include: Atol Online, CloudKassir, OrangeData, YooKassa, and others.
When an order is paid, Bitrix calls \Bitrix\Sale\Cashbox\Manager::sendCheck() with the receipt type CHECK_TYPE_SELL (sale). On a return — CHECK_TYPE_SELL_RETURN (return of receipt).
Tables: b_sale_cashbox_check — check history, b_sale_cashbox — configured cash registers.
How Is a Return Receipt Formed?
Bitrix automatically creates a return receipt when two conditions are met:
- The return transitions to the
COMPLETEDstatus - The original payment has an associated cash register and a confirmed fiscal sale receipt
The code that triggers this is \Bitrix\Sale\Cashbox\Manager::addByReturn():
// Inside the OnSaleReturnComplete event handler \Bitrix\Sale\Cashbox\Manager::addByReturn($return); If you have a non-standard scenario (return created by an external script), you need to call this method manually after saving the return.
What Goes Into the Return Receipt?
The receipt items are formed from b_sale_order_return_item. Each item contains:
- Product name (from
b_iblock_element.NAMEvia JOIN onb_sale_basket.PRODUCT_ID) - Quantity
- Price
- VAT rate
- Calculation subject indicator (product/service/work) — taken from the order item settings
If VAT is not specified or is incorrect in the original order, the return receipt will have an error. This is a common problem when migrating from Bitrix to a new cash register scheme.
Automatic fiscalization through the standard sale.cashbox module is 5 times more reliable than manual receipt punching through the operator’s personal account — it eliminates human errors and delays.
What Typical Problems Occur?
Return receipt is not sent. Cause: the return was created not through \Bitrix\Sale\OrderReturn but directly in the database or via an unofficial mechanism — the OnSaleReturnComplete event does not fire. Solution: always use ORM methods.
The return amount exceeds the sale amount. The cashier operator rejects the receipt if the return amount is greater than in the original sale receipt. This happens with partial returns of multiple payments for one order — each return receipt must be linked to a specific sale receipt via PARENT_CHECK_ID in b_sale_cashbox_check.
Duplicate receipt on repeated request. In case of a network failure, Bitrix may send the request twice. Atol Online has the external_id parameter — a unique receipt identifier on your side. Use it so the operator can identify duplicates.
Partial return of multiple items from one order. The receipt must contain only the returned items with correct quantities. The standard Manager::addByReturn() ensures this if b_sale_order_return_item is correctly filled.
How to Test Fiscalization of Returns?
All cash register operators provide a test environment. Atol Online — test URL https://testonline.atol.ru/possystem/v5/. OrangeData — test keys and certificates.
Checklist before going live:
| Scenario | What to check |
|---|---|
| Full order return | Return receipt equals sale receipt amount |
| Partial return of one item | Receipt contains only returned product |
| Return of an order with multiple payments | Receipt linked to correct payment |
| Return after price adjustment | VAT recalculated correctly |
| Repeated send on timeout | No duplicate receipt at the operator |
Setting Up Notifications for Fiscalization Errors
If a return receipt fails — the cashier operator returns an error. Bitrix saves it in the ERROR field of b_sale_cashbox_check, but by default the manager doesn’t find out about it. Set up an agent:
// Agent: checks unprocessed errors every 30 minutes $checks = \Bitrix\Sale\Cashbox\CheckManager::getList([ 'filter' => [ 'STATUS' => \Bitrix\Sale\Cashbox\Check::CHECK_STATUS_ERROR, '>=DATE_CREATE' => new \Bitrix\Main\Type\DateTime('-1 hour'), ], ]); foreach ($checks as $check) { if ($check['TYPE'] === \Bitrix\Sale\Cashbox\SellReturnCheck::TYPE) { NotificationService::alertAdmin( 'Return check error #' . $check['ID'] . ': ' . $check['ERROR'] ); } } Why Does VAT Often Cause Errors in Return Receipts?
If an order has a product with VAT 20%, but the rate is not specified in the infoblock, Bitrix substitutes the default value of 0%. The cashier operator may reject the return receipt because the rate does not match the original receipt. We check rate conformity during the audit stage.
How We Configure Returns in 5 Steps
- Audit of the current cash register scheme and version of the
sale.cashboxmodule. - Configuration of the cash register handler (Atol, OrangeData, CloudKassir, etc.) for the return environment.
- Implementation of custom scenarios (if the return is created by an external script).
- Testing all scenarios from the checklist in the operator’s test environment.
- Deployment, setup of error monitoring agent, and handover of documentation.
Common Errors and Solutions
| Error | Cause | Solution |
|---|---|---|
| Return receipt not sent | Return created not via ORM | Use \Bitrix\Sale\OrderReturn |
| Amount exceeds sale | Incorrect PARENT_CHECK_ID |
Link to specific sale receipt |
| Duplicate receipt | Repeated request on failure | Set external_id in the request |
| Incorrect VAT | VAT not set in product | Fill rate in infoblock |
Timeline
If the cash register is already configured for sales receipts, return setup takes 1–2 weeks. If configuring from scratch — 3–5 weeks, including testing all scenarios. The cost is calculated individually based on integration complexity. With hundreds of returns per day, savings on fines can be substantial. Order a turnkey return integration with a guarantee of 54-FZ compliance. Contact us for a free audit of your current scheme.







