Диагностика проблемы с изменением адреса доставки после оформления заказа
В WooCommerce по умолчанию покупатель может изменить адрес доставки в личном кабинете даже после оформления заказа, что нередко приводит к путанице в логистике и проблемам с доставкой. Если вы столкнулись с ситуацией, когда клиенты изменяют адреса доставки, а заказы уже обрабатываются или отправлены — стоит ограничить такую возможность.
Типичные признаки проблемы:
- Клиенты меняют адрес доставки в разделе «Мои заказы» после оформления заказа.
- Заказы с изменённым адресом уже на стадии сборки или доставки.
- Невозможность контролировать актуальность информации для логистики.
Пошаговое решение: блокируем изменение адреса доставки после оформления заказа
1. Запрет редактирования адреса доставки через интерфейс пользователя
Для этого добавим фильтр, который скроет форму редактирования адреса доставки для заказов в статусе, начиная с «обрабатывается» и выше.
add_filter('woocommerce_my_account_edit_address_available', 'disable_edit_shipping_address_after_order', 10, 3);
function disable_edit_shipping_address_after_order($is_available, $load_address, $user_id) {
// Проверяем, редактируется ли адрес доставки
if ($load_address !== 'shipping') {
return $is_available;
}
// Получаем заказы пользователя
$orders = wc_get_orders(array(
'customer_id' => $user_id,
'status' => array('processing', 'completed', 'on-hold', 'pending'),
'limit' => 1,
'orderby' => 'date',
'order' => 'DESC',
));
// Если есть хотя бы один заказ в статусе, запрещаем редактирование
if (!empty($orders)) {
return false;
}
return $is_available;
}Этот код проверяет, есть ли у пользователя заказы со статусом, при котором адрес доставки уже не должен изменяться. Если такие заказы есть, форма редактирования адреса становится недоступна.
2. Защита от изменения адреса доставки через REST API и прямые запросы
Клиенты могут попытаться изменить адрес напрямую через запросы API или формы. Чтобы заблокировать такие попытки, используйте хук woocommerce_customer_save_address и проверяйте статус заказов перед сохранением.
add_action('woocommerce_customer_save_address', 'prevent_shipping_address_change_after_order', 10, 2);
function prevent_shipping_address_change_after_order($user_id, $load_address) {
if ($load_address !== 'shipping') {
return;
}
$orders = wc_get_orders(array(
'customer_id' => $user_id,
'status' => array('processing', 'completed', 'on-hold', 'pending'),
'limit' => 1,
));
if (!empty($orders)) {
// Откатываем изменения адреса доставки
wc_add_notice(__('Редактирование адреса доставки невозможно, так как у вас есть активные заказы.'), 'error');
// Принудительно прерываем сохранение, можно перезагрузить страницу или вернуть ошибку
wp_redirect(wc_get_account_endpoint_url('edit-address/shipping'));
exit;
}
}Проверка результата после внедрения
- Зайдите под пользователем с оформленными заказами (статус «обрабатывается» или выше).
- Перейдите в личный кабинет, раздел «Адреса» и попробуйте отредактировать адрес доставки — опция должна быть недоступна.
- Попытайтесь отправить прямой POST-запрос на изменение адреса доставки — получите ошибку и редирект.
- Для пользователей без активных заказов редактирование адреса остается доступным.
Частые ошибки и как их исправить
- Редактирование адреса доступно, несмотря на код. Проверьте, что код добавлен в functions.php активной темы или в кастомный плагин, и что нет конфликтов с другими плагинами, которые могут переопределять функционал адресов.
- После попытки изменить адрес без ошибки происходит молчаливое игнорирование. Добавьте в код вывод уведомлений через
wc_add_noticeи убедитесь, что шаблоны WooCommerce поддерживают их отображение. - Изменения адреса доступны для некоторых статусов заказов. Уточните, какие статусы должны блокировать редактирование, и добавьте их в массив статусов в коде.
Практические советы по безопасности и производительности
- Проверяйте количество запросов к базе данных при использовании
wc_get_orders— ограничивайте выборку (параметрlimit). - Кэшируйте результаты проверки, если пользователь часто заходит на страницу редактирования адреса, чтобы уменьшить нагрузку.
- Используйте хук
woocommerce_customer_save_addressдля защиты от обхода через REST API и прямые POST-запросы. - Регулярно обновляйте WooCommerce и тестируйте, чтобы код не перестал работать после обновлений.
Сравнение способов реализации ограничения редактирования адреса доставки
| Метод | Преимущества | Недостатки |
|---|---|---|
| Отключение формы редактирования через фильтр | Простая реализация, не требует плагинов | Может быть обойдено через прямые запросы |
Блокировка сохранения через хук woocommerce_customer_save_address | Защищает от прямых запросов и API | Требует дополнительной обработки ошибок и уведомлений |
| Использование сторонних плагинов для контроля адресов | Готовые решения с интерфейсом и настройками | Может влиять на производительность, требует поддержки |