3.55.0 (2026-05-13)
New Features
- cabinet-rbac: split email trust — VK/Yandex verified for UX, untrusted for admin (7ebc485)
- payments: add per-method open_url_direct toggle for seamless MiniApp checkout (0b9c5c3)
- Поддержка кастомных Telegram Premium Emoji в кнопках для Menu Layout (Bot API 9.4+) (7c8f207)
Bug Fixes
- admin-notify: show real trial duration and traffic on activation (9955538)
- admin-notify: show real trial duration and traffic on activation (b58c997)
- admin: replace nonexistent User.preferred_location in country stats (51391f3)
- backup: respect BACKUP_TIME from cabinet, hot-reload scheduler on change (d6aa09a)
- buttons: strip leading unicode emoji when icon_custom_emoji_id is set (eef6dcd)
- cabinet-rbac: address H1/H2/M2/M3 from post-6cb272f6 audit (17a2e6f)
- cabinet-rbac: address remaining MEDIUM/LOW findings from full review (11df1f6)
- cabinet-rbac: assign Superadmin at login for ADMIN_IDS users (924fc92)
- cabinet-rbac: block auto-login for ADMIN_IDS / ADMIN_EMAILS users (6ec497e)
- cabinet-rbac: CRITICAL — use config getters; preserve UI revocation (457d7c1)
- cabinet-rbac: savepoint isolation, audit log, PII masking, NFKC normalize (8abec4f)
- cabinet-rbac: UserRole.revocation_source + harden OAuth + shared admin helper (6cb272f)
- cabinet: return original_price_per_device_kopeks for device addon (b5a0666)
- campaigns: admin chat count now matches cabinet registrations 1:1 (788fe4f)
- campaigns: close race conditions and ensure UNIQUE constraint exists (bd0bf98)
- campaigns: dedupe admin chat notifications for repeated /start (76a2bb6)
- channel-check: silence expected non-membership BadRequest errors (705ca80)
- email: inject cabinet_url + alias legacy placeholders ({amount}, {balance}, {reason}) (c731de5)
- email: inject cabinet_url and add legacy placeholder aliases (3b9bd53)
- gift: use pricing_engine as single source of truth in /config (c812e45)
- handle None values in email template substitution (7263b49)
- keyboards: apply CABINET_BUTTON_STYLES style to language and admin callback buttons (669bb17)
- lava: align with official Lava Business SDK contract (fd5e377)
- lava: harden signature canonicalization for PHP SDK parity (9b0751a)
- notifications: classify transient Telegram errors as warning, retry network failures (b23476e)
- payments: always show kopeks in insufficient-funds messages — close 0₽-shortage UX trap (e53008c)
- payments: persist open_url_direct in update_config allow-list (e13bbdd)
- price-display: show exact kopeks in 'insufficient funds' messages (b129970)
- promo-groups: include legacy promo_group_id in payment method filter (closes #422) (4af97c9)
- recurrent-payments: re-fetch subscription per iteration to avoid MissingGreenlet (ae4cd34)
- smtp: use implicit TLS (SMTPS) for port 465 registration emails (29d3e89)
- traffic: close TOCTOU race + handle unlimited tariff in TrafficPurchase housekeeping (c8aeb9b)
- traffic: preserve active TrafficPurchase packages across renewal (0beb45a)
- user-delete: also clean Apple IAP and RioPay before deleting transactions (e37e8b9)
- user-delete: clean up missing payment provider tables before deleting transactions (9c489d5)