WooCommerce: автоматическое возврат средств при отмене заказа через код

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

Во многих интернет-магазинах на WooCommerce возникает задача автоматического возврата средств при отмене заказа. По умолчанию WooCommerce не проводит возврат денег автоматически при смене статуса заказа на «отменён» или «возврат», а только меняет статус заказа. Это часто приводит к ручному контролю и ошибкам в учёте возвратов.

Проверить, что автоматический возврат не работает, можно, изменив статус заказа в админке на «отменён» и посмотрев, списались ли деньги с платёжной системы, а также проверив статус платежа в админке WooCommerce.

Пошаговое решение: добавляем автоматический возврат средств через хуки WooCommerce

1. Проверяем платежный шлюз

Для автоматического возврата необходимо, чтобы платежный шлюз поддерживал API возврата (refund). Например, Stripe, PayPal, CloudPayments — у них есть соответствующие методы. В противном случае возврат нужно делать вручную.

2. Пишем функцию возврата при смене статуса заказа

Добавим код в functions.php вашей темы или в отдельный плагин. Код будет запускаться при смене статуса заказа на «cancelled» (отменён) и инициировать возврат средств:

add_action('woocommerce_order_status_cancelled', 'auto_refund_on_order_cancelled', 10, 1);
function auto_refund_on_order_cancelled($order_id) {
    if (!$order_id) return;
    $order = wc_get_order($order_id);
    if (!$order) return;

    // Проверяем, что заказ оплачен
    if ($order->get_payment_method() && $order->get_total() > 0 && $order->get_status() === 'cancelled') {
        $payment_gateway = wc_get_payment_gateway_by_order($order);
        if (!$payment_gateway) return;

        // Проверяем, поддерживает ли шлюз возврат
        if (method_exists($payment_gateway, 'process_refund')) {
            $refund_amount = $order->get_total() - $order->get_total_refunded();
            if ($refund_amount > 0) {
                $refund_reason = 'Автоматический возврат при отмене заказа #'.$order_id;
                $refund = $payment_gateway->process_refund($order_id, $refund_amount, $refund_reason);
                if (is_wp_error($refund)) {
                    error_log('Ошибка возврата для заказа #'.$order_id.': '.$refund->get_error_message());
                } else {
                    $order->add_order_note('Автоматический возврат средств выполнен: '.$refund_amount.' руб.');
                }
            }
        }
    }
}

// Вспомогательная функция для получения шлюза по заказу
function wc_get_payment_gateway_by_order($order) {
    $payment_method = $order->get_payment_method();
    $gateways = WC()->payment_gateways->payment_gateways();
    return isset($gateways[$payment_method]) ? $gateways[$payment_method] : false;
}

3. Тестируем на тестовом заказе

Создайте тестовый заказ с оплатой через поддерживаемый шлюз, затем измените статус на «отменён» через админку. Если возврат прошёл успешно, в истории заказа появится заметка с суммой возврата, а платеж будет возвращён.

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

  • Статус заказа изменился на «отменён» в WooCommerce.
  • В истории заказа появилась запись «Автоматический возврат средств выполнен: ...».
  • Счёт покупателя в платежной системе уменьшился на сумму заказа.
  • В WooCommerce в разделе «Возвраты» или «Refunds» отображается созданный возврат.

Частые ошибки и их устранение

  • Платёжный шлюз не поддерживает автоматический возврат
    Проверьте документацию вашего платежного шлюза. Если метод process_refund отсутствует, возврат придется делать вручную.
  • Возврат не создаётся, ошибка в логах
    Включите WP_DEBUG и посмотрите ошибки в error.log. Частая причина — неправильный ID заказа или неправильный формат данных при вызове API.
  • Возврат дублируется
    Добавьте проверку суммы, чтобы не делать возврат дважды по одному заказу.
  • Функция не срабатывает при смене статуса
    Проверьте, что хук woocommerce_order_status_cancelled используется, и что статус действительно меняется на «cancelled».

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

  • Выводите ошибки возврата в лог, но не на фронтенд, чтобы не раскрывать внутренние детали.
  • Проверяйте сумму возврата, чтобы не возвращать больше, чем оплачено.
  • Используйте асинхронные задачи (например, WP-Cron) для выполнения возвратов при большой нагрузке.
  • Убедитесь, что доступ к API платежного шлюза защищён и токены не хранятся в открытом виде.

Сравнение вариантов реализации возврата

МетодПлюсыМинусы
Ручной возврат через админку WooCommerceПростота, контрольРучной труд, риск ошибок
Автоматический возврат через хук и API шлюзаАвтоматизация, экономия времениЗависимость от поддержки API, сложность отладки
Плагин для возвратовГотовое решение, поддержкаДополнительные расходы, возможные конфликты
Как автоматизировать сбор и отчет по аналитике в WordPress
24.02.2026
WooCommerce: автоматическое отключение платежных методов при отказанном заказе
16.06.2026
Решение проблем с временем жизни transient в WordPress
15.04.2026
WooCommerce: решение проблем с неотображением вариаций товаров
23.05.2026
WooCommerce: автоматическое отключение платежных методов при отказанном заказе
03.06.2026