Setting Up Receipts under Federal Law 54-FZ on 1C-Bitrix
A receipt under Federal Law 54-FZ is not just sending data to a cash register. It is a specific JSON format with mandatory fields: settlement marker, payment method marker, VAT for each item, agent data if settlement is through an intermediary, customer data if the amount exceeds 100,000 rubles. An error in any field — the receipt is not fiscalized, and the Federal Tax Service detects it.
Receipt Structure in Bitrix Context
Bitrix forms a receipt via class \Bitrix\Sale\Cashbox\Check and its subclasses:
-
Sell— income receipt (first payment) -
SellCorrection— income correction receipt -
Refund— refund receipt -
RefundCorrection— refund correction receipt -
AdvancePayment— advance (prepayment without binding to nomenclature) -
AdvancePaymentReturn— advance return -
Full— full settlement (for two-stage payment)
Receipt type is determined automatically by event. For two-stage payment, two receipts are needed: first when holding (advance), second when confirming (full settlement).
Mandatory Receipt Fields under FFD 1.2
From 2023, FFD 1.2 format is mandatory for new cash register machines. New fields have been added:
Settlement Object Marker (PAYMENT_OBJECT) — what is being sold:
-
COMMODITY— goods -
EXCISE— excisable goods -
JOB— work -
SERVICE— service -
PAYMENT— payment (advance without nomenclature)
Settlement Method Marker (PAYMENT_METHOD):
-
FULL_PAYMENT— full payment -
ADVANCE— advance -
PREPAYMENT— prepayment -
CREDIT— credit -
CREDIT_PAYMENT— credit payment
Configure via product properties through admin interface or via b_catalog_product.PAYMENT_OBJECT.
VAT Configuration for Receipt Items
Incorrect VAT — the most common cause of fiscalization failure. Check VAT binding:
-- All VAT rates in the system
SELECT ID, NAME, RATE FROM b_catalog_vat WHERE ACTIVE = 'Y';
-- Products without VAT binding (VAT_ID IS NULL)
SELECT ID, NAME FROM b_catalog_product WHERE VAT_ID IS NULL LIMIT 20;
-- Update VAT for all products of one information block
UPDATE b_catalog_product cp
JOIN b_iblock_element ie ON cp.ID = ie.ID
SET cp.VAT_ID = 3 -- ID of 20% VAT rate
WHERE ie.IBLOCK_ID = 7 AND cp.VAT_ID IS NULL;
Customer Data in Receipt
If the settlement amount exceeds 100,000 rubles, the receipt must contain customer data (full name, tax ID or email/phone). For B2B orders — organization's tax ID.
Configure order properties to transmit data to the receipt:
// Customer EMAIL property should be named EMAIL or have IS_EMAIL = Y flag
// Check:
$res = \Bitrix\Sale\Internals\OrderPropsTable::getList([
'filter' => ['IS_EMAIL' => 'Y'],
'select' => ['ID', 'NAME', 'CODE']
]);
The receipt transmits automatically if the order property is marked with "Customer Email" or "Customer Phone" flag in sales module settings.
Receipt Formation Debugging
Enable cash register module logging:
// /bitrix/php_interface/init.php
define('CASHBOX_DEBUG', true);
Log is written to bitrix/modules/sale/cashbox/log/. JSON format — you can check the receipt structure before sending.
Programmatically get receipt body without sending:
$order = \Bitrix\Sale\Order::load($orderId);
$payment = $order->getPaymentCollection()->getInnerPayment();
$check = \Bitrix\Sale\Cashbox\CheckManager::createCheck(
\Bitrix\Sale\Cashbox\Internals\Check\SellCheck::getType(),
$payment
);
// Get receipt data before sending
$checkData = $check->getDataForCheck();
var_dump($checkData);
Error Handling and Retry
Receipts with errors (status F in b_sale_cashbox_check) — common problem during initial setup:
-- Receipts with errors
SELECT ID, ORDER_ID, PAYMENT_ID, ERROR_TEXT, DATE_CREATE
FROM b_sale_cashbox_check
WHERE STATUS = 'F'
ORDER BY DATE_CREATE DESC;
Retry via admin panel: "Store" → "Online Cash Registers" → "Receipt Queue" → select receipt → "Send Again".
Programmatic retry:
$check = \Bitrix\Sale\Cashbox\CheckManager::getCheckById($checkId);
if ($check) {
$check->setField('STATUS', \Bitrix\Sale\Cashbox\Internals\Check::STATUS_NEW);
$check->save();
}
Receipt on Order Refund
When a paid order is cancelled, Bitrix must automatically generate a refund receipt. This happens when payment status is removed:
$payment->setField('PAID', 'N');
$order->save();
// Refund receipt is formed via OnSalePaymentEntitySaved event handler
Ensure that the cash register settings have the "Generate refund receipt on payment cancellation" option enabled.







