Configuring Automatic Receipt Delivery to Messenger in 1C-Bitrix
After an online payment, the customer receives an electronic receipt by email in compliance with fiscal regulations. Many email notifications end up in spam, or the customer does not have a convenient email client on their phone. Sending a receipt via messenger — Telegram or WhatsApp — solves the deliverability problem: messengers are read more frequently and faster.
When a Receipt Is Generated in Bitrix
A fiscal receipt is created by the cash register module at the moment payment is confirmed. Bitrix works with online cash registers through modules: atol.online, evotor.kassa, orangedata, and equivalents. After fiscalization, the module saves the receipt URL to the b_sale_pay_system_action table or to a custom payment field.
The event to hook into: OnSaleOrderPaid (module sale). By this point the receipt should already be created — depending on the cash register module, this may happen synchronously or with a delay of up to 30 seconds.
Retrieving the Receipt URL from the ATOL Module
// Read the receipt URL from payment data
$payment = $order->getPaymentCollection()->getInnerPayment();
$checkUrl = $payment->getField('PS_PARAMS') ?? null;
// For ATOL the receipt is stored in a separate table
$checkResult = \Atol\Online\Check::getByOrderId($order->getId());
$checkUrl = $checkResult['RECEIPT_URL'] ?? null;
The exact storage location depends on the cash register module. Before development — review the documentation for the specific module and its tables/fields.
Handler: Sending a Receipt After Payment
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'sale',
'OnSaleOrderPaid',
function (\Bitrix\Main\Event $event) {
$order = $event->getParameter('ENTITY');
$payment = $event->getParameter('PAYMENT');
$userId = $order->getUserId();
// Get the receipt URL — with a short delay if the cash register module is async
$checkUrl = self::waitForCheck($order->getId(), 3); // wait up to 3 seconds
if (!$checkUrl) {
// Receipt URL not received — log it, email was already sent via standard mechanism
return;
}
$message = sprintf(
"Your fiscal receipt for order #%d:\n%s",
$order->getId(),
$checkUrl
);
// Determine the user's preferred notification channel
$user = \Bitrix\Main\UserTable::getById($userId)->fetch();
if (!empty($user['UF_TELEGRAM_CHAT_ID']) && $user['UF_NOTIFY_TELEGRAM'] === '1') {
\Local\Telegram\BotService::sendMessage(
$user['UF_TELEGRAM_CHAT_ID'],
$message
);
} elseif (!empty($user['UF_PHONE']) && $user['UF_NOTIFY_WHATSAPP'] === '1') {
\Local\WhatsApp\Service::sendMessage($user['UF_PHONE'], $message);
}
// email is always sent via the standard Bitrix mechanism
}
);
If the cash register module creates the receipt asynchronously (via a queue), synchronous waiting is insufficient. In this case, subscribe to the cash register module's own event:
// ATOL Online event after receiving the OFD response
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'atol.online',
'OnReceiptRegistered',
function (\Bitrix\Main\Event $event) {
$orderId = $event->getParameter('ORDER_ID');
$checkUrl = $event->getParameter('RECEIPT_URL');
// Send to messenger here
}
);
Receipt Message Format
For Telegram, you can add a button with a link to the receipt via InlineKeyboard:
$payload = [
'chat_id' => $chatId,
'text' => "Receipt for order #{$orderId} is ready.",
'parse_mode' => 'HTML',
'reply_markup' => json_encode([
'inline_keyboard' => [[
['text' => 'View receipt', 'url' => $checkUrl],
]],
]),
];
Setup Timeline
Payment event handler, retrieving the receipt URL from the cash register module, sending to Telegram and/or WhatsApp — 4–8 hours. If the cash register module is asynchronous and requires subscribing to its events — an additional 2–4 hours.







