feat: add subscription and transaction repositories

- Implemented SubscriptionRepository with methods to get, create, and update subscriptions.
- Added BalanceTXRepository for creating and retrieving balance transactions.
- Introduced a test script for simulating Pally webhook for local testing.
This commit is contained in:
2026-04-27 21:33:25 +07:00
parent 049f31118d
commit 287f8eebda
34 changed files with 3401 additions and 53 deletions

View File

@@ -2,11 +2,13 @@ from collections.abc import AsyncGenerator
from contextlib import asynccontextmanager
from aiogram import Bot
from aiogram.client.default import DefaultBotProperties
from fastapi import FastAPI
from api.routes import routers
from config import settings
from repositories.bills import BillsRepository
from repositories.subscriptions import SubscriptionRepository
from repositories.users import UserRepository
from schemas.di import APIDependenciesDTO
from services.billing_service import BillingService
@@ -16,13 +18,15 @@ from services.user_service import UserService
@asynccontextmanager
async def lifespan(app: FastAPI) -> AsyncGenerator:
# Bot Init
bot = Bot(token=settings.bot_token)
bot_default = DefaultBotProperties(parse_mode="HTML")
bot = Bot(token=settings.bot_token, default=bot_default)
app.state.bot = bot
user_repository = UserRepository()
user_service = UserService(user_repository)
bills_repository = BillsRepository()
subscription_repository = SubscriptionRepository()
user_service = UserService(user_repository, subscription_repository=subscription_repository)
bills_service = BillingService(
user_repository=user_repository, bills_repository=bills_repository
)

View File

@@ -10,6 +10,8 @@ from sqlalchemy.ext.asyncio import AsyncSession
from api.core.deps import get_bot, get_db, get_deps
from api.core.notifications import successful_payment_notification
from config import settings
from db.models.bills import DepositStatus
from db.models.transactions import BalanceTxType
from misc.pally import BillStatus
from schemas.di import APIDependenciesDTO
@@ -56,16 +58,38 @@ async def pally_callback(
logger.critical("Bill %s is not found in db", bill_id)
return "OK"
if bill.status != DepositStatus.PENDING:
logger.warning("bill=%s is already paid according to the db", bill.id)
return "OK"
try:
amount = int(req_amount)
await deps.user_repository.increase_user_balance(session, bill.creator_id, amount=amount)
if bill.amount != amount:
logger.warning("requested amount for bill=%s is not equal to db entry", bill.id)
return "OK"
await deps.user_repository.increase_user_balance(
session,
bill.creator_id,
amount=amount,
tx_type=BalanceTxType.DEPOSIT,
description="personal balance deposit via PALLY",
)
await successful_payment_notification(bot, bill.creator_id, amount)
referal = bill.user.referal_id
user = await deps.user_repository.get_user_by_id(session, bill.creator_id)
referal = user.referal_id if user else None
if referal is not None:
referal_amount = math.floor(amount * (settings.referal_bonus / 100))
await deps.user_repository.increase_user_balance(session, referal, referal_amount)
await deps.user_repository.increase_user_balance(
session,
referal,
referal_amount,
tx_type=BalanceTxType.REFERRAL_BONUS,
description=f"referal reward for referal_id={bill.creator_id}",
)
await successful_payment_notification(bot, referal, referal_amount)
except Exception:
@@ -75,4 +99,8 @@ async def pally_callback(
bill.creator_id,
)
await deps.bills_repository.update_bill_status(
session, int(bill.id), status=DepositStatus.SUCCESS
)
return "OK"