Диагностика проблемы: почему нужно отключать оплату вручную?
В стандартной логике WooCommerce оплата заказа блокируется автоматически при отмене заказа, но в некоторых случаях, особенно при кастомных методах оплаты или интеграциях с внешними платежными шлюзами, статус оплаты остается активным. Это может привести к тому, что клиент ошибочно продолжит попытки оплаты или возникнут сложности с бухгалтерией.
Основные причины проблемы:
- Кастомные статусы заказа, не учитываемые платежным модулем.
- Отсутствие синхронизации статуса оплаты и статуса заказа.
- Проблемы с вебхуками платежного шлюза.
Пошаговое решение: как автоматически отключать оплату при отмене заказа
1. Отслеживаем событие отмены заказа
WooCommerce генерирует событие woocommerce_order_status_cancelled при смене статуса заказа на «отменён». Используем этот хук, чтобы запускать логику отключения оплаты.
2. Обновляем статус оплаты заказа
В WooCommerce для управления статусом оплаты используется метод update_status() и свойства объекта заказа. Отключение оплаты означает перевод заказа в статус, где оплата неактивна, например, «on-hold» или кастомный статус без оплаты.
add_action('woocommerce_order_status_cancelled', 'disable_payment_on_order_cancelled', 10, 1);
function disable_payment_on_order_cancelled($order_id) {
$order = wc_get_order($order_id);
if (!$order) return;
// Сбрасываем статус оплаты
$order->set_payment_method_title('Оплата отключена');
$order->set_payment_method(''); // убираем метод оплаты
$order->update_meta_data('_payment_complete', false);
$order->save();
}
3. Интеграция с кастомными платежными шлюзами
Если используется кастомный платежный шлюз, необходимо обеспечить, чтобы он реагировал на смену статуса заказа. Обычно это делается через соответствующие методы класса платежного шлюза. Добавьте вызов очистки статуса оплаты:
add_action('woocommerce_order_status_cancelled', 'custom_gateway_disable_payment', 20, 1);
function custom_gateway_disable_payment($order_id) {
$order = wc_get_order($order_id);
if (!$order) return;
$payment_method = $order->get_payment_method();
if ($payment_method === 'custom_gateway_id') {
// Вызовите метод вашего шлюза для отмены оплаты
$gateway = WC()->payment_gateways()->payment_gateways()[$payment_method];
if (method_exists($gateway, 'cancel_payment')) {
$gateway->cancel_payment($order);
}
}
}
Проверка результата после внедрения
После внедрения кода выполните следующие шаги:
- Создайте тестовый заказ с выбранной платежной системой.
- Отмените заказ через админку WooCommerce.
- Проверьте, что статус оплаты заказа сброшен или изменен на «Оплата отключена».
- Убедитесь, что клиент не может повторно оплатить отменённый заказ.
- При использовании кастомного шлюза проверьте логи и уведомления платежной системы.
Частые ошибки и их исправление
- Код не срабатывает при смене статуса. Проверьте правильность хуков и приоритеты. Используйте
woocommerce_order_status_cancelledименно для отмены. - Оставшийся метод оплаты не сбрасывается. Убедитесь, что вызывается
$order->set_payment_method('')и сохраняется заказ$order->save(). - Кастомный шлюз не реагирует. Проверьте, что в классе шлюза реализован метод отмены платежа и он вызывается.
- Пользователь видит кнопку «Оплатить» на отмененном заказе. Добавьте проверку в шаблон для скрытия кнопки при статусе «отменён».
Практические советы по безопасности и производительности
- Не используйте прямое изменение метаданных без проверки: всегда применяйте методы класса
WC_Order. - Для массовых изменений статусов используйте WP-CLI, чтобы избежать перегрузок при больших объемах заказов.
- Логируйте изменения статусов оплаты для последующего аудита.
- Если используете платежные шлюзы сторонних разработчиков, регулярно обновляйте их и проверяйте совместимость.
Чек-лист для внедрения автоматического отключения оплаты
- Добавить хук
woocommerce_order_status_cancelled. - В функции отключить метод оплаты и обновить мета данных.
- Если есть кастомный шлюз — реализовать метод отмены оплаты и вызвать его.
- Протестировать на тестовом заказе.
- Проверить отображение заказа на фронтенде и отсутствие кнопок оплаты.
- Добавить логирование и уведомления администратору (по желанию).