From d503cf7f7f65b4211375f18f3bfb7789eec6915e Mon Sep 17 00:00:00 2001 From: machka pasla Date: Fri, 31 Oct 2025 21:38:41 +0300 Subject: [PATCH] YOOKASSA_AUTOPAYMENTS_REQUIRE_CARD_BINDING param added --- .env.example | 1 + README.md | 2 ++ bot/handlers/user/subscription/payments.py | 10 ++++++++-- config/settings.py | 4 ++++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index 5a98439..ebe2b6a 100644 --- a/.env.example +++ b/.env.example @@ -44,6 +44,7 @@ YOOKASSA_RETURN_URL=https://t.me/your_bot # YOOKASSA_DEFAULT_RECEIPT_EMAIL=your_email@example.com # Default email for sending receipts YOOKASSA_VAT_CODE=1 # VAT code YOOKASSA_AUTOPAYMENTS_ENABLED=False # Auto-renew toggle +YOOKASSA_AUTOPAYMENTS_REQUIRE_CARD_BINDING=True # Force automatic card binding when autopay is enabled (set to False to show the save-card checkbox) # FreeKassa Payment Gateway Configuration FREEKASSA_MERCHANT_ID=your_shop_id # Your shop ID in FreeKassa diff --git a/README.md b/README.md index 1849156..2528a2a 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,8 @@ | `YOOKASSA_ENABLED` | Включить/выключить YooKassa (`true`/`false`). | | `YOOKASSA_SHOP_ID` | ID вашего магазина в YooKassa. | | `YOOKASSA_SECRET_KEY`| Секретный ключ магазина YooKassa. | + | `YOOKASSA_AUTOPAYMENTS_ENABLED` | Включить автопродление (сохранение карт, автосписания, управление способами оплаты). | + | `YOOKASSA_AUTOPAYMENTS_REQUIRE_CARD_BINDING` | Требовать обязательную привязку карты при оплате с автосписанием. Установите `false`, чтобы пользователю показывался чекбокс «Сохранить карту». | | `CRYPTOPAY_ENABLED` | Включить/выключить CryptoPay (`true`/`false`). | | `CRYPTOPAY_TOKEN` | Токен из вашего CryptoPay App. | | `FREEKASSA_ENABLED` | Включить/выключить FreeKassa (`true`/`false`). | diff --git a/bot/handlers/user/subscription/payments.py b/bot/handlers/user/subscription/payments.py index 1c21005..5157552 100644 --- a/bot/handlers/user/subscription/payments.py +++ b/bot/handlers/user/subscription/payments.py @@ -408,6 +408,9 @@ async def pay_yk_callback_handler(callback: types.CallbackQuery, settings: Setti user_id = callback.from_user.id currency_code_for_yk = "RUB" autopay_enabled = bool(getattr(settings, 'YOOKASSA_AUTOPAYMENTS_ENABLED', False)) + autopay_require_binding = bool( + getattr(settings, 'YOOKASSA_AUTOPAYMENTS_REQUIRE_CARD_BINDING', True) + ) saved_methods: List = [] if autopay_enabled: try: @@ -463,7 +466,7 @@ async def pay_yk_callback_handler(callback: types.CallbackQuery, settings: Setti months=months, price_rub=price_rub, currency_code_for_yk=currency_code_for_yk, - save_payment_method=autopay_enabled, + save_payment_method=autopay_enabled and autopay_require_binding, back_callback=f"subscribe_period:{months}", ) try: @@ -520,6 +523,9 @@ async def pay_yk_new_card_handler(callback: types.CallbackQuery, settings: Setti user_id = callback.from_user.id currency_code_for_yk = "RUB" autopay_enabled = bool(getattr(settings, 'YOOKASSA_AUTOPAYMENTS_ENABLED', False)) + autopay_require_binding = bool( + getattr(settings, 'YOOKASSA_AUTOPAYMENTS_REQUIRE_CARD_BINDING', True) + ) await _initiate_yk_payment( callback, @@ -533,7 +539,7 @@ async def pay_yk_new_card_handler(callback: types.CallbackQuery, settings: Setti months=months, price_rub=price_rub, currency_code_for_yk=currency_code_for_yk, - save_payment_method=autopay_enabled, + save_payment_method=autopay_enabled and autopay_require_binding, back_callback=f"subscribe_period:{months}", ) try: diff --git a/config/settings.py b/config/settings.py index 561f66c..c296621 100644 --- a/config/settings.py +++ b/config/settings.py @@ -41,6 +41,10 @@ class Settings(BaseSettings): YOOKASSA_PAYMENT_SUBJECT: str = Field(default="service") # Single toggle to enable recurring payments (saving cards, managing payment methods, auto-renew) YOOKASSA_AUTOPAYMENTS_ENABLED: bool = Field(default=False) + YOOKASSA_AUTOPAYMENTS_REQUIRE_CARD_BINDING: bool = Field( + default=True, + description="When true, new YooKassa payments in autopay mode force card binding without a user checkbox." + ) WEBHOOK_BASE_URL: Optional[str] = None