Merge pull request #1004 from Fr1ngg/revert-1003-bedolaga-d7n0dr
Revert "Implement mini app balance top-up flow"
This commit is contained in:
@@ -2,13 +2,9 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import re
|
||||
from decimal import Decimal, InvalidOperation, ROUND_HALF_UP
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Any, Dict, List, Optional, Tuple, Union
|
||||
|
||||
from aiogram import Bot
|
||||
from aiogram.client.default import DefaultBotProperties
|
||||
from aiogram.enums import ParseMode
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
@@ -35,7 +31,6 @@ from app.database.models import (
|
||||
Transaction,
|
||||
User,
|
||||
)
|
||||
from app.external.telegram_stars import TelegramStarsService
|
||||
from app.services.faq_service import FaqService
|
||||
from app.services.privacy_policy_service import PrivacyPolicyService
|
||||
from app.services.public_offer_service import PublicOfferService
|
||||
@@ -45,9 +40,7 @@ from app.services.remnawave_service import (
|
||||
)
|
||||
from app.services.promo_offer_service import promo_offer_service
|
||||
from app.services.promocode_service import PromoCodeService
|
||||
from app.services.payment_service import PaymentService
|
||||
from app.services.subscription_service import SubscriptionService
|
||||
from app.services.tribute_service import TributeService
|
||||
from app.utils.subscription_utils import get_happ_cryptolink_redirect_link
|
||||
from app.utils.telegram_webapp import (
|
||||
TelegramWebAppAuthError,
|
||||
@@ -57,7 +50,6 @@ from app.utils.user_utils import (
|
||||
get_detailed_referral_list,
|
||||
get_user_referral_summary,
|
||||
)
|
||||
from app.utils.currency_converter import currency_converter
|
||||
|
||||
from ..dependencies import get_db_session
|
||||
from ..schemas.miniapp import (
|
||||
@@ -83,10 +75,6 @@ from ..schemas.miniapp import (
|
||||
MiniAppReferralStats,
|
||||
MiniAppReferralTerms,
|
||||
MiniAppRichTextDocument,
|
||||
MiniAppCreatePaymentRequest,
|
||||
MiniAppCreatePaymentResponse,
|
||||
MiniAppPaymentMethod,
|
||||
MiniAppPaymentMethodsResponse,
|
||||
MiniAppSubscriptionRequest,
|
||||
MiniAppSubscriptionResponse,
|
||||
MiniAppSubscriptionUser,
|
||||
@@ -184,109 +172,6 @@ def _determine_offer_icon(offer_type: Optional[str], effect_type: str) -> str:
|
||||
return _DEFAULT_OFFER_ICON
|
||||
|
||||
|
||||
def _build_payment_methods_payload() -> List[MiniAppPaymentMethod]:
|
||||
methods: List[MiniAppPaymentMethod] = []
|
||||
|
||||
if settings.TELEGRAM_STARS_ENABLED:
|
||||
methods.append(
|
||||
MiniAppPaymentMethod(
|
||||
id="stars",
|
||||
type="telegram_stars",
|
||||
icon="⭐",
|
||||
requires_amount=True,
|
||||
currency="RUB",
|
||||
min_amount=100.0,
|
||||
metadata={"rate": settings.get_stars_rate()},
|
||||
)
|
||||
)
|
||||
|
||||
if settings.is_yookassa_enabled():
|
||||
min_amount = None
|
||||
max_amount = None
|
||||
if settings.YOOKASSA_MIN_AMOUNT_KOPEKS:
|
||||
min_amount = float(settings.YOOKASSA_MIN_AMOUNT_KOPEKS) / 100
|
||||
if settings.YOOKASSA_MAX_AMOUNT_KOPEKS:
|
||||
max_amount = float(settings.YOOKASSA_MAX_AMOUNT_KOPEKS) / 100
|
||||
|
||||
methods.append(
|
||||
MiniAppPaymentMethod(
|
||||
id="yookassa",
|
||||
type="card",
|
||||
icon="💳",
|
||||
requires_amount=True,
|
||||
currency="RUB",
|
||||
min_amount=min_amount,
|
||||
max_amount=max_amount,
|
||||
)
|
||||
)
|
||||
|
||||
if settings.TRIBUTE_ENABLED:
|
||||
methods.append(
|
||||
MiniAppPaymentMethod(
|
||||
id="tribute",
|
||||
type="card",
|
||||
icon="💳",
|
||||
requires_amount=False,
|
||||
currency="RUB",
|
||||
)
|
||||
)
|
||||
|
||||
if settings.is_mulenpay_enabled():
|
||||
min_amount = None
|
||||
max_amount = None
|
||||
if settings.MULENPAY_MIN_AMOUNT_KOPEKS:
|
||||
min_amount = float(settings.MULENPAY_MIN_AMOUNT_KOPEKS) / 100
|
||||
if settings.MULENPAY_MAX_AMOUNT_KOPEKS:
|
||||
max_amount = float(settings.MULENPAY_MAX_AMOUNT_KOPEKS) / 100
|
||||
|
||||
methods.append(
|
||||
MiniAppPaymentMethod(
|
||||
id="mulenpay",
|
||||
type="card",
|
||||
icon="💳",
|
||||
requires_amount=True,
|
||||
currency="RUB",
|
||||
min_amount=min_amount,
|
||||
max_amount=max_amount,
|
||||
)
|
||||
)
|
||||
|
||||
if settings.is_pal24_enabled():
|
||||
min_amount = None
|
||||
max_amount = None
|
||||
if settings.PAL24_MIN_AMOUNT_KOPEKS:
|
||||
min_amount = float(settings.PAL24_MIN_AMOUNT_KOPEKS) / 100
|
||||
if settings.PAL24_MAX_AMOUNT_KOPEKS:
|
||||
max_amount = float(settings.PAL24_MAX_AMOUNT_KOPEKS) / 100
|
||||
|
||||
methods.append(
|
||||
MiniAppPaymentMethod(
|
||||
id="pal24",
|
||||
type="sbp",
|
||||
icon="🏦",
|
||||
requires_amount=True,
|
||||
currency="RUB",
|
||||
min_amount=min_amount,
|
||||
max_amount=max_amount,
|
||||
)
|
||||
)
|
||||
|
||||
if settings.is_cryptobot_enabled():
|
||||
methods.append(
|
||||
MiniAppPaymentMethod(
|
||||
id="cryptobot",
|
||||
type="crypto",
|
||||
icon="🪙",
|
||||
requires_amount=True,
|
||||
currency="RUB",
|
||||
min_amount=100.0,
|
||||
max_amount=100000.0,
|
||||
)
|
||||
)
|
||||
|
||||
return methods
|
||||
|
||||
|
||||
def _extract_offer_test_squad_uuids(offer: Any) -> List[str]:
|
||||
extra = _extract_offer_extra(offer)
|
||||
raw = extra.get("test_squad_uuids") or extra.get("squads") or []
|
||||
@@ -1316,382 +1201,6 @@ async def get_subscription_details(
|
||||
)
|
||||
|
||||
|
||||
@router.get("/payments/methods", response_model=MiniAppPaymentMethodsResponse)
|
||||
async def list_payment_methods() -> MiniAppPaymentMethodsResponse:
|
||||
return MiniAppPaymentMethodsResponse(methods=_build_payment_methods_payload())
|
||||
|
||||
|
||||
@router.post("/payments/create", response_model=MiniAppCreatePaymentResponse)
|
||||
async def create_payment_link(
|
||||
payload: MiniAppCreatePaymentRequest,
|
||||
db: AsyncSession = Depends(get_db_session),
|
||||
) -> MiniAppCreatePaymentResponse:
|
||||
try:
|
||||
webapp_data = parse_webapp_init_data(payload.init_data, settings.BOT_TOKEN)
|
||||
except TelegramWebAppAuthError as error:
|
||||
raise HTTPException(
|
||||
status.HTTP_401_UNAUTHORIZED,
|
||||
detail={"code": "unauthorized", "message": str(error)},
|
||||
) from error
|
||||
|
||||
telegram_user = webapp_data.get("user")
|
||||
if not isinstance(telegram_user, dict) or "id" not in telegram_user:
|
||||
raise HTTPException(
|
||||
status.HTTP_400_BAD_REQUEST,
|
||||
detail={"code": "invalid_user", "message": "Invalid Telegram user payload"},
|
||||
)
|
||||
|
||||
try:
|
||||
telegram_id = int(telegram_user["id"])
|
||||
except (TypeError, ValueError):
|
||||
raise HTTPException(
|
||||
status.HTTP_400_BAD_REQUEST,
|
||||
detail={"code": "invalid_user", "message": "Invalid Telegram user identifier"},
|
||||
) from None
|
||||
|
||||
user = await get_user_by_telegram_id(db, telegram_id)
|
||||
if not user:
|
||||
raise HTTPException(
|
||||
status.HTTP_404_NOT_FOUND,
|
||||
detail={"code": "user_not_found", "message": "User not found"},
|
||||
)
|
||||
|
||||
method_id = (payload.method or "").strip().lower()
|
||||
if not method_id:
|
||||
raise HTTPException(
|
||||
status.HTTP_400_BAD_REQUEST,
|
||||
detail={"code": "invalid_method", "message": "Payment method is required"},
|
||||
)
|
||||
|
||||
available_methods = {method.id: method for method in _build_payment_methods_payload()}
|
||||
method_config = available_methods.get(method_id)
|
||||
if not method_config:
|
||||
raise HTTPException(
|
||||
status.HTTP_404_NOT_FOUND,
|
||||
detail={"code": "method_not_available", "message": "Payment method is not available"},
|
||||
)
|
||||
|
||||
currency_code = (payload.currency or method_config.currency or "RUB").upper()
|
||||
if currency_code != "RUB":
|
||||
raise HTTPException(
|
||||
status.HTTP_400_BAD_REQUEST,
|
||||
detail={"code": "unsupported_currency", "message": "Only RUB currency is supported"},
|
||||
)
|
||||
|
||||
amount_decimal: Optional[Decimal] = None
|
||||
amount_kopeks: Optional[int] = None
|
||||
if method_config.requires_amount:
|
||||
if payload.amount is None:
|
||||
raise HTTPException(
|
||||
status.HTTP_400_BAD_REQUEST,
|
||||
detail={"code": "amount_required", "message": "Amount is required for this payment method"},
|
||||
)
|
||||
|
||||
try:
|
||||
amount_decimal = Decimal(str(payload.amount))
|
||||
except (InvalidOperation, TypeError):
|
||||
raise HTTPException(
|
||||
status.HTTP_400_BAD_REQUEST,
|
||||
detail={"code": "invalid_amount", "message": "Amount must be a valid number"},
|
||||
) from None
|
||||
|
||||
if amount_decimal <= Decimal("0"):
|
||||
raise HTTPException(
|
||||
status.HTTP_400_BAD_REQUEST,
|
||||
detail={"code": "invalid_amount", "message": "Amount must be greater than zero"},
|
||||
)
|
||||
|
||||
if method_config.min_amount is not None and amount_decimal < Decimal(str(method_config.min_amount)):
|
||||
raise HTTPException(
|
||||
status.HTTP_400_BAD_REQUEST,
|
||||
detail={
|
||||
"code": "amount_too_low",
|
||||
"message": f"Minimum amount is {method_config.min_amount:.2f} RUB",
|
||||
},
|
||||
)
|
||||
|
||||
if method_config.max_amount is not None and amount_decimal > Decimal(str(method_config.max_amount)):
|
||||
raise HTTPException(
|
||||
status.HTTP_400_BAD_REQUEST,
|
||||
detail={
|
||||
"code": "amount_too_high",
|
||||
"message": f"Maximum amount is {method_config.max_amount:.2f} RUB",
|
||||
},
|
||||
)
|
||||
|
||||
amount_kopeks = int((amount_decimal * 100).to_integral_value(rounding=ROUND_HALF_UP))
|
||||
else:
|
||||
amount_decimal = Decimal("0")
|
||||
|
||||
description_amount = amount_kopeks or 0
|
||||
description = settings.get_balance_payment_description(description_amount)
|
||||
payment_service = PaymentService()
|
||||
|
||||
if method_id == "yookassa":
|
||||
if amount_kopeks is None:
|
||||
raise HTTPException(
|
||||
status.HTTP_400_BAD_REQUEST,
|
||||
detail={"code": "amount_required", "message": "Amount is required for YooKassa"},
|
||||
)
|
||||
|
||||
payment_result = await payment_service.create_yookassa_payment(
|
||||
db=db,
|
||||
user_id=user.id,
|
||||
amount_kopeks=amount_kopeks,
|
||||
description=description,
|
||||
metadata={
|
||||
"user_telegram_id": str(user.telegram_id),
|
||||
"user_username": user.username or "",
|
||||
"purpose": "balance_topup",
|
||||
},
|
||||
)
|
||||
|
||||
if not payment_result or not payment_result.get("confirmation_url"):
|
||||
raise HTTPException(
|
||||
status.HTTP_502_BAD_GATEWAY,
|
||||
detail={"code": "payment_creation_failed", "message": "Failed to create YooKassa payment"},
|
||||
)
|
||||
|
||||
return MiniAppCreatePaymentResponse(
|
||||
method=method_id,
|
||||
redirect_url=str(payment_result.get("confirmation_url")),
|
||||
amount_kopeks=amount_kopeks,
|
||||
payment_id=str(payment_result.get("yookassa_payment_id")),
|
||||
extra={"localPaymentId": payment_result.get("local_payment_id")},
|
||||
)
|
||||
|
||||
if method_id == "mulenpay":
|
||||
if amount_kopeks is None:
|
||||
raise HTTPException(
|
||||
status.HTTP_400_BAD_REQUEST,
|
||||
detail={"code": "amount_required", "message": "Amount is required for Mulen Pay"},
|
||||
)
|
||||
|
||||
payment_result = await payment_service.create_mulenpay_payment(
|
||||
db=db,
|
||||
user_id=user.id,
|
||||
amount_kopeks=amount_kopeks,
|
||||
description=description,
|
||||
language=user.language,
|
||||
)
|
||||
|
||||
if not payment_result or not payment_result.get("payment_url"):
|
||||
raise HTTPException(
|
||||
status.HTTP_502_BAD_GATEWAY,
|
||||
detail={"code": "payment_creation_failed", "message": "Failed to create Mulen Pay payment"},
|
||||
)
|
||||
|
||||
return MiniAppCreatePaymentResponse(
|
||||
method=method_id,
|
||||
redirect_url=str(payment_result.get("payment_url")),
|
||||
amount_kopeks=amount_kopeks,
|
||||
payment_id=str(payment_result.get("mulen_payment_id")),
|
||||
extra={"localPaymentId": payment_result.get("local_payment_id")},
|
||||
)
|
||||
|
||||
if method_id == "pal24":
|
||||
if amount_kopeks is None:
|
||||
raise HTTPException(
|
||||
status.HTTP_400_BAD_REQUEST,
|
||||
detail={"code": "amount_required", "message": "Amount is required for PayPalych"},
|
||||
)
|
||||
|
||||
language = user.language or settings.DEFAULT_LANGUAGE or "ru"
|
||||
payment_result = await payment_service.create_pal24_payment(
|
||||
db=db,
|
||||
user_id=user.id,
|
||||
amount_kopeks=amount_kopeks,
|
||||
description=description,
|
||||
language=language,
|
||||
)
|
||||
|
||||
if not payment_result:
|
||||
raise HTTPException(
|
||||
status.HTTP_502_BAD_GATEWAY,
|
||||
detail={"code": "payment_creation_failed", "message": "Failed to create PayPalych payment"},
|
||||
)
|
||||
|
||||
redirect_url = (
|
||||
payment_result.get("sbp_url")
|
||||
or payment_result.get("transfer_url")
|
||||
or payment_result.get("link_url")
|
||||
or payment_result.get("card_url")
|
||||
or payment_result.get("link_page_url")
|
||||
)
|
||||
|
||||
if not redirect_url:
|
||||
raise HTTPException(
|
||||
status.HTTP_502_BAD_GATEWAY,
|
||||
detail={"code": "payment_creation_failed", "message": "Payment link is unavailable"},
|
||||
)
|
||||
|
||||
extra_payload = {
|
||||
"billId": payment_result.get("bill_id"),
|
||||
"orderId": payment_result.get("order_id"),
|
||||
"sbpUrl": payment_result.get("sbp_url"),
|
||||
"cardUrl": payment_result.get("card_url"),
|
||||
"localPaymentId": payment_result.get("local_payment_id"),
|
||||
}
|
||||
|
||||
return MiniAppCreatePaymentResponse(
|
||||
method=method_id,
|
||||
redirect_url=str(redirect_url),
|
||||
amount_kopeks=amount_kopeks,
|
||||
payment_id=str(payment_result.get("bill_id")),
|
||||
extra={key: value for key, value in extra_payload.items() if value},
|
||||
)
|
||||
|
||||
if method_id == "stars":
|
||||
if amount_kopeks is None:
|
||||
raise HTTPException(
|
||||
status.HTTP_400_BAD_REQUEST,
|
||||
detail={"code": "amount_required", "message": "Amount is required for Telegram Stars"},
|
||||
)
|
||||
|
||||
try:
|
||||
default_props = DefaultBotProperties(parse_mode=ParseMode.HTML)
|
||||
async with Bot(token=settings.BOT_TOKEN, default=default_props) as bot:
|
||||
stars_payment_service = PaymentService(bot)
|
||||
invoice_link = await stars_payment_service.create_stars_invoice(
|
||||
amount_kopeks=amount_kopeks,
|
||||
description=description,
|
||||
payload=f"miniapp_stars_{user.id}_{amount_kopeks}",
|
||||
)
|
||||
except Exception as error:
|
||||
raise HTTPException(
|
||||
status.HTTP_502_BAD_GATEWAY,
|
||||
detail={"code": "payment_creation_failed", "message": f"Failed to create Stars invoice: {error}"},
|
||||
) from error
|
||||
|
||||
if not invoice_link:
|
||||
raise HTTPException(
|
||||
status.HTTP_502_BAD_GATEWAY,
|
||||
detail={"code": "payment_creation_failed", "message": "Failed to create Stars invoice"},
|
||||
)
|
||||
|
||||
stars_amount = TelegramStarsService.calculate_stars_from_rubles(float(amount_decimal))
|
||||
|
||||
return MiniAppCreatePaymentResponse(
|
||||
method=method_id,
|
||||
redirect_url=str(invoice_link),
|
||||
amount_kopeks=amount_kopeks,
|
||||
payment_id=None,
|
||||
extra={
|
||||
"stars": stars_amount,
|
||||
"rate": settings.get_stars_rate(),
|
||||
},
|
||||
)
|
||||
|
||||
if method_id == "cryptobot":
|
||||
if amount_kopeks is None:
|
||||
raise HTTPException(
|
||||
status.HTTP_400_BAD_REQUEST,
|
||||
detail={"code": "amount_required", "message": "Amount is required for CryptoBot"},
|
||||
)
|
||||
|
||||
rate = await currency_converter.get_usd_to_rub_rate()
|
||||
if not rate or rate <= 0:
|
||||
raise HTTPException(
|
||||
status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail={"code": "rate_unavailable", "message": "Unable to load currency rate"},
|
||||
)
|
||||
|
||||
rate_decimal = Decimal(str(rate))
|
||||
amount_usd_decimal = (amount_decimal / rate_decimal).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
|
||||
|
||||
if amount_usd_decimal < Decimal("1"):
|
||||
raise HTTPException(
|
||||
status.HTTP_400_BAD_REQUEST,
|
||||
detail={"code": "amount_too_low", "message": "Minimum amount is 1.00 USD"},
|
||||
)
|
||||
|
||||
if amount_usd_decimal > Decimal("1000"):
|
||||
raise HTTPException(
|
||||
status.HTTP_400_BAD_REQUEST,
|
||||
detail={"code": "amount_too_high", "message": "Maximum amount is 1000.00 USD"},
|
||||
)
|
||||
|
||||
payment_result = await payment_service.create_cryptobot_payment(
|
||||
db=db,
|
||||
user_id=user.id,
|
||||
amount_usd=float(amount_usd_decimal),
|
||||
asset=settings.CRYPTOBOT_DEFAULT_ASSET,
|
||||
description=f"Пополнение баланса на {settings.format_price(amount_kopeks)} ({amount_usd_decimal} USD)",
|
||||
payload=f"miniapp_cryptobot_{user.id}_{amount_kopeks}",
|
||||
)
|
||||
|
||||
if not payment_result:
|
||||
raise HTTPException(
|
||||
status.HTTP_502_BAD_GATEWAY,
|
||||
detail={"code": "payment_creation_failed", "message": "Failed to create CryptoBot invoice"},
|
||||
)
|
||||
|
||||
redirect_url = (
|
||||
payment_result.get("bot_invoice_url")
|
||||
or payment_result.get("mini_app_invoice_url")
|
||||
or payment_result.get("web_app_invoice_url")
|
||||
)
|
||||
|
||||
if not redirect_url:
|
||||
raise HTTPException(
|
||||
status.HTTP_502_BAD_GATEWAY,
|
||||
detail={"code": "payment_creation_failed", "message": "Payment link is unavailable"},
|
||||
)
|
||||
|
||||
extra_payload = {
|
||||
"invoiceId": payment_result.get("invoice_id"),
|
||||
"asset": payment_result.get("asset"),
|
||||
"botInvoiceUrl": payment_result.get("bot_invoice_url"),
|
||||
"miniAppInvoiceUrl": payment_result.get("mini_app_invoice_url"),
|
||||
"webAppInvoiceUrl": payment_result.get("web_app_invoice_url"),
|
||||
"localPaymentId": payment_result.get("local_payment_id"),
|
||||
"amountUsd": float(amount_usd_decimal),
|
||||
}
|
||||
|
||||
return MiniAppCreatePaymentResponse(
|
||||
method=method_id,
|
||||
redirect_url=str(redirect_url),
|
||||
amount_kopeks=amount_kopeks,
|
||||
payment_id=str(payment_result.get("invoice_id")),
|
||||
extra={key: value for key, value in extra_payload.items() if value is not None},
|
||||
)
|
||||
|
||||
if method_id == "tribute":
|
||||
try:
|
||||
default_props = DefaultBotProperties(parse_mode=ParseMode.HTML)
|
||||
async with Bot(token=settings.BOT_TOKEN, default=default_props) as bot:
|
||||
tribute_service = TributeService(bot)
|
||||
payment_url = await tribute_service.create_payment_link(
|
||||
user_id=user.telegram_id,
|
||||
amount_kopeks=0,
|
||||
description=description,
|
||||
)
|
||||
except Exception as error:
|
||||
raise HTTPException(
|
||||
status.HTTP_502_BAD_GATEWAY,
|
||||
detail={"code": "payment_creation_failed", "message": f"Failed to create Tribute payment: {error}"},
|
||||
) from error
|
||||
|
||||
if not payment_url:
|
||||
raise HTTPException(
|
||||
status.HTTP_502_BAD_GATEWAY,
|
||||
detail={"code": "payment_creation_failed", "message": "Failed to create Tribute payment"},
|
||||
)
|
||||
|
||||
return MiniAppCreatePaymentResponse(
|
||||
method=method_id,
|
||||
redirect_url=str(payment_url),
|
||||
amount_kopeks=None,
|
||||
payment_id=None,
|
||||
extra={},
|
||||
)
|
||||
|
||||
raise HTTPException(
|
||||
status.HTTP_400_BAD_REQUEST,
|
||||
detail={"code": "unsupported_method", "message": "Unsupported payment method"},
|
||||
)
|
||||
|
||||
|
||||
@router.post(
|
||||
"/promo-codes/activate",
|
||||
response_model=MiniAppPromoCodeActivationResponse,
|
||||
|
||||
@@ -253,38 +253,6 @@ class MiniAppReferralInfo(BaseModel):
|
||||
referrals: Optional[MiniAppReferralList] = None
|
||||
|
||||
|
||||
class MiniAppPaymentMethod(BaseModel):
|
||||
id: str
|
||||
type: str
|
||||
icon: Optional[str] = None
|
||||
requires_amount: bool = False
|
||||
currency: str = "RUB"
|
||||
min_amount: Optional[float] = None
|
||||
max_amount: Optional[float] = None
|
||||
amount_step: Optional[float] = None
|
||||
metadata: Dict[str, Any] = Field(default_factory=dict)
|
||||
|
||||
|
||||
class MiniAppPaymentMethodsResponse(BaseModel):
|
||||
methods: List[MiniAppPaymentMethod] = Field(default_factory=list)
|
||||
|
||||
|
||||
class MiniAppCreatePaymentRequest(BaseModel):
|
||||
init_data: str = Field(..., alias="initData")
|
||||
method: str
|
||||
amount: Optional[float] = None
|
||||
currency: Optional[str] = None
|
||||
|
||||
|
||||
class MiniAppCreatePaymentResponse(BaseModel):
|
||||
success: bool = True
|
||||
method: str
|
||||
redirect_url: Optional[str] = None
|
||||
amount_kopeks: Optional[int] = None
|
||||
payment_id: Optional[str] = None
|
||||
extra: Dict[str, Any] = Field(default_factory=dict)
|
||||
|
||||
|
||||
class MiniAppSubscriptionResponse(BaseModel):
|
||||
success: bool = True
|
||||
subscription_id: int
|
||||
|
||||
-1119
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user