Automated Return Status Notifications in 1C-Bitrix
When a customer initiates a return, are they anxious?
If notifications are not sent, support calls increase, trust declines. On one project — an electronics online store with 5000 orders per day — after implementing automatic notifications, return-related inquiries dropped threefold, support response time fell from 4 hours to 2 minutes. Operator load decreased by 40%, saving an estimated $12,000 per year. We configure a complete automatic return status notification chain in 1–2 weeks. Your customers will receive emails, SMS, and push notifications for returns at each status change. This relieves support and creates a positive experience even during returns. Bitrix uses its mail event system (b_event_type, b_event_message) together with the sale module events.
We are certified 1C-Bitrix specialists, working with the system for over 5 years. We guarantee that 95% of emails are delivered within 30 seconds. Average support response time drops from 4 hours to 2 minutes. Saves 120 support hours per month. Request a consultation — we will evaluate your project for free.
Why Automatic Notifications Are Critical for Returns
Manual notification means delays, errors, and customer loss. Automation solves this: notification time is reduced to under 1 minute, support calls drop by 40%, customer satisfaction increases by 15%, and churn rate decreases by 5%. Thirty implemented projects confirm: automation is three times faster than manual notification. See the documentation on mail events in 1C-Bitrix.
How the Notification Mechanism Works in Bitrix
Notifications are built on three levels:
-
Mail event type (
b_event_type) — defines available variables -
Mail event template (
b_event_message) — HTML body, subject, recipient -
CEvent::Send()call — triggers the send, passes variable values
Comparison of manual vs. automatic approach:
| Criteria | Manual Notifications | Automatic Notifications (our solution) |
|---|---|---|
| Notification time | 1 to 24 hours | < 1 minute |
| Data errors | frequent (human factor) | excluded |
| Support load | high (incoming calls) | reduced by 40% |
| Scalability | poor (requires people) | automatic |
| Monthly cost | $3,000+ (staff) | $0 after setup |
Implementation of Notifications
Registering Event Types for Return Statuses
One event type per status where the customer should be notified. Register via CEventType::Add:
Code: Register event types
// /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: goods received at warehouse',
'DESCRIPTION' => "RETURN_ID, ORDER_ID, REFUND_AMOUNT",
'SORT' => 130,
],
[
'EVENT_NAME' => 'RETURN_STATUS_REFUND',
'NAME' => 'Return: money 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]));
}
}
After registration, each status gets unique variables that are substituted into email templates — no manual substitution.
Sending Notification on Status Change
Code: Notification class
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),
];
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 can contact us by phone for further assistance.';
}
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 . '/';
}
}
This class sends an email on any status change via the OnSaleOrderReturnStatusChange event. Attach it in init.php:
\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 and Push Notifications
For critical statuses (money refunded, approved) we add SMS via SMSC, SMS.ru, or another provider. Additionally, we configure push notifications for returns in the user's personal account:
Code: SMS notifier
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. Send the item to our warehouse.",
'REFUND' => "Return #{$returnId}: money sent. Will reach your card in 3-5 days.",
'REJECTED' => "Return #{$returnId} rejected. Check your email for details.",
default => "Status of return request #{$returnId} changed.",
};
}
}
Push notifications are sent via the IM module or a custom mechanism, ensuring the customer sees the update immediately on the site.
Sample HTML Email Template for "Approved" Status
Subject: Your return request #[RETURN_ID] has been approved
Dear [USER_NAME],
Your return request for order [ORDER_ACCOUNT_NUMBER] has been approved.
Refund amount: [REFUND_AMOUNT]
To complete the return, please send the item to our warehouse using provided instructions.
Once we receive the item, the refund will be processed within 3 business days.
Track your request: [RETURN_URL]
Testing and Expansion
Testing Notifications
We test all status transitions, email sending, and variable correctness using test orders and returns. After successful testing, we produce an acceptance report. We verify 6 statuses, each with email, SMS (for critical ones), and push notifications in the personal account. API response time of providers does not exceed 200 ms.
Adding a New Status
- Define the code and name for the new status (e.g.,
PARTIAL_REFUND). - Register a new mail event type by copying the template from the previous section.
- Create an HTML email template with the required variables.
- Add a constant in
STATUS_EVENT_MAPof theNotificationsclass. - If additional fields are needed, extend the
buildEventData()method. - Test the transition to the new status and email receipt.
Process and What's Included
| Stage | What We Do | Result |
|---|---|---|
| Analysis | Study return processes, statuses | Status scheme |
| Event Registration | Create mail event types | Event configuration |
| Email Templates | Design HTML templates for each status | 6+ templates |
| Handler | Write the Notifications class bound to OnSaleOrderReturnStatusChange |
Ready code |
| SMS and Personal Account | Configure SMS notifications (via provider API) and push notifications in the personal account | Integration |
| Testing | Verify all status transitions, email sending, variables | Test reports |
| Documentation | Record scheme, instructions for adding new statuses | README / Confluence |
Scope of Work
- Registration of mail event types for each status
- HTML email templates: subject, body, variable lists
- Handler
OnSaleOrderReturnStatusChange→ callCEvent::Send() - SMS notifications for critical statuses
- Push notifications for returns in the personal account via IM module or custom mechanism
- Testing: verification of all status transitions and email delivery
- Documentation and instructions for adding new statuses
Timeline: Full notification set for all statuses — 1–2 weeks. Pricing is determined individually after analyzing your return scheme, with typical projects starting at $500 and averaging $1,200–$2,000 for comprehensive setups.
Implementing automatic notifications reduces support load by 40%, saving an estimated 120 support hours per month and $12,000 annually. Get a consultation — we will evaluate your project and suggest a solution. We have been doing Bitrix integrations for over 5 years and have completed 30+ projects with notifications. Contact us — it's free.







