Add global payment request timeout setting
This commit is contained in:
@@ -348,6 +348,16 @@ SETTINGS_MANIFEST: List[SettingField] = [
|
||||
"Английская версия текста на этапе оплаты.",
|
||||
subsection="checkout",
|
||||
),
|
||||
SettingField(
|
||||
"PAYMENT_REQUEST_TIMEOUT_SECONDS",
|
||||
"float",
|
||||
"payments",
|
||||
"Таймаут запроса к провайдеру",
|
||||
"Максимальное общее время одного API-запроса к платёжному провайдеру, в секундах.",
|
||||
optional=False,
|
||||
min=1,
|
||||
subsection="checkout",
|
||||
),
|
||||
# ─── Payment providers (toggles) ───────────────────────────────
|
||||
# Common
|
||||
SettingField("STARS_ENABLED", "bool", "payments", "Telegram Stars", subsection="common"),
|
||||
|
||||
@@ -153,7 +153,7 @@ class FreeKassaService(HttpClientMixin):
|
||||
self.default_currency: str = default_payment_currency_code_for_settings(settings).upper()
|
||||
|
||||
self.api_base_url: str = "https://api.fk.life/v1"
|
||||
self._init_http_client(total_timeout=15)
|
||||
self._init_http_client(total_timeout=self.settings.PAYMENT_REQUEST_TIMEOUT_SECONDS)
|
||||
self._nonce_lock = asyncio.Lock()
|
||||
self._last_nonce = int(time.time() * 1000)
|
||||
|
||||
|
||||
@@ -243,7 +243,7 @@ class HeleketService(HttpClientMixin):
|
||||
self.referral_service = referral_service
|
||||
self._default_return_url = default_return_url
|
||||
|
||||
self._init_http_client(total_timeout=20)
|
||||
self._init_http_client(total_timeout=self.settings.PAYMENT_REQUEST_TIMEOUT_SECONDS)
|
||||
if not self.configured:
|
||||
logging.warning(
|
||||
"HeleketService initialized but not fully configured. Payments disabled."
|
||||
|
||||
@@ -369,7 +369,7 @@ class PaykillaService(HttpClientMixin):
|
||||
self.referral_service = referral_service
|
||||
self._default_return_url = default_return_url
|
||||
|
||||
self._init_http_client(total_timeout=20)
|
||||
self._init_http_client(total_timeout=self.settings.PAYMENT_REQUEST_TIMEOUT_SECONDS)
|
||||
if not self.configured:
|
||||
logging.warning(
|
||||
"PaykillaService initialized but not fully configured. Payments disabled."
|
||||
|
||||
@@ -157,7 +157,7 @@ class PlategaService(HttpClientMixin):
|
||||
self.referral_service = referral_service
|
||||
self._default_return_url = default_return_url
|
||||
|
||||
self._init_http_client(total_timeout=60)
|
||||
self._init_http_client(total_timeout=self.settings.PAYMENT_REQUEST_TIMEOUT_SECONDS)
|
||||
if not self.configured:
|
||||
logging.warning(
|
||||
"PlategaService initialized but not fully configured. Payments disabled."
|
||||
|
||||
@@ -136,7 +136,7 @@ class SeverPayService(HttpClientMixin):
|
||||
self.referral_service = referral_service
|
||||
self._default_return_url = default_return_url
|
||||
|
||||
self._init_http_client(total_timeout=15)
|
||||
self._init_http_client(total_timeout=self.settings.PAYMENT_REQUEST_TIMEOUT_SECONDS)
|
||||
|
||||
if not self.configured:
|
||||
logging.warning(
|
||||
|
||||
@@ -206,7 +206,7 @@ class WataService(HttpClientMixin):
|
||||
self._default_return_url = default_return_url
|
||||
self._cached_public_key_pem = None # populated by webhook on first verify
|
||||
|
||||
self._init_http_client(total_timeout=10)
|
||||
self._init_http_client(total_timeout=self.settings.PAYMENT_REQUEST_TIMEOUT_SECONDS)
|
||||
if not self.configured:
|
||||
logging.warning("WataService initialized but not fully configured. Payments disabled.")
|
||||
|
||||
|
||||
@@ -319,6 +319,11 @@ class Settings(BaseSettings):
|
||||
default=DEFAULT_SUBSCRIPTION_PURCHASE_DESCRIPTION_EN,
|
||||
description="English subscription description shown before purchase/renewal options.",
|
||||
)
|
||||
PAYMENT_REQUEST_TIMEOUT_SECONDS: float = Field(
|
||||
default=20,
|
||||
ge=1,
|
||||
description="Maximum total time for one payment provider API request, in seconds.",
|
||||
)
|
||||
|
||||
MONTH_1_ENABLED: bool = Field(default=True, alias="1_MONTH_ENABLED")
|
||||
MONTH_3_ENABLED: bool = Field(default=True, alias="3_MONTHS_ENABLED")
|
||||
|
||||
@@ -200,6 +200,7 @@
|
||||
| `PAYMENT_METHODS_ORDER` | Порядок кнопок оплаты: `severpay,wata,freekassa,platega,yookassa,stars,cryptopay,heleket,paykilla`. |
|
||||
| `SUBSCRIPTION_PURCHASE_DESCRIPTION_ENABLED` | Показывать описание подписки перед выбором срока. |
|
||||
| `SUBSCRIPTION_PURCHASE_DESCRIPTION_RU` / `SUBSCRIPTION_PURCHASE_DESCRIPTION_EN` | Локализованное описание подписки. |
|
||||
| `PAYMENT_REQUEST_TIMEOUT_SECONDS` | Общий таймаут одного API-запроса к платёжному провайдеру, в секундах. По умолчанию `20`. |
|
||||
| `PAYMENT_<METHOD>_WEBAPP_LABEL_RU` / `PAYMENT_<METHOD>_WEBAPP_LABEL_EN` | Текст кнопки провайдера в Web App. |
|
||||
| `PAYMENT_<METHOD>_WEBAPP_ICON` | Lucide-иконка кнопки в Web App. |
|
||||
| `PAYMENT_<METHOD>_TELEGRAM_LABEL_RU` / `PAYMENT_<METHOD>_TELEGRAM_LABEL_EN` | Текст кнопки в Telegram. |
|
||||
|
||||
@@ -603,6 +603,26 @@
|
||||
"overridden": false,
|
||||
"updated_at": null
|
||||
},
|
||||
{
|
||||
"key": "PAYMENT_REQUEST_TIMEOUT_SECONDS",
|
||||
"type": "float",
|
||||
"section": "payments",
|
||||
"section_order": 4,
|
||||
"subsection": "checkout",
|
||||
"label": "Таймаут запроса к провайдеру",
|
||||
"description": "Максимальное общее время одного API-запроса к платёжному провайдеру, в секундах.",
|
||||
"i18n_label_key": "admin_settings_field_payment_request_timeout_seconds_label",
|
||||
"i18n_description_key": "admin_settings_field_payment_request_timeout_seconds_description",
|
||||
"i18n_subsection_key": "admin_settings_subsection_checkout",
|
||||
"i18n_placeholder_key": null,
|
||||
"placeholder": "",
|
||||
"optional": false,
|
||||
"secret": false,
|
||||
"min": 1,
|
||||
"value": "",
|
||||
"overridden": false,
|
||||
"updated_at": null
|
||||
},
|
||||
{
|
||||
"key": "STARS_ENABLED",
|
||||
"type": "bool",
|
||||
|
||||
@@ -1170,6 +1170,7 @@
|
||||
"admin_settings_subsection_cryptopay": "CryptoPay",
|
||||
"admin_settings_subsection_wata": "Wata",
|
||||
"admin_settings_subsection_heleket": "Heleket",
|
||||
"admin_settings_subsection_paykilla": "PayKilla",
|
||||
"admin_settings_provider_webhook_url": "Webhook URL",
|
||||
"admin_settings_provider_webhook_url_hint": "Use this URL in the provider webhook settings.",
|
||||
"admin_settings_panel_webhook_url_hint": "Use this URL as WEBHOOK_URL in Remnawave Panel.",
|
||||
@@ -1676,6 +1677,8 @@
|
||||
"admin_settings_field_subscription_purchase_description_ru_description": "Russian text shown during checkout.",
|
||||
"admin_settings_field_subscription_purchase_description_en_label": "Subscription description (EN)",
|
||||
"admin_settings_field_subscription_purchase_description_en_description": "English text shown during checkout.",
|
||||
"admin_settings_field_payment_request_timeout_seconds_label": "Payment provider request timeout",
|
||||
"admin_settings_field_payment_request_timeout_seconds_description": "Maximum total time for one payment provider API request, in seconds.",
|
||||
"admin_settings_field_stars_enabled_label": "Stars Enabled",
|
||||
"admin_settings_field_yookassa_enabled_label": "YooKassa Enabled",
|
||||
"admin_settings_field_yookassa_shop_id_label": "YooKassa Shop ID",
|
||||
|
||||
@@ -1170,6 +1170,7 @@
|
||||
"admin_settings_subsection_cryptopay": "CryptoPay",
|
||||
"admin_settings_subsection_wata": "Wata",
|
||||
"admin_settings_subsection_heleket": "Heleket",
|
||||
"admin_settings_subsection_paykilla": "PayKilla",
|
||||
"admin_settings_provider_webhook_url": "Webhook URL",
|
||||
"admin_settings_provider_webhook_url_hint": "Укажите этот адрес в настройках вебхуков провайдера.",
|
||||
"admin_settings_panel_webhook_url_hint": "Укажите этот адрес как WEBHOOK_URL в Remnawave Panel.",
|
||||
@@ -1676,6 +1677,8 @@
|
||||
"admin_settings_field_subscription_purchase_description_ru_description": "Русская версия текста на этапе оплаты.",
|
||||
"admin_settings_field_subscription_purchase_description_en_label": "Описание подписки (EN)",
|
||||
"admin_settings_field_subscription_purchase_description_en_description": "Английская версия текста на этапе оплаты.",
|
||||
"admin_settings_field_payment_request_timeout_seconds_label": "Таймаут запроса к провайдеру",
|
||||
"admin_settings_field_payment_request_timeout_seconds_description": "Максимальное общее время одного API-запроса к платёжному провайдеру, в секундах.",
|
||||
"admin_settings_field_stars_enabled_label": "Telegram Stars",
|
||||
"admin_settings_field_yookassa_enabled_label": "Включена",
|
||||
"admin_settings_field_yookassa_shop_id_label": "Shop ID",
|
||||
|
||||
@@ -24,6 +24,7 @@ SUBSCRIPTION_PURCHASE_DESCRIPTION_SETTINGS = (
|
||||
"SUBSCRIPTION_PURCHASE_DESCRIPTION_ENABLED",
|
||||
"SUBSCRIPTION_PURCHASE_DESCRIPTION_RU",
|
||||
"SUBSCRIPTION_PURCHASE_DESCRIPTION_EN",
|
||||
"PAYMENT_REQUEST_TIMEOUT_SECONDS",
|
||||
)
|
||||
|
||||
SUBSCRIPTION_GUIDE_SETTINGS = (
|
||||
@@ -177,6 +178,11 @@ def test_support_settings_i18n_keys_exist_in_admin_locales():
|
||||
def test_subscription_purchase_description_settings_i18n_keys_exist():
|
||||
manifest = _manifest_by_key()
|
||||
|
||||
timeout_field = manifest["PAYMENT_REQUEST_TIMEOUT_SECONDS"]
|
||||
assert timeout_field["type"] == "float"
|
||||
assert timeout_field["optional"] is False
|
||||
assert timeout_field["min"] == 1
|
||||
|
||||
for language in ("ru", "en"):
|
||||
messages = _locale(language)
|
||||
for setting_key in SUBSCRIPTION_PURCHASE_DESCRIPTION_SETTINGS:
|
||||
|
||||
Reference in New Issue
Block a user