fix: gate PayKilla by minimum payment amount

This commit is contained in:
3252a8
2026-06-04 16:21:10 +03:00
parent bdf0622be5
commit ae7bfb9621
15 changed files with 567 additions and 25 deletions
+28
View File
@@ -128,6 +128,8 @@ WebhookPathGetter = Callable[[Any], str]
WebhookRoute = Callable[[Any], Awaitable[Any]]
WebAppPaymentFactory = Callable[[WebAppPaymentContext], Awaitable[Any]]
CurrencySupportResolver = Callable[[Any], Optional[Sequence[str]]]
PaymentAmountResolver = Callable[[Any, Any, Any], bool]
PaymentMinimumResolver = Callable[[Any, Any], Optional[Mapping[str, Any]]]
def normalize_payment_currency_code(value: Any, default: str = "RUB") -> str:
@@ -192,6 +194,8 @@ class PaymentProviderSpec:
admin_only_enabled: Optional[EnabledPredicate] = None
supported_currencies: Optional[Sequence[str]] = ("RUB",)
supported_currencies_resolver: Optional[CurrencySupportResolver] = None
payment_amount_resolver: Optional[PaymentAmountResolver] = None
payment_minimum_resolver: Optional[PaymentMinimumResolver] = None
currency_support_note: str = ""
currency_support_url: Optional[str] = None
@@ -306,6 +310,30 @@ class PaymentProviderSpec:
return True
return self.supports_currency(source, currency)
def payment_minimum(self, source: Any, currency: Any) -> Optional[Mapping[str, Any]]:
if self.payment_minimum_resolver is None:
return None
source_for_amount = self._currency_source(source)
try:
return self.payment_minimum_resolver(source_for_amount, currency)
except Exception:
return None
def is_usable_for_payment_amount(self, source: Any, currency: Any, amount: Any) -> bool:
if self.price_source == "stars" or self.payment_amount_resolver is None:
return True
source_for_amount = self._currency_source(source)
try:
return bool(self.payment_amount_resolver(source_for_amount, currency, amount))
except Exception:
return True
def is_usable_for_payment(self, source: Any, currency: Any, amount: Any) -> bool:
return self.is_usable_for_payment_currency(
source,
currency,
) and self.is_usable_for_payment_amount(source, currency, amount)
def is_visible(self, source: Any, app: Any) -> bool:
return self.is_enabled(source) and self.is_service_configured(app)