Перейти к содержимому

Возврат покупателю - отмена оплаты, чек возврата, склад

Оформляем возврат так, чтобы деньги, чек, склад и учётная система рассказывали одну и ту же историю, а не три разные.

Решение

Отмечаем возврат в оплате заказа:

$order = \Bitrix\Sale\Order::load($orderId);
$payment = $order->getPaymentCollection()->getItemById($paymentId);
$payment->setReturn('Y'); // признак возврата у самой оплаты
$order->save();
// без этой отметки заказ остаётся оплаченным во всех отчётах

Возврат начинается с отметки в самой оплате. Пока её нет, заказ считается оплаченным: он попадает в выручку, в отчёты и в выгрузку в учётную систему как обычная продажа.

Возвращаем деньги платёжной системой:

$service = \Bitrix\Sale\PaySystem\Manager::getObjectById($payment->getPaymentSystemId());
$result = $service->refund($payment, $sum);
if (!$result->isSuccess()) {
AddMessage2Log(implode('; ', $result->getErrorMessages()), 'vendor.shop');
return; // без успешного возврата дальше идти нельзя
}

Деньги возвращает та же платёжная система, которой платили. Возврат руками из личного кабинета банка оставляет сайт в неведении, и сверка в конце месяца показывает расхождение без объяснений.

Пробиваем чек возврата:

use Bitrix\Sale\Cashbox\CheckManager;
CheckManager::addChecks([$payment]); // при отметке возврата это чек возврата
// тип чека определяется признаком возврата у оплаты, а не отдельным вызовом
// очередь чеков после возврата проверяют так же, как после оплаты

У возврата свой чек, а не отмена прежнего. Он уходит в ту же очередь и точно так же может там застрять, поэтому смотреть на неё после возврата нужно не меньше, чем после оплаты.

Возвращаем товар на склад:

foreach ($order->getShipmentCollection() as $shipment) {
if (!$shipment->isSystem()) { $shipment->tryUnship(); } // снимаем отгрузку
}
$order->save();
// после этого позиции снова доступны к продаже

Позиции заказа возвращают на склад отдельным и совершенно явным шагом самого кода. Деньги ушли обратно, а товар так и числится отгруженным - это самое частое состояние заказа, возвращённого наполовину вручную.

Частичный возврат считают по позициям, а не на глаз. Доставка при возврате одной позиции из трёх обычно не возвращается, и это правило магазин формулирует до первого случая, а не в момент спора.

Причину возврата стоит хранить рядом с заказом. Десяток возвратов по одной причине - это разговор с поставщиком или правка карточки, а не случайность.

Возврат в учётной системе и возврат на сайте должны совпадать. Расхождение находят сверкой, и чем реже она делается, тем дороже обходится.

Типичные проблемы

Заказ вернули, а он числится оплаченным.

Деньги вернули из личного кабинета банка, минуя сайт. Возврат начинают с отметки о нём в самой оплате этого самого заказа.

Чек возврата не пробит.

Чек ушёл в очередь и застрял там с ошибкой. Очередь чеков после возврата смотрят так же, как после оплаты.

Товар не вернулся в продажу.

Отгрузка по этому заказу так и осталась проведённой в самой системе учёта. Позиции возвращают на склад отдельным шагом.

При частичном возврате вернули лишнее.

Сумма посчитана на глаз, вместе с доставкой. Частичный возврат считают строго по позициям самого этого заказа этого покупателя.

В отчётах выручка выше реальной.

Возвраты нигде не отражены и не вычитаются из суммы. Признак возврата обязательно учитывают в фильтре любого отчёта по общей выручке магазина.

Частые вопросы

Чем полный возврат отличается от частичного?

Суммой и составом: частичный возвращает часть позиций. Признак возврата у оплаты при этом бывает и частичным.

Возвращать ли стоимость доставки?

Обычно нет, если товар уже везли. Правило формулируют заранее и пишут в условия магазина.

Нужен ли чек возврата всегда?

Если чек при оплате пробивался - да, возврат оформляют своим чеком. Это требование закона, а не настройка.

Как отразить возврат в учётной системе?

Обменом, вместе с остальными изменениями заказа. Руками в двух местах данные расходятся быстро.

Смежное

Первоисточник