fix: autopay renewing trial subscriptions at classic-mode pricing

Three bugs caused trial subscriptions to be auto-renewed without a
tariff at arbitrary prices:

1. try_auto_extend_expired_after_topup: is_trial guard used truthiness
   check — NULL (legacy rows) passed as falsy. Changed to
   `is_trial is not False` (NULL-safe).

2. Multi-tariff branch: `not s.is_trial` treated NULL as not-trial.
   Changed to `s.is_trial is False`.

3. Telegram bot autopay toggle: no is_trial guard — users could enable
   autopay on trial subscriptions. Added trial check before enabling.
This commit is contained in:
Fringg
2026-04-29 08:16:39 +03:00
parent 422844d78d
commit 2fbdbf5ab0
2 changed files with 15 additions and 2 deletions
+12
View File
@@ -101,6 +101,18 @@ async def toggle_autopay(callback: types.CallbackQuery, db_user: User, db: Async
enable = callback.data.startswith('autopay_enable')
if enable:
# Trial subscriptions cannot use autopay
if subscription.is_trial or subscription.is_trial is None:
texts = get_texts(db_user.language)
await callback.answer(
texts.t(
'AUTOPAY_NOT_AVAILABLE_TRIAL',
'Автоплатеж недоступен для пробных подписок.',
),
show_alert=True,
)
return
# Classic subscriptions cannot use autopay when tariff mode is enabled
if settings.is_tariffs_mode() and not subscription.tariff_id:
texts = get_texts(db_user.language)
@@ -2138,7 +2138,7 @@ async def try_auto_extend_expired_after_topup(
from app.database.crud.subscription import get_all_subscriptions_by_user_id
all_subs = await get_all_subscriptions_by_user_id(db, user.id)
expired_subs = [s for s in all_subs if s.status == SubscriptionStatus.EXPIRED.value and not s.is_trial]
expired_subs = [s for s in all_subs if s.status == SubscriptionStatus.EXPIRED.value and s.is_trial is False]
if not expired_subs:
subscription = None
else:
@@ -2154,9 +2154,10 @@ async def try_auto_extend_expired_after_topup(
return False
# Only process expired subscriptions (not trial, not disabled)
# NULL-safe: is_trial can be None in legacy rows — treat as trial
if subscription.status != SubscriptionStatus.EXPIRED.value:
return False
if subscription.is_trial:
if subscription.is_trial is not False:
return False
# Only process subscriptions expired within the last 30 days