Диагностика проблемы с оплатой в WooCommerce
Многие магазины на WooCommerce сталкиваются с проблемой, когда заказы остаются в статусе "В ожидании оплаты" или "Обработка" после неудачной попытки оплаты. Это создает накладные расходы на обслуживание и искажает статистику. Задача — автоматизировать отмену таких заказов и возврат средств (если средства списались), чтобы не держать открытые "зависшие" заказы.
Как понять, что заказ завис из-за проблемы с оплатой
- Статус заказа не меняется в течение длительного времени (например, 1 час и дольше).
- В логах платежного шлюза или WooCommerce есть записи об ошибках оплаты.
- Покупатель жалуется, что оплата не прошла, но заказ создан.
Пошаговое решение: автоматическая отмена заказов с проблемами оплаты
Рассмотрим реализацию на PHP, которая с помощью WP Cron будет проверять заказы в статусе pending или on-hold старше заданного времени и автоматически отменять их.
add_action('woocommerce_cancel_unpaid_orders_event', 'wc_cancel_unpaid_orders_callback');
function wc_cancel_unpaid_orders_callback() {
$threshold = strtotime('-1 hour'); // Время ожидания оплаты
$args = [
'limit' => -1,
'status' => ['pending', 'on-hold'],
'date_created' => '<' . date('Y-m-d H:i:s', $threshold),
];
$orders = wc_get_orders($args);
foreach ($orders as $order) {
// Если заказ уже отменен, пропускаем
if ($order->has_status('cancelled')) continue;
// Проверяем статус оплаты
if (!$order->is_paid()) {
$order->update_status('cancelled', 'Автоматическая отмена: оплата не получена в течение часа.');
// Если были списания, инициируем возврат (зависит от шлюза)
if ($order->get_transaction_id()) {
wc_process_refund_for_order($order);
}
}
}
}
// Планируем событие при активации темы или плагина
if (!wp_next_scheduled('woocommerce_cancel_unpaid_orders_event')) {
wp_schedule_event(time(), 'hourly', 'woocommerce_cancel_unpaid_orders_event');
}
// Функция возврата средств
function wc_process_refund_for_order($order) {
$refund = wc_create_refund([
'amount' => $order->get_total(),
'reason' => 'Автоматический возврат из-за неоплаты',
'order_id' => $order->get_id(),
]);
if (is_wp_error($refund)) {
error_log('Ошибка возврата для заказа #' . $order->get_id() . ': ' . $refund->get_error_message());
}
}
Как подключить и протестировать решение
1. Вставьте код в functions.php дочерней темы или в отдельный плагин.
2. Создайте тестовый заказ в статусе pending без оплаты.
3. Подождите 1 час (или измените strtotime в коде для теста на 5 минут назад).
4. Проверьте, что статус заказа сменился на cancelled и в заметках заказа есть комментарий об отмене.
5. Если есть транзакция, убедитесь, что возврат инициирован (в платежной системе и логах).
Проверка результата после внедрения
- Заказы в статусе
pendingстарше 1 часа автоматически становятсяcancelled. - Отмена сопровождается заметкой в истории заказа.
- При наличии платежа создается возврат.
- Логи ошибок возврата отсутствуют или фиксируются для анализа.
Частые ошибки и как исправить
- Отмена не срабатывает: проверьте, запланировано ли событие WP Cron (
wp_next_scheduled('woocommerce_cancel_unpaid_orders_event')). - Возврат не создается: убедитесь, что платежный шлюз поддерживает автоматические возвраты через WooCommerce, иначе потребуется кастомная интеграция API платежного сервиса.
- Заказы отменяются раньше времени: скорректируйте значение времени в
strtotime('-1 hour')на более подходящее. - Ошибки в логах: проверьте правильность передачи параметров в
wc_create_refundи права пользователя, под которым выполняется скрипт.
Практические советы по безопасности и производительности
- Не используйте слишком короткий таймаут отмены, чтобы не мешать оплате клиентов.
- Для большого количества заказов делайте выборку порциями (
limitиpagedвwc_get_orders), чтобы не перегружать память. - Логи ошибок записывайте в отдельный файл или используйте мониторинг, чтобы оперативно реагировать.
- Для возвратов лучше использовать официальные API шлюзов, если WooCommerce не поддерживает автоматический возврат по умолчанию.
Таблица сравнения вариантов решения
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
| WP Cron + wc_get_orders + update_status | Автоматическая отмена заказов старше таймаута | Простая реализация, нет сторонних плагинов | Зависит от WP Cron, может задерживать выполнение |
| Плагин сторонний (например, WooCommerce Order Status Control) | Готовое решение с настройками | Простота настройки, поддержка | Доп. нагрузка, платные функции |
| Пользовательский скрипт с API платежей | Автоматический возврат через API шлюза | Гибкость, точный контроль возвратов | Сложность реализации, требует знаний API |