Настройка автоматической обработки возвратов 1С-Битрикс
Автоматизация возвратов нужна там, где объём выше 20–30 заявок в день и менеджер тратит существенное время на рутинные операции: проверить оплату заказа, создать возврат в 1С, провести возврат денег, отправить письмо покупателю. Каждое из этих действий можно запустить автоматически при смене статуса заявки — через обработчики событий модуля sale и агенты Битрикс.
Наша команда за 8 лет работы с платформой реализовала более 40 автоматизаций возвратов для интернет-магазинов различного масштаба. Мы обеспечиваем полную интеграцию с 1С и платёжными шлюзами, что сокращает среднее время обработки одной заявки с 15 минут до 2 минут. Экономия для магазина с потоком 50 возвратов в день составляет около 10 часов работы менеджера в неделю — это высвобождает ресурсы на более важные задачи. Также автоматизация исключает человеческие ошибки при возврате денежных средств и работе с 1С.
Событийная модель возвратов
Модуль sale генерирует события при работе с возвратами. Ключевые точки для автоматизации:
-
OnSaleOrderReturnSaved— создание или обновление заявки -
OnSaleOrderReturnStatusChange— смена статуса -
OnSalePaymentCollectionReturnAdd— добавление возврата платежа
Регистрируем обработчики в /local/php_interface/init.php:
$eventManager = \Bitrix\Main\EventManager::getInstance(); $eventManager->addEventHandler('sale', 'OnSaleOrderReturnSaved', [\Local\Returns\AutoProcessor::class, 'onReturnSaved']); $eventManager->addEventHandler('sale', 'OnSaleOrderReturnStatusChange', [\Local\Returns\AutoProcessor::class, 'onStatusChange']); Автоматические действия при создании заявки
namespace Local\Returns; class AutoProcessor { public static function onReturnSaved(\Bitrix\Main\Event $event): void { $return = $event->getParameter('ENTITY'); if (!$return instanceof \Bitrix\Sale\OrderReturn) return; // Только при создании (не при обновлении) if (!$event->getParameter('IS_NEW')) return; $returnId = $return->getId(); // 1. Назначаем ответственного по ротации self::assignResponsible($returnId); // 2. Отправляем подтверждение покупателю Notifications::sendToCustomer($returnId, 'RETURN_CREATED'); // 3. Уведомляем менеджера Notifications::sendToManager($returnId, 'NEW_RETURN'); // 4. Если сумма возврата небольшая — автоодобряем self::tryAutoApprove($return); } public static function onStatusChange(\Bitrix\Main\Event $event): void { $returnId = $event->getParameter('RETURN_ID'); $newStatus = $event->getParameter('NEW_STATUS_ID'); $oldStatus = $event->getParameter('OLD_STATUS_ID'); $handler = new self(); $handler->handleStatusTransition($returnId, $oldStatus, $newStatus); } private function handleStatusTransition(int $returnId, string $from, string $to): void { match ($to) { 'APPROVED' => $this->onApproved($returnId), 'RECEIVED' => $this->onReceived($returnId), 'REJECTED' => $this->onRejected($returnId), 'REFUND' => $this->onRefunded($returnId), default => null, }; } } Автоодобрение мелких возвратов
Возвраты до определённой суммы (конфигурируемый порог) не требуют ручной проверки:
private static function tryAutoApprove(\Bitrix\Sale\OrderReturn $return): void { $autoApproveLimit = (float)\Bitrix\Main\Config\Option::get( 'local.returns', 'auto_approve_limit', 500 ); $returnAmount = (float)$return->getField('REFUND_AMOUNT'); if ($returnAmount <= 0 || $returnAmount > $autoApproveLimit) { return; } // Проверяем: покупатель без истории спорных возвратов $userId = $return->getOrder()->getUserId(); if (self::hasDisputeHistory($userId)) { return; } // Автоматически меняем статус на APPROVED $return->setField('STATUS_ID', 'APPROVED'); $return->setField('MANAGER_COMMENT', 'Автоодобрено: сумма до ' . $autoApproveLimit . ' руб.'); $result = $return->save(); if ($result->isSuccess()) { \CEventLog::Add([ 'SEVERITY' => 'INFO', 'AUDIT_TYPE_ID' => 'RETURN_AUTO_APPROVED', 'MODULE_ID' => 'local.returns', 'DESCRIPTION' => "Return #{$return->getId()} auto-approved, amount: {$returnAmount}", ]); } } private static function hasDisputeHistory(int $userId): bool { // Считаем отклонённые возвраты за последние 6 месяцев $dateFrom = new \Bitrix\Main\Type\Date(); $dateFrom->add('-180 days'); $result = \Bitrix\Sale\OrderReturnTable::getList([ 'filter' => [ '=ORDER.USER_ID' => $userId, 'STATUS_ID' => 'REJECTED', '>=DATE_INSERT' => $dateFrom, ], 'select' => ['ID'], ]); return (bool)$result->fetch(); } Автоматический возврат денег при одобрении
При переходе в статус «Одобрен» — автоматически инициируем возврат через API платёжной системы:
private function onApproved(int $returnId): void { $return = \Bitrix\Sale\OrderReturn::loadById($returnId); if (!$return) return; $order = $return->getOrder(); $payments = $order->getPaymentCollection(); foreach ($payments as $payment) { if (!$payment->isPaid()) continue; $psHandler = \Bitrix\Sale\PaySystem\Manager::getObjectById( $payment->getPaymentSystemId() ); if (!$psHandler) continue; $supportsRefund = method_exists($psHandler, 'refund'); if (!$supportsRefund) { // Платёжная система не поддерживает автовозврат — ставим в очередь для ручной обработки $this->flagForManualRefund($returnId, 'PS does not support auto refund'); continue; } $refundAmount = (float)$return->getField('REFUND_AMOUNT'); $result = $psHandler->refund($payment, $refundAmount); if ($result->isSuccess()) { $return->setField('STATUS_ID', 'REFUND'); $return->setField('REFUND_DATE', new \Bitrix\Main\Type\DateTime()); $return->save(); Notifications::sendToCustomer($returnId, 'RETURN_REFUNDED'); } else { $this->flagForManualRefund($returnId, implode('; ', $result->getErrorMessages())); } } } Автоматическая проверка получения товара через трекинг
Если покупатель отправляет товар назад по трекинг-номеру, можно автоматически отслеживать доставку:
class TrackingWatcher { // Агент, запускаемый каждые 2 часа public static function checkPendingReturns(): string { $returns = \Bitrix\Sale\OrderReturnTable::getList([ 'filter' => [ 'STATUS_ID' => 'APPROVED', 'UF_TRACKING' => ['!=', '', false], // заявки с трекинг-номером ], 'select' => ['ID', 'UF_TRACKING', 'UF_CARRIER'], ]); $checker = new \Local\Delivery\TrackingChecker(); while ($row = $returns->fetch()) { $status = $checker->getStatus($row['UF_TRACKING'], $row['UF_CARRIER'] ?? 'pochta'); if ($status === 'delivered') { $return = \Bitrix\Sale\OrderReturn::loadById($row['ID']); $return->setField('STATUS_ID', 'RECEIVED'); $return->save(); } } return 'checkPendingReturns();'; // перезапуск агента } } Эскалация просроченных заявок
Агент для контроля SLA по возвратам:
class SlaWatcher { private const SLA_HOURS = [ 'WAIT' => 24, // рассмотреть в течение 24 часов 'REVIEW' => 48, // принять решение в течение 48 часов ]; public static function checkOverdue(): string { foreach (self::SLA_HOURS as $statusId => $maxHours) { $deadline = new \Bitrix\Main\Type\DateTime(); $deadline->add('-' . $maxHours . ' hours'); $overdueReturns = \Bitrix\Sale\OrderReturnTable::getList([ 'filter' => [ 'STATUS_ID' => $statusId, '<=DATE_STATUS' => $deadline, ], 'select' => ['ID', 'RESPONSIBLE_ID', 'ORDER_ID'], ]); while ($row = $overdueReturns->fetch()) { Notifications::escalate($row['ID'], $row['RESPONSIBLE_ID'], $statusId, $maxHours); } } return 'checkOverdue();'; } } Состав работ
- Обработчики событий:
OnSaleOrderReturnSaved,OnSaleOrderReturnStatusChange - Логика автоодобрения по сумме и истории покупателя
- Автовозврат денег через API платёжных систем (ЮKassa, Тинькофф и др.)
- Агент трекинга входящих посылок (Почта России, СДЭК, Boxberry)
- Агент SLA-мониторинга с эскалацией просроченных заявок
- Email-автоматика: шаблоны под каждый статус
Сроки: базовая автоматизация (уведомления + автовозврат денег) — 2–3 недели. Полный стек со SLA-мониторингом и трекингом — 4–6 недель.
Детальное описание процесса
Интеграция требует тщательного планирования и анализа текущих процессов в вашей компании. Мы проводим аудит существующих систем, определяем точки интеграции и возможные конфликты. На каждом этапе предоставляем подробную документацию и проводим тестирование на staging-среде перед запуском в production. Наши решения разработаны с учётом лучших практик индустрии и позволяют значительно снизить операционные затраты.
Наша гарантия качества
Мы берём на себя полную ответственность за качество выполненной работы. В течение 12 месяцев после завершения проекта исправляем любые обнаруженные проблемы абсолютно бесплатно. Техническая поддержка включает консультации, обучение вашей команды и помощь при возникновении вопросов. Каждый проект завершается итоговым отчётом с описанием реализованного функционала, рекомендациями по оптимизации и планом развития системы.
Примеры успешных проектов
За время работы мы реализовали интеграции для компаний разного размера: от небольших интернет-магазинов до крупных оптовых дистрибьюторов. Каждый проект требовал индивидуального подхода, и мы гордимся результатом, который значительно улучшил эффективность работы наших клиентов.
Преимущества нашего подхода
Мы обеспечиваем комплексное решение, а не отдельные исправления. Каждый проект включает документирование, тестирование и обучение команды. Нашим клиентам нравится, что мы не просто выполняем работу, но и объясняем каждый шаг процесса, давая возможность вашей команде в будущем самостоятельно поддерживать систему. Со своей стороны, мы гарантируем помощь в течение года после завершения проекта.
Контакты и следующие шаги
Если ваша компания столкнулась с описанной проблемой, свяжитесь с нами для бесплатной консультации. Проведём анализ вашей системы и предложим оптимальное решение. Стоимость проекта зависит от сложности и объёма работ, но для типовых решений мы всегда предоставляем точную смету на основе предварительного анализа требований.
Технологии и инструменты
В нашей работе мы используем современный стек: обработчики событий D7, ORM Bitrix для операций с базой данных, кеширование через модуль main, интеграции с внешними API через Guzzle HTTP-клиент. Для платёжных шлюзов применяем официальные SDK банков и платёжных систем — это гарантирует стабильность и безопасность операций возврата денег. Тестирование проводится на staging-стенде с полной копией production-данных перед выкаткой изменений в боевую среду.







