feat: add multicurrency tariff payments

This commit is contained in:
3252a8
2026-05-31 22:17:28 +03:00
parent df8f2636d2
commit 80e5f0c80d
35 changed files with 1242 additions and 227 deletions
+36 -4
View File
@@ -16,6 +16,10 @@ from bot.middlewares.i18n import JsonI18n
from bot.services.referral_service import ReferralService
from bot.services.subscription_service import SubscriptionService
from config.settings import Settings
from config.tariffs_config import (
default_currency_key_for_settings,
default_payment_currency_code_for_settings,
)
from db.dal import payment_dal
from .base import (
@@ -24,6 +28,8 @@ from .base import (
ProviderManifestField,
ServiceFactoryContext,
WebAppPaymentContext,
normalize_payment_currency_code,
parse_supported_currency_codes,
provider_env_file,
provider_runtime_enabled,
)
@@ -69,6 +75,7 @@ class SeverPayConfig(ProviderEnvConfig):
RETURN_URL: Optional[str] = None
BASE_URL: str = Field(default="https://severpay.io/api/merchant")
LIFETIME_MINUTES: Optional[int] = None
SUPPORTED_CURRENCIES: str = Field(default="RUB,USD")
@field_validator("MID", "LIFETIME_MINUTES", mode="before")
@classmethod
@@ -201,9 +208,19 @@ class SeverPayService(HttpClientMixin):
logging.error("SeverPayService is not configured. Cannot create payment.")
return False, {"message": "service_not_configured"}
currency_code = normalize_payment_currency_code(
currency or self.settings.DEFAULT_CURRENCY_SYMBOL or "RUB"
)
supported = parse_supported_currency_codes(self.config.SUPPORTED_CURRENCIES)
if supported and currency_code not in supported:
return False, {
"message": "unsupported_currency",
"currency": currency_code,
"supported_currencies": list(supported),
}
session = await self._get_session()
url = f"{self.base_url}/payin/create"
currency_code = (currency or self.settings.DEFAULT_CURRENCY_SYMBOL or "RUB").upper()
body = {
"order_id": str(payment_db_id),
@@ -428,13 +445,13 @@ async def pay_severpay_callback_handler(
user_id=callback.from_user.id,
parts=parts,
subscription_service=severpay_service.subscription_service,
currency="rub",
currency=default_currency_key_for_settings(settings),
)
if not parts:
await notify_callback_parse_error(callback, translator)
return
currency_code = settings.DEFAULT_CURRENCY_SYMBOL or "RUB"
currency_code = default_payment_currency_code_for_settings(settings)
payment_description = describe_payment(translator, parts)
record_payload = build_payment_record_payload(
user_id=callback.from_user.id,
@@ -503,7 +520,7 @@ async def create_webapp_payment(ctx: WebAppPaymentContext) -> web.Response:
if not service or not service.configured:
return payment_unavailable()
currency = settings.DEFAULT_CURRENCY_SYMBOL or "RUB"
currency = ctx.currency or settings.DEFAULT_CURRENCY_SYMBOL or "RUB"
try:
payment = await create_webapp_payment_record(
ctx,
@@ -627,6 +644,18 @@ _CONFIG_MANIFEST = (
max=4320,
attr="LIFETIME_MINUTES",
),
ProviderManifestField(
"SEVERPAY_SUPPORTED_CURRENCIES",
"string",
"Supported currencies",
description=(
"Comma-separated currencies enabled for your SeverPay merchant. "
"The public PayIn docs show USD examples but do not publish a fixed global list."
),
placeholder="RUB,USD",
subsection="SeverPay",
attr="SUPPORTED_CURRENCIES",
),
)
@@ -651,4 +680,7 @@ SPEC = PaymentProviderSpec(
config_class=SeverPayConfig,
presentation_class=SeverPayPresentation,
manifest_fields=_CONFIG_MANIFEST + _PRESENTATION_MANIFEST,
supported_currencies_resolver=lambda config: getattr(config, "SUPPORTED_CURRENCIES", "RUB,USD"),
currency_support_note="SeverPay PayIn requires a currency; keep this list aligned with your merchant account.",
currency_support_url="https://docs.severpay.io/ru/payin/create",
)