Налаштування автоматичної обробки повернень 1С-Бітрікс
Автоматизація повернень потрібна там, де обсяг перевищує 20–30 заявок на день і менеджер витрачає суттєвий час на рутинні операції: перевірити оплату замовлення, створити повернення в 1С, провести повернення коштів, надіслати лист покупцю. Кожну з цих дій можна запустити автоматично при зміні статусу заявки — через обробники подій модуля sale та агенти Бітрікс.
Подієва модель повернень
Модуль 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, Тінькофф тощо)
- Агент трекінгу вхідних посилок (Укрпошта, СДЕК, Нова Пошта)
- Агент SLA-моніторингу з ескалацією прострочених заявок
- Email-автоматика: шаблони під кожен статус
Терміни: базова автоматизація (повідомлення + автоповернення коштів) — 2–3 тижні. Повний стек із SLA-моніторингом і трекінгом — 4–6 тижнів.







