WooCommerce: как автоматически удалять бонусные баллы после возврата товара

Диагностика проблемы: бонусные баллы не списываются при возврате

В интернет-магазинах на WooCommerce часто используется система бонусных баллов для лояльности клиентов. Однако при возврате товара начисленные баллы по-прежнему остаются у пользователя, что ведет к некорректной работе системы мотивации и финансовым потерям.

Проверить проблему можно так:

  • Возвратите товар через стандартный механизм возврата WooCommerce или вручную измените статус заказа на "Возвращен" (refunded).
  • Проверьте, остались ли начисленные баллы на счету пользователя.
  • Если баллы не списались автоматически, значит, необходимо реализовать кастомное решение для синхронизации бонусов с возвратами.

Пошаговое решение: автоматическое списание бонусных баллов при возврате заказа

1. Определяем событие возврата

WooCommerce запускает хук woocommerce_order_refunded при возврате заказа. Именно на него будем вешать нашу логику.

2. Получаем данные о бонусных баллах заказа

В зависимости от используемого плагина бонусных баллов (например, myCred, WooCommerce Points and Rewards или собственной реализации) нужно получить сумму начисленных баллов, связанных с возвратом.

Для примера возьмем простую систему, где баллы хранятся в метаполях заказа _earned_points.

3. Списываем баллы у пользователя

Напишем функцию, которая при возврате заказа вычтет соответствующее количество баллов из профиля пользователя.

add_action('woocommerce_order_refunded', 'remove_bonus_points_on_refund', 10, 2); 
function remove_bonus_points_on_refund($order_id, $refund_id) {
    $order = wc_get_order($order_id);
    if (!$order) return;

    $user_id = $order->get_user_id();
    if (!$user_id) return;

    // Получаем количество начисленных баллов из мета заказа
    $earned_points = (int) get_post_meta($order_id, '_earned_points', true);
    if ($earned_points <= 0) return;

    // Получаем текущий баланс баллов пользователя
    $current_points = (int) get_user_meta($user_id, '_user_bonus_points', true);

    // Вычитаем баллы
    $new_points = max(0, $current_points - $earned_points);
    update_user_meta($user_id, '_user_bonus_points', $new_points);

    // Логируем действие для отладки
    error_log("[BonusPoints] Списано $earned_points баллов у пользователя $user_id за возврат заказа $order_id.");
}

Проверка результата после внедрения

  • Создайте тестовый заказ, начислите баллы (например, вручную в метаполе _earned_points и в пользовательском мета _user_bonus_points).
  • Верните заказ через WooCommerce.
  • Проверьте баланс баллов пользователя через базу данных или с помощью кода:
$points = get_user_meta($user_id, '_user_bonus_points', true);
echo "Текущий баланс баллов: $points";

Если баллы уменьшились на сумму возврата, решение работает корректно.

Частые ошибки и как их исправить

  • Баллы не списываются: проверьте, что хук woocommerce_order_refunded срабатывает и функция подключена.
  • Баллы хранятся в другом плагине: изучите API плагина бонусов — там наверняка есть функции для списания и начисления баллов, используйте их вместо прямого обновления метаполей.
  • Не учитываются частичные возвраты: если возврат частичный, нужно получить сумму баллов пропорционально возвращенным товарам. Для этого нужно доработать логику, учитывая сумму возврата и сумму заказа.
  • Пользователь анонимный: если заказ оформлен без регистрации, то списать баллы нельзя — нужно предусмотреть обработку этого случая.

Практические советы по безопасности и производительности

  • Используйте транзакции и проверки в случае сложных операций с базой данных, чтобы избежать рассогласования баллов.
  • Логируйте изменения баллов для аудита и отладки, но не оставляйте подробные логи в продакшне.
  • Кэшируйте значения баллов пользователя при частом обращении, чтобы снизить нагрузку на базу.
  • Если используете сторонние плагины для бонусов, обновляйте их и проверяйте совместимость с WooCommerce после обновлений.

Сравнение вариантов реализации автоматического списания баллов

МетодПлюсыМинусыПример использования
Прямое обновление метаполейПростота, контроль кодаТребует знания структуры данных, риск ошибокПример кода выше
Использование API плагина бонусовГарантия корректности, поддержка обновленийЗависимость от плагина, сложность интеграцииmyCred: mycred_subtract('refunded_order', $user_id, $points);
Ручной контроль через админкуМаксимальный контрольНеавтоматично, требует времениРедактирование баллов в профиле пользователя
WordPress: как создать динамическое меню с подменю через код
08.01.2026
WooCommerce: как предотвратить повторные заказы после успешной оплаты
29.06.2026
Как создать автоматический импорт данных из Google Analytics в WordPress
11.03.2026
Как удалить и заблокировать IP-адреса в WordPress: практическое руководство
09.04.2026
Как добавить поле в форму регистрации WordPress: плагины и код
04.01.2026