Диагностика проблем с лицензиями в WooCommerce подписках
При работе с комплексными подписками WooCommerce часто возникают проблемы с корректным управлением лицензиями плагинов или цифровых товаров. Типичные симптомы — дублирование лицензий, отсутствие обновлений после продления подписки, или невозможность отозвать лицензию при отмене подписки.
Для начала проверьте следующие моменты:
- Корректно ли связаны объекты лицензий с подписками в базе данных WP (таблицы
wp_postsи метаданныеwp_postmeta). - Работает ли триггер обновления лицензии при смене статуса подписки (например, с
activeнаcancelled). - Проверена ли логика проверки лицензий в плагине с учётом мультиактиваций или продлений.
Пример запроса для проверки связи лицензии и подписки в базе данных
SELECT p.ID AS license_id, pm.meta_value AS subscription_id
FROM wp_posts p
JOIN wp_postmeta pm ON pm.post_id = p.ID
WHERE p.post_type = 'license'
AND pm.meta_key = '_subscription_id'
AND pm.meta_value = '12345';Замените 12345 на ID вашей подписки. Если запрос не возвращает данных, связь не установлена, что влечёт ошибки.
Пошаговое решение для корректного управления лицензиями
1. Установка мета-связи лицензии и подписки
При создании лицензии в момент оформления подписки добавьте мета-данные для связи:
add_action('woocommerce_subscription_status_active', 'link_license_to_subscription', 10, 1);
function link_license_to_subscription($subscription) {
$user_id = $subscription->get_user_id();
$license_id = create_license_for_user($user_id); // Ваша функция генерации лицензии
update_post_meta($license_id, '_subscription_id', $subscription->get_id());
}2. Реализация обновления лицензии при продлении подписки
Используйте хук woocommerce_subscription_renewal_payment_complete, чтобы продлить срок действия лицензии:
add_action('woocommerce_subscription_renewal_payment_complete', 'extend_license_on_renewal', 10, 1);
function extend_license_on_renewal($subscription) {
$license_id = get_license_id_by_subscription($subscription->get_id());
if ($license_id) {
$expiry = strtotime(get_post_meta($license_id, '_expiry_date', true));
$new_expiry = max(time(), $expiry) + 30 * DAY_IN_SECONDS; // продлить на 30 дней
update_post_meta($license_id, '_expiry_date', date('Y-m-d', $new_expiry));
}
}3. Автоматический отзыв лицензии при отмене подписки
Отзовите лицензию при смене статуса подписки на отменённый или завершённый:
add_action('woocommerce_subscription_status_cancelled', 'revoke_license_on_cancellation', 10, 1);
add_action('woocommerce_subscription_status_expired', 'revoke_license_on_cancellation', 10, 1);
function revoke_license_on_cancellation($subscription) {
$license_id = get_license_id_by_subscription($subscription->get_id());
if ($license_id) {
update_post_meta($license_id, '_license_status', 'revoked');
}
}Проверка результата после внедрения
Чтобы убедиться, что решение работает:
- Создайте тестовую подписку и проверьте, что для неё автоматически создаётся и привязывается лицензия (через админку или SQL запрос).
- Продлите подписку вручную или через тестовый платеж — проверьте, что дата окончания лицензии обновилась.
- Отмените подписку — убедитесь, что статус лицензии изменился на
revoked. - Проверьте, что плагин, использующий лицензию, корректно реагирует на статус
revoked(например, блокирует обновления).
Частые ошибки и как их исправить
- Отсутствие связи лицензии и подписки. Решение — добавить мета-данные
_subscription_idпри создании лицензии. - Лицензия не продлевается при обновлении подписки. Проверьте подключение хука
woocommerce_subscription_renewal_payment_completeи корректность функции продления. - Отзыв лицензии не срабатывает. Убедитесь, что все нужные статусы подписок обрабатываются, и статус лицензии корректно обновляется.
- Дублирование лицензий при повторных подписках. Добавьте проверку на существующую активную лицензию перед созданием новой.
Практические советы по безопасности и производительности
- Используйте транзакции и проверяйте ошибки при обновлении мета-полей, чтобы избежать рассинхронизации.
- Кэшируйте часто используемые данные лицензий с помощью Transients API для уменьшения нагрузки на базу данных.
- Обязательно проверяйте права доступа при работе с лицензиями, чтобы избежать утечки данных.
- Для сложных сценариев интеграции рассмотрите создание REST API эндпоинтов для управления лицензиями с внешних сервисов.
Сравнение способов реализации связи лицензий и подписок
| Метод | Плюсы | Минусы | Рекомендации |
|---|---|---|---|
Использование мета-данных _subscription_id | Простая реализация, легко искать связи | Требует дополнительной логики управления при изменениях подписок | Рекомендуется для большинства случаев |
| Связь через собственные таблицы базы | Гибкость, масштабируемость | Сложнее в поддержке и интеграции | Использовать при больших проектах с множеством лицензий |
| REST API для управления лицензиями | Удалённое управление, интеграция с внешними сервисами | Требует дополнительной настройки безопасности | Рекомендуется для SaaS решений |