feat: add wata payment provider

This commit is contained in:
3252a8
2026-05-17 23:09:04 +03:00
parent 11429e887e
commit fff7e90e14
26 changed files with 996 additions and 6 deletions
+77 -1
View File
@@ -62,6 +62,15 @@ class PaymentSettings(BaseModel):
severpay_return_url: Optional[str]
severpay_base_url: str
severpay_lifetime_minutes: Optional[int]
wata_enabled: bool
wata_api_token: Optional[str]
wata_base_url: str
wata_return_url: Optional[str]
wata_failed_url: Optional[str]
wata_payment_link_ttl_days: int
wata_webhook_verify_signature: bool
wata_public_key: Optional[str]
wata_trusted_ips: List[str]
cryptopay_enabled: bool
cryptopay_token: Optional[str]
cryptopay_network: str
@@ -255,11 +264,30 @@ class Settings(BaseSettings):
description="Lifetime of the payment link in minutes (30-4320, defaults to provider value)",
)
WATA_ENABLED: bool = Field(default=False)
WATA_API_TOKEN: Optional[str] = None
WATA_BASE_URL: str = Field(default="https://api.wata.pro/api/h2h")
WATA_RETURN_URL: Optional[str] = None
WATA_FAILED_URL: Optional[str] = None
WATA_PAYMENT_LINK_TTL_DAYS: int = Field(
default=3,
description="Payment link lifetime in days (1-30).",
)
WATA_WEBHOOK_VERIFY_SIGNATURE: bool = Field(default=True)
WATA_PUBLIC_KEY: Optional[str] = Field(
default=None,
description="Optional cached Wata RSA public key for webhook signature verification.",
)
WATA_TRUSTED_IPS: str = Field(
default="62.84.126.140,51.250.106.150",
description="Comma-separated Wata webhook IP allowlist.",
)
YOOKASSA_ENABLED: bool = Field(default=True)
STARS_ENABLED: bool = Field(default=True)
PAYMENT_METHODS_ORDER: Optional[str] = Field(
default=None,
description="Comma-separated list of payment methods to show (e.g., severpay,freekassa,yookassa,platega,stars,cryptopay)", # noqa: E501
description="Comma-separated list of payment methods to show (e.g., severpay,wata,freekassa,yookassa,platega,stars,cryptopay)", # noqa: E501
)
MONTH_1_ENABLED: bool = Field(default=True, alias="1_MONTH_ENABLED")
@@ -532,6 +560,15 @@ class Settings(BaseSettings):
severpay_return_url=self.SEVERPAY_RETURN_URL,
severpay_base_url=self.SEVERPAY_BASE_URL,
severpay_lifetime_minutes=self.SEVERPAY_LIFETIME_MINUTES,
wata_enabled=self.WATA_ENABLED,
wata_api_token=self.WATA_API_TOKEN,
wata_base_url=self.WATA_BASE_URL,
wata_return_url=self.WATA_RETURN_URL,
wata_failed_url=self.WATA_FAILED_URL,
wata_payment_link_ttl_days=self.WATA_PAYMENT_LINK_TTL_DAYS,
wata_webhook_verify_signature=self.WATA_WEBHOOK_VERIFY_SIGNATURE,
wata_public_key=self.WATA_PUBLIC_KEY,
wata_trusted_ips=self.wata_trusted_ips,
cryptopay_enabled=self.CRYPTOPAY_ENABLED,
cryptopay_token=self.CRYPTOPAY_TOKEN,
cryptopay_network=self.CRYPTOPAY_NETWORK,
@@ -719,6 +756,24 @@ class Settings(BaseSettings):
return f"{base.rstrip('/')}{self.severpay_webhook_path}"
return None
@computed_field
@property
def wata_webhook_path(self) -> str:
return "/webhook/wata"
@computed_field
@property
def wata_full_webhook_url(self) -> Optional[str]:
base = self.WEBHOOK_BASE_URL
if base:
return f"{base.rstrip('/')}{self.wata_webhook_path}"
return None
@computed_field
@property
def wata_trusted_ips(self) -> List[str]:
return _split_csv(self.WATA_TRUSTED_IPS)
@computed_field
@property
def platega_webhook_path(self) -> str:
@@ -948,6 +1003,7 @@ class Settings(BaseSettings):
"platega_sbp",
"platega_crypto",
"severpay",
"wata",
"yookassa",
"stars",
"cryptopay",
@@ -1060,6 +1116,10 @@ class Settings(BaseSettings):
"PLATEGA_RETURN_URL",
"PLATEGA_FAILED_URL",
"SEVERPAY_RETURN_URL",
"WATA_RETURN_URL",
"WATA_FAILED_URL",
"WATA_API_TOKEN",
"WATA_PUBLIC_KEY",
"CRYPT4_REDIRECT_URL",
"PRIVACY_POLICY_URL",
"USER_AGREEMENT_URL",
@@ -1091,6 +1151,17 @@ class Settings(BaseSettings):
return None
return v
@field_validator("WATA_PAYMENT_LINK_TTL_DAYS", mode="before")
@classmethod
def validate_wata_ttl_days(cls, v):
if isinstance(v, str):
v = v.strip()
try:
value = int(v)
except (TypeError, ValueError):
return 3
return min(30, max(1, value))
# Notification types
LOG_NEW_USERS: bool = Field(
default=True, description="Send notifications for new user registrations"
@@ -1182,6 +1253,11 @@ def get_settings() -> Settings:
logging.warning(
"CRITICAL: SeverPay is enabled but MID or TOKEN is missing. SeverPay payments will not work." # noqa: E501
)
if _settings_instance.WATA_ENABLED:
if not _settings_instance.WATA_API_TOKEN:
logging.warning(
"CRITICAL: Wata is enabled but WATA_API_TOKEN is missing. Wata payments will not work." # noqa: E501
)
except ValidationError as e:
logging.critical(f"Pydantic validation error while loading settings: {e}")