1+ import logging
12from abc import ABC , abstractmethod
23
4+ import requests
5+ from aiogram import Bot
6+ from aiogram .fsm .storage .redis import RedisStorage
7+ from aiogram .utils .i18n import I18n
8+ from aiogram .utils .i18n import gettext as _
9+ from aiogram .utils .i18n import lazy_gettext as __
10+ from aiohttp .web import Application
11+ from sqlalchemy .ext .asyncio import async_sessionmaker
12+
13+ from app .bot .models import ServicesContainer , SubscriptionData
14+ from app .bot .routers .main_menu .handler import redirect_to_main_menu
15+ from app .bot .utils .constants import (
16+ DEFAULT_LANGUAGE ,
17+ EVENT_PAYMENT_CANCELED_TAG ,
18+ EVENT_PAYMENT_SUCCEEDED_TAG ,
19+ Currency ,
20+ TransactionStatus ,
21+ )
22+ from app .bot .utils .formatting import format_device_count , format_subscription_period
23+ from app .config import Config
24+ from app .db .models import Transaction , User
25+
26+ logger = logging .getLogger (__name__ )
27+
328from app .bot .models import SubscriptionData
429from app .bot .utils .constants import Currency
530
@@ -9,6 +34,24 @@ class PaymentGateway(ABC):
934 currency : Currency
1035 callback : str
1136
37+ def __init__ (
38+ self ,
39+ app : Application ,
40+ config : Config ,
41+ session : async_sessionmaker ,
42+ storage : RedisStorage ,
43+ bot : Bot ,
44+ i18n : I18n ,
45+ services : ServicesContainer ,
46+ ):
47+ self .app = app
48+ self .config = config
49+ self .session = session
50+ self .storage = storage
51+ self .bot = bot
52+ self .i18n = i18n
53+ self .services = services
54+
1255 @abstractmethod
1356 async def create_payment (self , data : SubscriptionData ) -> str :
1457 pass
@@ -20,3 +63,91 @@ async def handle_payment_succeeded(self, payment_id: str) -> None:
2063 @abstractmethod
2164 async def handle_payment_canceled (self , payment_id : str ) -> None :
2265 pass
66+
67+ async def _on_payment_succeeded (self , payment_id : str ) -> None :
68+ logger .info (f"Payment succeeded { payment_id } " )
69+
70+ async with self .session () as session :
71+ transaction = await Transaction .get_by_id (session = session , payment_id = payment_id )
72+ data = SubscriptionData .unpack (transaction .subscription )
73+ logger .debug (f"Subscription data unpacked: { data } " )
74+ user = await User .get (session = session , tg_id = data .user_id )
75+
76+ await Transaction .update (
77+ session = session ,
78+ payment_id = payment_id ,
79+ status = TransactionStatus .COMPLETED ,
80+ )
81+
82+ await self .services .notification .notify_developer (
83+ text = EVENT_PAYMENT_SUCCEEDED_TAG
84+ + "\n \n "
85+ + _ ("payment:event:payment_succeeded" ).format (
86+ payment_id = payment_id ,
87+ user_id = user .tg_id ,
88+ devices = format_device_count (data .devices ),
89+ duration = format_subscription_period (data .duration ),
90+ ),
91+ )
92+
93+ locale = user .language_code if user else DEFAULT_LANGUAGE
94+ with self .i18n .use_locale (locale ):
95+ await redirect_to_main_menu (bot = self .bot , user = user , storage = self .storage )
96+
97+ if data .is_extend :
98+ await self .services .vpn .extend_subscription (
99+ user = user ,
100+ devices = data .devices ,
101+ duration = data .duration ,
102+ )
103+ logger .info (f"Subscription extended for user { user .tg_id } " )
104+ await self .services .notification .notify_extend_success (
105+ user_id = user .tg_id ,
106+ data = data ,
107+ )
108+ elif data .is_change :
109+ await self .services .vpn .change_subscription (
110+ user = user ,
111+ devices = data .devices ,
112+ duration = data .duration ,
113+ )
114+ logger .info (f"Subscription changed for user { user .tg_id } " )
115+ await self .services .notification .notify_change_success (
116+ user_id = user .tg_id ,
117+ data = data ,
118+ )
119+ else :
120+ await self .services .vpn .create_subscription (
121+ user = user ,
122+ devices = data .devices ,
123+ duration = data .duration ,
124+ )
125+ logger .info (f"Subscription created for user { user .tg_id } " )
126+ key = await self .services .vpn .get_key (user )
127+ await self .services .notification .notify_purchase_success (
128+ user_id = user .tg_id ,
129+ key = key ,
130+ )
131+
132+ async def _on_payment_canceled (self , payment_id : str ) -> None :
133+ logger .info (f"Payment canceled { payment_id } " )
134+ async with self .session () as session :
135+ transaction = await Transaction .get_by_id (session = session , payment_id = payment_id )
136+ data = SubscriptionData .unpack (transaction .subscription )
137+
138+ await Transaction .update (
139+ session = session ,
140+ payment_id = payment_id ,
141+ status = TransactionStatus .CANCELED ,
142+ )
143+
144+ await self .services .notification .notify_developer (
145+ text = EVENT_PAYMENT_CANCELED_TAG
146+ + "\n \n "
147+ + _ ("payment:event:payment_canceled" ).format (
148+ payment_id = payment_id ,
149+ user_id = data .user_id ,
150+ devices = format_device_count (data .devices ),
151+ duration = format_subscription_period (data .duration ),
152+ ),
153+ )
0 commit comments