Files
backend/app/services/billing_service.py

80 lines
3.2 KiB
Python

import aiohttp
import logging
from typing import Dict, Any, Optional
from enum import Enum
class BillingErrorCode(Enum):
INSUFFICIENT_FUNDS = "INSUFFICIENT_FUNDS"
USER_NOT_FOUND = "USER_NOT_FOUND"
PAYMENT_FAILED = "PAYMENT_FAILED"
SERVICE_UNAVAILABLE = "SERVICE_UNAVAILABLE"
class BillingAdapter:
def __init__(self, base_url: str):
self.base_url = base_url
self.logger = logging.getLogger(__name__)
self.session = None
async def get_session(self):
if self.session is None:
self.session = aiohttp.ClientSession()
return self.session
async def withdraw_funds(self, user_id: int, amount: float, description: str = "") -> Dict[str, Any]:
"""
Списание средств через биллинг-сервис
"""
try:
session = await self.get_session()
payload = {
"user_id": user_id,
"amount": amount,
"description": description or f"Payment for subscription"
}
self.logger.info(f"Withdrawing {amount} from user {user_id}")
async with session.post(f"{self.base_url}/billing/payments/withdraw", json=payload) as response:
if response.status == 200:
result = await response.json()
if result.get("success"):
return {"status": "success"}
else:
error = result.get("error", "WITHDRAWAL_FAILED")
self.logger.error(f"Withdrawal failed: {error}")
return {"status": "error", "code": error}
else:
self.logger.error(f"Billing service error: {response.status}")
return {"status": "error", "code": "SERVICE_UNAVAILABLE"}
except aiohttp.ClientError as e:
self.logger.error(f"Billing service connection error: {str(e)}")
return {"status": "error", "code": "SERVICE_UNAVAILABLE"}
except Exception as e:
self.logger.error(f"Unexpected error in withdraw_funds: {str(e)}")
return {"status": "error", "code": "PAYMENT_FAILED"}
async def get_balance(self, user_id: int) -> Dict[str, Any]:
"""
Получение баланса пользователя
"""
try:
session = await self.get_session()
async with session.get(f"{self.base_url}/billing/balance/{user_id}") as response:
if response.status == 200:
result = await response.json()
return {"status": "success", "balance": result.get("balance", 0)}
elif response.status == 404:
return {"status": "error", "code": "USER_NOT_FOUND"}
else:
return {"status": "error", "code": "SERVICE_UNAVAILABLE"}
except Exception as e:
self.logger.error(f"Error getting balance: {str(e)}")
return {"status": "error", "code": "SERVICE_UNAVAILABLE"}
async def close(self):
if self.session:
await self.session.close()