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

Диагностика проблемы с возвратами в WooCommerce

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

Как понять, что нужна автоматизация возвратов

  • Много заказов с запросами на возврат, которые затягиваются
  • Ручная проверка сроков возврата занимает много времени
  • Частые жалобы клиентов из-за задержек с возвратом средств

Пошаговое решение: автоматический возврат средств по сроку возврата

Для реализации автоматического возврата средств по истечении срока возврата (например, 14 дней с даты получения) можно использовать пользовательский скрипт с WP-Cron.

1. Добавление пользовательского поля с датой получения заказа

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

add_action('woocommerce_order_status_completed', 'set_order_received_date');
function set_order_received_date($order_id) {
    $order = wc_get_order($order_id);
    if (!$order->get_meta('_date_received')) {
        $order->update_meta_data('_date_received', current_time('Y-m-d'));
        $order->save();
    }
}

2. Создание WP-Cron задачи для проверки и возврата денег

Добавим событие, которое будет запускаться ежедневно и проверять заказы с истекшим сроком возврата.

add_action('wp', 'schedule_refund_event');
function schedule_refund_event() {
    if (!wp_next_scheduled('auto_refund_expired_orders')) {
        wp_schedule_event(time(), 'daily', 'auto_refund_expired_orders');
    }
}

add_action('auto_refund_expired_orders', 'process_expired_refunds');
function process_expired_refunds() {
    $args = [
        'limit' => -1,
        'status' => 'completed',
        'meta_key' => '_date_received',
        'meta_compare' => 'EXISTS',
    ];
    $orders = wc_get_orders($args);
    $refund_period_days = 14;
    foreach ($orders as $order) {
        $date_received = $order->get_meta('_date_received');
        if (!$date_received) continue;

        $received_timestamp = strtotime($date_received);
        $expiry_timestamp = strtotime("+{$refund_period_days} days", $received_timestamp);

        if (time() > $expiry_timestamp && 'completed' === $order->get_status()) {
            // Проверяем, были ли уже возвраты
            if (!$order->get_refunds()) {
                // Создаем возврат
                $refund = wc_create_refund([
                    'amount' => $order->get_total(),
                    'reason' => 'Автоматический возврат по истечении срока',
                    'order_id' => $order->get_id(),
                    'refund_payment' => true,
                ]);
                if (is_wp_error($refund)) {
                    error_log('Ошибка возврата для заказа ' . $order->get_id() . ': ' . $refund->get_error_message());
                } else {
                    // Меняем статус заказа на refunded
                    $order->update_status('refunded', 'Автоматический возврат средств.');
                }
            }
        }
    }
}

3. Активируем задачу при деактивации плагина или темы

register_deactivation_hook(__FILE__, 'remove_scheduled_refund_event');
function remove_scheduled_refund_event() {
    $timestamp = wp_next_scheduled('auto_refund_expired_orders');
    if ($timestamp) {
        wp_unschedule_event($timestamp, 'auto_refund_expired_orders');
    }
}

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

  • Создайте тестовый заказ, поставьте статус completed и добавьте дату получения в метаполе _date_received в базе данных или через код.
  • Измените дату _date_received на дату, которая превышает срок возврата (например, 15 дней назад).
  • Запустите вручную хук auto_refund_expired_orders с помощью плагина WP Crontrol или вызовом функции process_expired_refunds();.
  • Проверьте, что заказ изменил статус на refunded и создан возврат в админке WooCommerce.

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

  • Отсутствует дата получения заказа: без метаполя _date_received скрипт не сможет определить срок возврата. Убедитесь, что дата записывается при изменении статуса заказа.
  • Проблемы с WP-Cron: если на сайте малый трафик, задачи WP-Cron могут не запускаться. Настройте системный cron или используйте плагины для отладки.
  • Ошибка возврата из-за платежного шлюза: автоматический возврат может не поддерживаться шлюзом, либо требует дополнительных настроек. Проверьте логи ошибок и документацию платежной системы.
  • Дублирование возвратов: скрипт проверяет наличие возвратов у заказа, чтобы не создавать дубли. Если дубли появляются, проверьте корректность проверки $order->get_refunds().

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

  • Ограничивайте выборку заказов в запросах WP_Query или wc_get_orders, чтобы не перегружать сервер при большом количестве заказов.
  • Настройте логирование ошибок возврата в отдельный файл для удобного мониторинга без засорения основного лога.
  • Используйте nonce и проверку прав при реализации интерфейсов администрирования для управления датами получения и возвратами.
  • Обязательно тестируйте автоматизацию на тестовом сайте и с тестовыми платежными шлюзами.

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

МетодПлюсыМинусыПример
Плагин готовыйБыстрая установка, поддержкаМожет быть платным, менее гибкийWooCommerce Smart Refunder
Кастомный код с WP-CronПолный контроль, бесплатныйТребует навыков программирования, тестированияПример из статьи
Ручной возврат в админкеПростота, без кодаВысокая нагрузка, ошибкиСтандартный WooCommerce интерфейс
Как закрыть от индексации страницы авторов и архивов в WordPress
25.08.2026