Задача: автоматическое удаление заказов по ссылке без подтверждения
В WooCommerce часто возникает необходимость быстро удалить заказ, например, в административных скриптах или массовом управлении через пользовательский интерфейс. По умолчанию удаление заказа требует подтверждения через стандартный UI, что неудобно для автоматизации. В этой статье разберём, как создать ссылку для удаления заказа без запроса подтверждения, но при этом максимально безопасно.
Диагностика проблемы
Стандартный механизм удаления заказа в WooCommerce реализован через интерфейс WordPress с nonce и подтверждением действия. При попытке создать прямую ссылку для удаления заказа без подтверждения мы сталкиваемся с рядом проблем:
- Отсутствие nonce приводит к уязвимости CSRF (межсайтовая подделка запросов).
- Удаление без проверки прав пользователя опасно — любой посетитель может удалить заказы.
- Простое прямое обращение к URL с id заказа не работает из-за проверки nonce и ролей.
Поэтому задача — создать безопасный механизм удаления через ссылку, который:
- Проверяет права пользователя (например, только администратор или менеджер заказа).
- Использует nonce для защиты от CSRF.
- Обрабатывает запрос без отображения дополнительных форм и подтверждений.
Пошаговое решение
1. Добавляем обработчик запроса через AJAX или пользовательский endpoint
Для реализации безопасной ссылки создадим кастомный эндпоинт с параметрами, который будет принимать ID заказа и nonce, проверять права и удалять заказ.
add_action('init', function() {
if (isset($_GET['delete_order_id']) && isset($_GET['_wpnonce'])) {
$order_id = intval($_GET['delete_order_id']);
$nonce = sanitize_text_field($_GET['_wpnonce']);
if (!wp_verify_nonce($nonce, 'delete_order_' . $order_id)) {
wp_die('Ошибка безопасности: неверный nonce');
}
if (!current_user_can('delete_post', $order_id)) {
wp_die('Ошибка доступа: недостаточно прав');
}
$order = wc_get_order($order_id);
if (!$order) {
wp_die('Заказ не найден');
}
// Удаляем заказ
wp_delete_post($order_id, true);
// Перенаправляем обратно или выводим сообщение
wp_redirect(remove_query_arg(['delete_order_id', '_wpnonce']));
exit;
}
});2. Генерируем ссылку удаления с nonce
Генерация ссылки должна быть доступна только пользователям с правами удаления заказов. Используем функцию wp_create_nonce() с уникальным ключом по ID заказа:
function get_delete_order_link($order_id) {
if (!current_user_can('delete_post', $order_id)) {
return '';
}
$nonce = wp_create_nonce('delete_order_' . $order_id);
return add_query_arg([
'delete_order_id' => $order_id,
'_wpnonce' => $nonce
], home_url());
}Проверка результата после внедрения
Чтобы проверить, что удаление работает:
- Войдите на сайт под пользователем с правами администратора или менеджера заказов.
- Получите ссылку для удаления заказа, вызвав
get_delete_order_link($order_id). - Перейдите по ссылке в браузере.
- Проверьте, что заказ исчез из админки WooCommerce и из базы данных (таблица
wp_posts). - Попробуйте перейти по ссылке под пользователем без прав — должно появиться сообщение об ошибке доступа.
- Попробуйте изменить nonce — должна возникнуть ошибка безопасности.
Частые ошибки и как исправить
- Ошибка: Заказ не удаляется, появляется сообщение «недостаточно прав».
Проверьте, что пользователь действительно имеет правоdelete_postна тип записиshop_order. Для кастомных ролей можно добавить черезadd_cap. - Ошибка: Происходит перенаправление, но заказ остаётся.
Проверьте, чтоwp_delete_post($order_id, true)вызывается и что заказ существует. Возможно, заказ уже удалён или ID неверен. - Ошибка: Неверный nonce.
Убедитесь, что nonce генерируется и проверяется с одним и тем же ключом (например,'delete_order_' . $order_id). - Ошибка: Ссылка доступна анонимным пользователям.
Добавьте проверку правcurrent_user_canдо вывода ссылки и в обработчике.
Практические советы по безопасности и производительности
- Используйте
wp_verify_nonceдля защиты от CSRF. - Ограничьте возможность удаления только администраторам или менеджерам заказов.
- Для массового удаления лучше использовать AJAX с подтверждением и логированием действий.
- Удаление заказов — необратимая операция, рекомендуется создавать резервные копии базы перед применением.
- Если требуется удалять заказы по условию (например, старые или отменённые), реализуйте отдельные WP-CLI команды или cron-задачи с логированием.
Сравнение вариантов реализации удаления заказов
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
| Стандартное удаление через админку | Удаление с подтверждением UI | Безопасно, понятно для пользователя | Не подходит для автоматизации |
| Удаление по ссылке с nonce (описано в статье) | Прямая ссылка с проверками | Быстро, можно интегрировать в UI | Требует ручного контроля безопасности |
| Удаление через WP-CLI | Командная строка для массового удаления | Массовое удаление, автоматизация | Не подходит для пользователей без доступа к серверу |