Проблема: как автоматически удалить пользователя после отмены подписки в WooCommerce
В WooCommerce с подписками (WooCommerce Subscriptions) часто возникает задача — удалить учетную запись пользователя сразу после отмены подписки. Это полезно для магазинов с контентом или сервисами, где доступ строго ограничен подпиской. По умолчанию WooCommerce не удаляет пользователя при отмене подписки, только меняет статус подписки, оставляя пользователя в базе. В статье разберём как реализовать автоматическое удаление пользователя при отмене подписки программно.
Диагностика проблемы: почему пользователь не удаляется автоматически
WooCommerce Subscriptions работает с подписками как отдельным типом данных. При отмене подписки WooCommerce просто меняет статус подписки на 'cancelled', но не трогает объект пользователя. Автоматическое удаление пользователя не является стандартным поведением — это сделано для сохранения истории заказов и данных.
Чтобы понять, почему пользователь не удаляется, можно проследить хук, который срабатывает при отмене подписки:
add_action('woocommerce_subscription_status_cancelled', 'my_callback_function');Этот хук вызывается, но по умолчанию не содержит логики удаления пользователя.
Пошаговое решение: автоматическое удаление пользователя при отмене подписки
1. Подключение к хуку отмены подписки
Используем хук woocommerce_subscription_status_cancelled для запуска удаления пользователя.
2. Получение ID пользователя из объекта подписки
Подписка — это объект типа WC_Subscription, у которого есть метод get_user_id().
3. Удаление пользователя программно
Используем функцию wp_delete_user($user_id) для удаления пользователя и всех связанных данных.
Пример кода для functions.php или кастомного плагина:
add_action('woocommerce_subscription_status_cancelled', 'delete_user_after_subscription_cancelled', 10, 1);
function delete_user_after_subscription_cancelled( $subscription ) {
if ( ! is_a( $subscription, 'WC_Subscription' ) ) {
return;
}
$user_id = $subscription->get_user_id();
if ( ! $user_id ) {
return;
}
// Проверка: удаляем только пользователей с ролью 'customer'
$user = get_userdata( $user_id );
if ( ! $user || ! in_array( 'customer', (array) $user->roles ) ) {
return;
}
// Удаляем пользователя и все его данные
wp_delete_user( $user_id );
}Проверка результата после внедрения
- Создайте тестовую подписку под тестовым пользователем с ролью 'customer'.
- Отмените подписку через админку WooCommerce или личный кабинет.
- Проверьте, что после отмены подписки пользователь удалён из базы (wp_users и wp_usermeta).
- Убедитесь, что при удалении не возникает ошибок.
Частые ошибки и как их исправить
- Пользователь не удаляется: Проверьте, что передаётся объект подписки с нужным ID пользователя.
- Удаляются неправильные пользователи: Добавьте проверку роли пользователя перед удалением, чтобы не удалить администратора или редактора.
- Ошибки PHP или фатальные ошибки: Проверьте, что код подключён и нет конфликтов с другими плагинами.
- История заказов «ломается» после удаления пользователя: Помните, что удаление пользователя удаляет все связанные данные, включая заказы. В таком случае, возможно, стоит подумать об анонимизации, а не удалении.
Практические советы по безопасности и производительности
- Всегда делайте бэкап базы перед внедрением автоматического удаления пользователей.
- Добавьте логирование удаления пользователей для аудита, например с помощью error_log() или сторонних логгеров.
- Подумайте о сценариях, когда пользователь может иметь несколько подписок — удалять только если это последняя активная.
- Если WooCommerce Subscriptions активно используется, тестируйте на staging-среде перед продакшеном.
Сравнение вариантов реализации
| Вариант | Плюсы | Минусы |
|---|---|---|
| Автоматическое удаление через хук | Простота, полная очистка данных | Можно потерять историю заказов, риск случайного удаления |
| Анонимизация пользователя | Сохраняется история заказов, безопасность данных | Сложнее реализовать, требует кастомного кода |
| Ручное удаление через админку | Контроль, минимальные риски | Затратно по времени, не автоматизировано |