Configuring Return Status Notifications in 1C-Bitrix
Notifications upon a return status change are a touchpoint where a store either builds trust or loses a customer. A buyer waiting for a return decision is anxious. A timely email with a status update eliminates calls to support and creates a positive experience even in a return situation. In Bitrix, this is handled by the mail template system (b_event_type, b_event_message) in conjunction with events from the sale module.
Notification Mechanism in Bitrix
Notifications are built on three levels:
-
Mail event type (
b_event_type) — defines the set of available variables -
Mail event template (
b_event_message) — HTML body, subject, and recipient -
CEvent::Send()call — the sending trigger, passes variable values
Registering Event Types for Return Statuses
One event type per status where the buyer needs to be notified:
// /local/install/register_return_events.php
$returnEventTypes = [
[
'EVENT_NAME' => 'RETURN_STATUS_REVIEW',
'NAME' => 'Return: Accepted for review',
'DESCRIPTION' => "RETURN_ID, ORDER_ID, ORDER_ACCOUNT_NUMBER, USER_NAME, USER_EMAIL, STATUS_NAME",
'SORT' => 100,
],
[
'EVENT_NAME' => 'RETURN_STATUS_NEED_DOCS',
'NAME' => 'Return: Documents required',
'DESCRIPTION' => "RETURN_ID, ORDER_ID, ORDER_ACCOUNT_NUMBER, USER_NAME, USER_EMAIL, STATUS_NAME, MANAGER_COMMENT",
'SORT' => 110,
],
[
'EVENT_NAME' => 'RETURN_STATUS_APPROVED',
'NAME' => 'Return: Approved',
'DESCRIPTION' => "RETURN_ID, ORDER_ID, REFUND_AMOUNT, SHIPPING_INSTRUCTIONS",
'SORT' => 120,
],
[
'EVENT_NAME' => 'RETURN_STATUS_RECEIVED',
'NAME' => 'Return: Item received at warehouse',
'DESCRIPTION' => "RETURN_ID, ORDER_ID, REFUND_AMOUNT",
'SORT' => 130,
],
[
'EVENT_NAME' => 'RETURN_STATUS_REFUND',
'NAME' => 'Return: Funds refunded',
'DESCRIPTION' => "RETURN_ID, ORDER_ID, REFUND_AMOUNT, REFUND_DATE, PAYMENT_METHOD",
'SORT' => 140,
],
[
'EVENT_NAME' => 'RETURN_STATUS_REJECTED',
'NAME' => 'Return: Rejected',
'DESCRIPTION' => "RETURN_ID, ORDER_ID, MANAGER_COMMENT, APPEAL_INSTRUCTIONS",
'SORT' => 150,
],
];
$eventType = new \CEventType();
foreach ($returnEventTypes as $type) {
$existing = \CEventType::GetList(['EVENT_NAME' => $type['EVENT_NAME']])->Fetch();
if (!$existing) {
$eventType->Add(array_merge($type, ['LID' => LANGUAGE_ID]));
}
}
Sending Notifications on Status Change
namespace Local\Returns;
class Notifications
{
private const STATUS_EVENT_MAP = [
'REVIEW' => 'RETURN_STATUS_REVIEW',
'NEED_DOCS' => 'RETURN_STATUS_NEED_DOCS',
'APPROVED' => 'RETURN_STATUS_APPROVED',
'RECEIVED' => 'RETURN_STATUS_RECEIVED',
'REFUND' => 'RETURN_STATUS_REFUND',
'REJECTED' => 'RETURN_STATUS_REJECTED',
];
public static function sendStatusChange(int $returnId, string $newStatus): void
{
$eventName = self::STATUS_EVENT_MAP[$newStatus] ?? null;
if (!$eventName) return;
$data = self::buildEventData($returnId, $newStatus);
if (!$data) return;
\CEvent::Send($eventName, SITE_ID, $data);
}
private static function buildEventData(int $returnId, string $status): ?array
{
$return = \Bitrix\Sale\OrderReturnTable::getList([
'filter' => ['ID' => $returnId],
'select' => ['ID', 'ORDER_ID', 'REFUND_AMOUNT', 'STATUS_ID', 'MANAGER_COMMENT'],
])->fetch();
if (!$return) return null;
$order = \Bitrix\Sale\Order::load($return['ORDER_ID']);
if (!$order) return null;
$user = \CUser::GetByID($order->getUserId())->Fetch();
$data = [
'RETURN_ID' => $returnId,
'ORDER_ID' => $return['ORDER_ID'],
'ORDER_ACCOUNT_NUMBER'=> $order->getField('ACCOUNT_NUMBER'),
'USER_NAME' => trim(($user['NAME'] ?? '') . ' ' . ($user['LAST_NAME'] ?? '')),
'USER_EMAIL' => $user['EMAIL'] ?? '',
'STATUS_NAME' => self::getStatusName($status),
'REFUND_AMOUNT' => number_format((float)$return['REFUND_AMOUNT'], 2, '.', ' ') . ' RUB',
'MANAGER_COMMENT' => $return['MANAGER_COMMENT'] ?? '',
'RETURN_URL' => self::getReturnUrl($returnId),
];
// Status-specific data
if ($status === 'APPROVED') {
$data['SHIPPING_INSTRUCTIONS'] = self::getShippingInstructions();
}
if ($status === 'REFUND') {
$data['REFUND_DATE'] = (new \Bitrix\Main\Type\DateTime())->format('d.m.Y');
$data['PAYMENT_METHOD'] = self::getPaymentMethodName($order);
}
if ($status === 'REJECTED') {
$data['APPEAL_INSTRUCTIONS'] = 'You may contact us by phone +7 (800) 555-35-35';
}
return $data;
}
private static function getStatusName(string $statusId): string
{
$result = \CSaleOrderReturnStatus::GetByID($statusId);
return $result['NAME'] ?? $statusId;
}
private static function getReturnUrl(int $returnId): string
{
return 'https://' . SITE_SERVER_NAME . '/personal/returns/' . $returnId . '/';
}
}
Hooking into the Status Change Handler
// In init.php — attach notifications to sale module events
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'sale',
'OnSaleOrderReturnStatusChange',
function (\Bitrix\Main\Event $event) {
$returnId = $event->getParameter('RETURN_ID');
$newStatus = $event->getParameter('NEW_STATUS_ID');
\Local\Returns\Notifications::sendStatusChange($returnId, $newStatus);
}
);
SMS Notifications
For critical statuses (funds refunded, approved) add SMS via SMSC, SMS.ru, or another provider:
class SmsNotifier
{
private const SMS_STATUSES = ['APPROVED', 'REFUND', 'REJECTED'];
public static function maybeSend(int $returnId, string $status): void
{
if (!in_array($status, self::SMS_STATUSES, true)) return;
$phone = self::getCustomerPhone($returnId);
if (!$phone) return;
$text = self::buildSmsText($returnId, $status);
$client = new \Local\Sms\SmsClient();
$client->send($phone, $text);
}
private static function buildSmsText(int $returnId, string $status): string
{
return match ($status) {
'APPROVED' => "Return #{$returnId} approved. Please ship the item to: ...",
'REFUND' => "Return #{$returnId}: funds sent. Will arrive within 3–5 business days.",
'REJECTED' => "Return #{$returnId} rejected. Reason sent to your email.",
default => "Return request #{$returnId} status has been updated.",
};
}
}
Push Notifications in the Personal Account
In addition to email and SMS — browser notifications via Web Push or through the personal account notification mechanism:
// Add notification to the Bitrix personal account (if im module or custom mechanism is available)
class LkNotifier
{
public static function notify(int $userId, int $returnId, string $status): void
{
// Via the im module (corporate portal)
if (\Bitrix\Main\Loader::includeModule('im')) {
\CIMNotify::Add([
'FROM_USER_ID' => 0, // from system
'TO_USER_ID' => $userId,
'NOTIFY_TYPE' => IM_NOTIFY_SYSTEM,
'NOTIFY_MODULE'=> 'local.returns',
'NOTIFY_TAG' => 'RETURN_' . $returnId,
'NOTIFY_MESSAGE' => "Return request #{$returnId} status changed to «" .
\Local\Returns\Notifications::getStatusName($status) . "»",
'NOTIFY_MESSAGE_OUT' => 'Return request status updated',
]);
}
}
}
Email Template: "Approved" Status
Sample HTML template for the RETURN_STATUS_APPROVED event:
Subject: Your return request #[RETURN_ID] has been approved
Dear [USER_NAME],
Your request to return an item from order [ORDER_ACCOUNT_NUMBER] has been approved.
Refund amount: [REFUND_AMOUNT]
To complete the return, please ship the item to:
[SHIPPING_INSTRUCTIONS]
Once we receive the item at our warehouse, funds will be transferred within 3 business days.
Track your return status: [RETURN_URL]
Scope of Work
- Register mail event types for each status
- HTML email templates: subject, body, variable lists
-
OnSaleOrderReturnStatusChangehandler →CEvent::Send()call - SMS notifications for critical statuses
- Personal account notifications via the IM module or custom mechanism
- Testing: verify all status transitions and email delivery
Timeline: full set of notifications for all statuses — 1–2 weeks.







