Files
malenia/api/routes/pally.py

107 lines
3.4 KiB
Python

import hashlib
import logging
import math
from aiogram import Bot
from fastapi import Depends, Form, HTTPException
from fastapi.routing import APIRouter
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
router = APIRouter(prefix="/pally")
logger = logging.getLogger(__name__)
@router.post("/result")
async def pally_callback(
InvId: str = Form(...),
OutSum: str = Form(...),
Commission: str = Form(...),
TrsId: str = Form(...),
Status: str = Form(...),
CurrencyIn: str = Form(...),
custom: str | None = Form(None),
SignatureValue: str = Form(...),
session: AsyncSession = Depends(get_db),
bot: Bot = Depends(get_bot),
deps: APIDependenciesDTO = Depends(get_deps),
):
oid = InvId
raw_string = f"{OutSum}:{InvId}:{settings.pally_token}"
expected_signature = hashlib.md5(raw_string.encode("utf-8")).hexdigest().upper()
if SignatureValue != expected_signature:
logger.critical("Invalid signature for TrsId %s", TrsId)
raise HTTPException(403, detail="Invalid signature.")
if Status != BillStatus.SUCCESS:
logger.info("Bill %s skipped: status=%s", TrsId, Status)
return "OK"
logger.info("Received successfully paid bill %s", TrsId)
if not oid.isdigit():
logger.critical("Invalid InvId format for TrsId %s", TrsId)
return "OK"
bill = await deps.bills_repository.get_bill_by_id(session, int(oid))
if not bill:
logger.critical("Bill %s is not found in db", TrsId)
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(float(OutSum))
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)
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,
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:
logger.exception(
"Exception caught while processing balances for TrsId %s (Creator: %s)",
TrsId,
bill.creator_id,
)
await deps.bills_repository.update_bill_status(
session, int(bill.id), status=DepositStatus.SUCCESS
)
return "OK"