diff --git a/README.md b/README.md index 2e29ae8..95f40d3 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ aaio.so return a pydantic's models for each response. Please write about all problems related to the library to [issues](https://github.com/kewldan/AAIO/issues) -API is up-to-date as of *07 August 2024*. +API is up-to-date as of *16 August 2024*. * PyPl - https://pypi.org/project/aaio/ * Github - https://github.com/kewldan/AAIO diff --git a/pyproject.toml b/pyproject.toml index 2d00dea..6313664 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ packages = ["src/aaio"] [project] name = "aaio" -version = "1.4.0" +version = "1.4.1" description = "Async AAIO api wrapper for python" readme = "README.md" authors = [{ name = "kewldan", email = "kewldanil1@gmail.com" }] diff --git a/src/aaio/client.py b/src/aaio/client.py index 28f065f..5035009 100644 --- a/src/aaio/client.py +++ b/src/aaio/client.py @@ -18,7 +18,8 @@ class AAIO: API for https://aaio.so/ """ - def __init__(self, merchant_id: str, secret_1: str, secret_2: str, api_key: str, default_currency: str = 'RUB', + def __init__(self, merchant_id: str, secret_1: str, secret_2: str | None = None, api_key: str | None = None, + default_currency: str = 'RUB', base_url: str = 'https://aaio.so'): """ Creates instance of one AAIO merchant API client @@ -67,12 +68,14 @@ def __generate_payment_params(self, amount: float, order_id: str, description: s email: str = None, referral: str = None, us_key: str = None, currency: str = None, language: str = 'ru'): + currency = currency or self._default_currency + return { 'merchant_id': self._merchant_id, 'amount': amount, 'currency': currency, 'order_id': order_id, - 'sign': self.__generate_sign(amount, order_id, currency or self._default_currency), + 'sign': self.__generate_sign(amount, order_id, currency), 'desc': description, 'lang': language, 'method': method, @@ -114,7 +117,7 @@ def create_payment(self, amount: float, order_id: str, description: str = None, async def get_pay_url(self, amount: float, order_id: str, description: str = None, method: str = None, email: str = None, referral: str = None, us_key: str = None, currency: str = None, - language: str = 'ru') -> dict: + language: str = 'ru') -> str: """ Creates payment URL See https://wiki.aaio.so/priem-platezhei/sozdanie-zakaza-zaprosom-rekomenduem for more detailed information @@ -138,7 +141,7 @@ async def get_pay_url(self, amount: float, order_id: str, description: str = Non response = await self.__create_request('/merchant/get_pay_url', params) - return response + return response['url'] async def get_ips(self) -> List[str]: response = await self.__create_request('/api/public/ips') @@ -157,6 +160,9 @@ async def get_payment_info(self, order_id: str) -> PaymentInfo: """ + if not self._api_key: + raise ValueError('API key is required for this method') + params = { 'merchant_id': self._merchant_id, 'order_id': order_id @@ -174,6 +180,9 @@ async def get_balances(self) -> Balance: Returns: Model from response JSON """ + if not self._api_key: + raise ValueError('API key is required for this method') + response = await self.__create_request('/api/balance') return Balance(**response) @@ -195,6 +204,9 @@ async def create_payoff(self, method: str, amount: float, wallet: str, payoff_id """ + if not self._api_key: + raise ValueError('API key is required for this method') + params = { 'my_id': payoff_id, 'method': method, @@ -213,6 +225,10 @@ async def get_payoff_sbp_banks(self) -> PayoffSbpBanks: See https://wiki.aaio.so/api/banki-dlya-vyvoda-sredstv-na-sbp Returns: list of banks """ + + if not self._api_key: + raise ValueError('API key is required for this method') + response = await self.__create_request('/api/sbp-banks-payoff') return PayoffSbpBanks(**response) @@ -232,6 +248,9 @@ async def get_payoff_info(self, payoff_id: str = None, aaio_id: str = None) -> P """ + if not self._api_key: + raise ValueError('API key is required for this method') + params = { 'my_id': payoff_id, 'id': aaio_id @@ -250,6 +269,9 @@ async def get_payoff_rates(self) -> PayoffRates: """ + if not self._api_key: + raise ValueError('API key is required for this method') + response = await self.__create_request('/api/rates-payoff') return PayoffRates(**response) @@ -263,6 +285,9 @@ async def get_payoff_methods(self) -> PayoffMethods: """ + if not self._api_key: + raise ValueError('API key is required for this method') + response = await self.__create_request('/api/methods-payoff') return PayoffMethods(**response) @@ -276,6 +301,9 @@ async def get_payment_methods(self) -> PaymentMethods: """ + if not self._api_key: + raise ValueError('API key is required for this method') + params = { 'merchant_id': self._merchant_id } @@ -301,10 +329,12 @@ async def __create_request(self, uri: str, params: dict = None) -> Optional[dict headers = { 'Accept': 'application/json', - 'Content-Type': 'application/x-www-form-urlencoded', - 'X-Api-Key': self._api_key + 'Content-Type': 'application/x-www-form-urlencoded' } + if self._api_key: + headers['X-Api-Key'] = self._api_key + async with aiohttp.ClientSession(self._base_url) as session: async with session.post(uri, headers=headers, data={k: v for k, v in params.items() if v is not None}) as r: @@ -315,5 +345,9 @@ async def __create_request(self, uri: str, params: dict = None) -> Optional[dict raise AAIOBadRequest(response['code'], response['message']) def is_valid_payment_webhook(self, data: PaymentWebhookData) -> bool: + + if self._secret_2 is None: + raise ValueError('2nd secret key is required for webhook validation') + return hashlib.sha256( f'{self._merchant_id}:{data.amount}:{self._secret_2}:{data.order_id}'.encode()).hexdigest() == data.sign