diff --git a/.env.example b/.env.example index 77f05953..439962de 100644 --- a/.env.example +++ b/.env.example @@ -294,6 +294,7 @@ MINIAPP_SERVICE_NAME_EN=Bedolaga VPN MINIAPP_SERVICE_NAME_RU=Bedolaga VPN MINIAPP_SERVICE_DESCRIPTION_EN=Secure & Fast Connection MINIAPP_SERVICE_DESCRIPTION_RU=Безопасное и быстрое подключение +MINIAPP_PURCHASE_URL= # Параметры режима happ_cryptolink CONNECT_BUTTON_HAPP_DOWNLOAD_ENABLED=false diff --git a/README.md b/README.md index c1fdb9f1..8c688eaf 100644 --- a/README.md +++ b/README.md @@ -539,6 +539,7 @@ MINIAPP_SERVICE_NAME_EN=Bedolaga VPN MINIAPP_SERVICE_NAME_RU=Bedolaga VPN MINIAPP_SERVICE_DESCRIPTION_EN=Secure & Fast Connection MINIAPP_SERVICE_DESCRIPTION_RU=Безопасное и быстрое подключение +MINIAPP_PURCHASE_URL= # Параметры режима happ_cryptolink CONNECT_BUTTON_HAPP_DOWNLOAD_ENABLED=false diff --git a/app/config.py b/app/config.py index 773f4f45..a4057c24 100644 --- a/app/config.py +++ b/app/config.py @@ -217,6 +217,7 @@ class Settings(BaseSettings): MINIAPP_SERVICE_NAME_RU: str = "Bedolaga VPN" MINIAPP_SERVICE_DESCRIPTION_EN: str = "Secure & Fast Connection" MINIAPP_SERVICE_DESCRIPTION_RU: str = "Безопасное и быстрое подключение" + MINIAPP_PURCHASE_URL: str = "" CONNECT_BUTTON_HAPP_DOWNLOAD_ENABLED: bool = False HAPP_CRYPTOLINK_REDIRECT_TEMPLATE: Optional[str] = None HAPP_DOWNLOAD_LINK_IOS: Optional[str] = None diff --git a/app/webapi/routes/miniapp.py b/app/webapi/routes/miniapp.py index 64bc7bd4..b6aca0a0 100644 --- a/app/webapi/routes/miniapp.py +++ b/app/webapi/routes/miniapp.py @@ -24,6 +24,7 @@ from app.utils.telegram_webapp import ( from ..dependencies import get_db_session from ..schemas.miniapp import ( + MiniAppConfigResponse, MiniAppConnectedServer, MiniAppDevice, MiniAppPromoGroup, @@ -63,6 +64,11 @@ def _format_limit_label(limit: Optional[int]) -> str: return f"{limit} GB" +def _get_purchase_url() -> Optional[str]: + value = (settings.MINIAPP_PURCHASE_URL or "").strip() + return value or None + + def _bytes_to_gb(bytes_value: Optional[int]) -> float: if not bytes_value: return 0.0 @@ -258,6 +264,11 @@ async def _load_subscription_links( return payload +@router.get("/config", response_model=MiniAppConfigResponse) +async def get_miniapp_config() -> MiniAppConfigResponse: + return MiniAppConfigResponse(purchase_url=_get_purchase_url()) + + @router.post("/subscription", response_model=MiniAppSubscriptionResponse) async def get_subscription_details( payload: MiniAppSubscriptionRequest, @@ -364,6 +375,7 @@ async def get_subscription_details( user=response_user, subscription_url=subscription_url, subscription_crypto_link=subscription_crypto_link, + purchase_url=_get_purchase_url(), links=links, ss_conf_links=ss_conf_links, connected_squads=connected_squads, diff --git a/app/webapi/schemas/miniapp.py b/app/webapi/schemas/miniapp.py index a0d5cb1a..3e644aa7 100644 --- a/app/webapi/schemas/miniapp.py +++ b/app/webapi/schemas/miniapp.py @@ -11,6 +11,10 @@ class MiniAppBranding(BaseModel): service_description: Dict[str, Optional[str]] = Field(default_factory=dict) +class MiniAppConfigResponse(BaseModel): + purchase_url: Optional[str] = None + + class MiniAppSubscriptionRequest(BaseModel): init_data: str = Field(..., alias="initData") @@ -74,6 +78,7 @@ class MiniAppSubscriptionResponse(BaseModel): user: MiniAppSubscriptionUser subscription_url: Optional[str] = None subscription_crypto_link: Optional[str] = None + purchase_url: Optional[str] = None links: List[str] = Field(default_factory=list) ss_conf_links: Dict[str, str] = Field(default_factory=dict) connected_squads: List[str] = Field(default_factory=list) diff --git a/miniapp/index.html b/miniapp/index.html index fe03f136..b84030cd 100644 --- a/miniapp/index.html +++ b/miniapp/index.html @@ -314,6 +314,19 @@ line-height: 1.6; } + .error-actions { + margin-top: 24px; + display: flex; + justify-content: center; + } + + .error-actions .btn { + width: auto; + min-width: 200px; + padding-left: 32px; + padding-right: 32px; + } + /* Cards */ .card { background: var(--bg-secondary); @@ -758,6 +771,7 @@ overflow: hidden; text-transform: uppercase; letter-spacing: 0.5px; + text-decoration: none; } .btn::before { @@ -1186,6 +1200,9 @@