Integrating returns with the 1C-Bitrix online cash register

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
    1173
  • 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
    745
  • 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

Integrating Returns with the Online Cash Register in 1C-Bitrix

Under Federal Law No. 54-FZ, when refunding money to a buyer, the cash register must issue a receipt with the settlement attribute "Return of Receipt." If the website processes payments through Bitrix with an online cash register, any return must automatically generate a fiscal document through the same channel. Without this, a violation occurs: money has been refunded but no receipt has been issued.

How Bitrix Interacts with the Cash Register

The sale.cashbox module (bitrix/modules/sale/cashbox/) handles fiscalization. Receipts are sent through handlers inheriting 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 receipt type CHECK_TYPE_SELL (income). On a return — CHECK_TYPE_SELL_RETURN (return of income).

Tables: b_sale_cashbox_check — receipt history; b_sale_cashbox — configured cash registers.

How a Return Receipt Is Generated

Bitrix automatically creates a return receipt when two conditions are met:

  1. The return transitions to the COMPLETED status
  2. A cash register is linked to the original payment and a confirmed fiscal income receipt already exists

The code that triggers this — \Bitrix\Sale\Cashbox\Manager::addByReturn():

// Inside the OnSaleReturnComplete event handler
\Bitrix\Sale\Cashbox\Manager::addByReturn($return);

If you have a non-standard scenario (a return is created by an external script), you must call this method manually after saving the return.

What Goes into the Return Receipt

Receipt line items are built from b_sale_order_return_item. Each line item contains:

  • Product name (from b_iblock_element.NAME via JOIN on b_sale_basket.PRODUCT_ID)
  • Quantity
  • Price
  • VAT rate
  • Settlement subject attribute (goods/service/work) — taken from the original order item settings

If VAT is missing or incorrectly specified in the original order, the return receipt will contain an error. This is a common issue when migrating from Bitrix to a new cash register scheme.

Common Issues

Return receipt is not sent. Cause: the return was created directly in the database or via an unofficial mechanism — the OnSaleReturnComplete event does not fire. Solution: always use ORM methods.

Error: "Return amount exceeds income amount." The fiscal operator rejects the receipt if the return amount is greater than in the original income receipt. This happens with partial returns of multiple payments for one order — each return receipt must be linked to a specific income receipt via PARENT_CHECK_ID in b_sale_cashbox_check.

Duplicate receipt on repeated request. If the network fails, Bitrix may send the request twice. Atol Online has an external_id parameter — a unique receipt identifier on your side. Use it so the operator can detect duplicates.

Partial return of multiple items from one order. The receipt must contain only the returned items with the correct quantities. The standard Manager::addByReturn() handles this if b_sale_order_return_item is populated correctly.

Testing Fiscalization of Returns

All fiscal operators provide a test environment. Atol Online — test URL https://testonline.atol.ru/possystem/v5/. OrangeData — test keys and certificates.

Pre-production checklist:

Scenario What to verify
Full order return Return receipt amount = income receipt amount
Partial return of one item Receipt contains only the returned item
Return of order with multiple payments Receipt linked to the correct payment
Return after price adjustment VAT recalculated correctly
Resend after timeout No duplicate receipt at the operator

Configuring Fiscalization Error Notifications

If a return receipt fails, the fiscal operator returns an error. Bitrix stores it in the ERROR field of b_sale_cashbox_check, but by default the manager is not notified. Set up an agent:

// Agent: checks for unhandled 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 receipt error #' . $check['ID'] . ': ' . $check['ERROR']
        );
    }
}

Scope of Work

  • Check sale.cashbox module version and compatibility with the fiscal operator version
  • Configure the cash register handler for the return environment (test/production URL)
  • Test all return scenarios in the operator's test environment
  • Set up a fiscalization error monitoring agent
  • Verify VAT correctness in order and return line items
  • Documentation for manual receipt issuance in exceptional situations

Timeline: if the cash register is already configured for income receipts — configuring returns takes 1–2 weeks. If the cash register is being set up from scratch — 3–5 weeks, including testing across all scenarios.