Диагностика проблемы: почему нужно запретить изменение адреса доставки после оформления заказа
В стандартной установке WooCommerce покупатель может изменить адрес доставки в личном кабинете даже после оформления заказа. Это приводит к путанице на этапе обработки заказов, особенно если адрес уже передан курьеру или службе доставки. Чтобы избежать ошибок и снизить нагрузку на службу поддержки, стоит запретить изменение адреса доставки после оформления заказа.
Как отключить изменение адреса доставки после оформления заказа
Добавление проверки в личный кабинет WooCommerce
По умолчанию WooCommerce позволяет редактировать адреса через страницу "Мой аккаунт > Адреса". Мы можем запретить редактировать адрес доставки, если у пользователя есть оформленные заказы с этим адресом.
Для этого добавим следующий код в functions.php вашей темы или в кастомный плагин:
add_filter('woocommerce_my_account_get_addresses', 'disable_shipping_address_edit_after_order', 10, 1);
function disable_shipping_address_edit_after_order($address_types) {
$user_id = get_current_user_id();
if (!$user_id) return $address_types;
$has_orders = wc_customer_has_orders($user_id, 'completed'); // Проверяем наличие завершённых заказов
if ($has_orders) {
// Удаляем возможность редактирования адреса доставки
if (isset($address_types['shipping'])) {
unset($address_types['shipping']);
}
}
return $address_types;
}Функция wc_customer_has_orders проверяет, есть ли у пользователя хотя бы один завершённый заказ. Если есть — адрес доставки исключается из списка адресов для редактирования.
Блокировка изменения адреса доставки через REST API и другие методы
Чтобы предотвратить обход через REST API или кастомные запросы, добавим серверную проверку при сохранении адреса доставки:
add_action('woocommerce_customer_save_address', 'prevent_shipping_address_update_after_order', 10, 2);
function prevent_shipping_address_update_after_order($user_id, $load_address) {
if ($load_address !== 'shipping') return; // Проверяем только адрес доставки
$has_orders = wc_customer_has_orders($user_id, 'completed');
if ($has_orders) {
// Отменяем сохранение и возвращаем ошибку
wp_die('Изменение адреса доставки невозможно после оформления заказа.');
}
}Проверка результата после внедрения
- Зайдите в личный кабинет пользователя с завершёнными заказами.
- Перейдите в раздел "Адреса". Адрес доставки должен отсутствовать для редактирования.
- Попробуйте вручную отправить POST-запрос на обновление адреса доставки через REST API — должен появиться запрет.
- Проверьте, что для пользователей без заказов возможность редактирования адреса доставки осталась.
Частые ошибки и как их исправить
- Адрес доставки всё ещё доступен для редактирования — проверьте, что код добавлен в правильное место и активен. Убедитесь, что пользователь действительно имеет завершённые заказы.
- Ошибка wp_die слишком жёсткая для UX — вместо неё можно возвращать ошибку через AJAX или использовать
wc_add_noticeс редиректом. - Изменения не применяются при кэшировании — очистите кэш сайта и браузера.
Практические советы по безопасности и производительности
- Используйте хук
woocommerce_customer_save_addressдля серверной валидации, чтобы исключить обход через API. - Проверяйте статус заказов (например, "completed", "processing") по бизнес-логике, чтобы не блокировать изменение адреса преждевременно.
- Для больших магазинов с высокой нагрузкой кешируйте результат проверки наличия заказов в пользовательском мета, обновляя кеш при изменении статуса заказов.
Сравнение способов реализации
| Метод | Плюсы | Минусы |
|---|---|---|
| Удаление адреса доставки из личного кабинета (фильтр) | Простая реализация, хорошая UX | Не защищает от обхода через API |
| Серверная проверка с wp_die | Гарантированная блокировка на сервере | Жёсткий откат, может ухудшить UX |
| Использование плагинов для управления доступом | Готовые решения, поддержка | Дополнительная нагрузка, стоимость |