├── .gitignore
├── AsyncPayments
├── __init__.py
├── aaio
│ ├── __init__.py
│ ├── api.py
│ └── models.py
├── cryptoBot
│ ├── __init__.py
│ ├── api.py
│ └── models.py
├── cryptomus
│ ├── __init__.py
│ ├── api.py
│ └── models.py
├── crystalPay
│ ├── __init__.py
│ ├── api.py
│ └── models.py
├── exceptions
│ ├── __init__.py
│ └── exceptions.py
├── freeKassa
│ ├── __init__.py
│ ├── api.py
│ └── models.py
├── lolz
│ ├── __init__.py
│ ├── api.py
│ └── models.py
├── payok
│ ├── __init__.py
│ ├── api.py
│ └── models.py
├── requests.py
├── ruKassa
│ ├── __init__.py
│ ├── api.py
│ └── models.py
└── xrocket
│ ├── __init__.py
│ ├── api.py
│ └── models.py
├── LICENSE
├── README.md
└── pyproject.toml
/.gitignore:
--------------------------------------------------------------------------------
1 | __pycache__
2 |
3 | .venv/
4 | venv/
5 | env/
6 |
7 | build/
8 | dist/
9 |
10 | *.egg-info/
11 |
12 | .github
13 |
14 | .idea
--------------------------------------------------------------------------------
/AsyncPayments/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/I-ToSa-I/AsyncPayments/fc34c6b1fc94424103b281e6a8ec299309ea50af/AsyncPayments/__init__.py
--------------------------------------------------------------------------------
/AsyncPayments/aaio/__init__.py:
--------------------------------------------------------------------------------
1 | from .api import AsyncAaio
--------------------------------------------------------------------------------
/AsyncPayments/aaio/api.py:
--------------------------------------------------------------------------------
1 | from ..requests import RequestsClient
2 | from .models import Order, OrderMethod, WithdrawalMethod, CreateWithdrawalInfo, Withdrawal, Balance
3 | from typing import Optional, Union, List
4 | from urllib.parse import urlencode
5 |
6 | import hashlib
7 |
8 |
9 | class AsyncAaio(RequestsClient):
10 | API_HOST: str = "https://aaio.so"
11 |
12 | def __init__(self, apikey: str, shopid: str, secretkey: str) -> None:
13 | '''
14 | Initialize Aaio API client
15 | :param apikey: Your API Key
16 | :param shopid: Your Shop ID
17 | :param secretkey: Your Secretkey №1
18 | '''
19 | super().__init__()
20 | self.__api_key = apikey
21 | self.__shop_id = shopid
22 | self.__secret_key = secretkey
23 | self.__headers = {
24 | "Accept": "application/json",
25 | "X-Api-Key": self.__api_key
26 | }
27 | self.__post_method = "POST"
28 | self.__payment_name = "aaio"
29 | self.check_values()
30 |
31 | def check_values(self):
32 | if not self.__secret_key or not self.__shop_id or not self.__api_key:
33 | raise ValueError('No SecretKey, ApiKey or ShopID specified')
34 |
35 | def __create_sign(self, amount: Union[float, int], currency: str, order_id: str) -> str:
36 | params_for_sing = ':'.join(map(
37 | str,
38 | [self.__shop_id, amount, currency, self.__secret_key, order_id])
39 | )
40 |
41 | return hashlib.sha256(params_for_sing.encode('utf-8')).hexdigest()
42 |
43 | async def create_payment_url(
44 | self,
45 | amount: float,
46 | order_id: Union[int, str],
47 | currency: Optional[str] = 'RUB',
48 | method: Optional[str] = None,
49 | desc: Optional[str] = None,
50 | email: Optional[str] = None,
51 | lang: Optional[str] = None,
52 | referal: Optional[str] = None,
53 | us_key: Optional[str] = None,
54 | ) -> str:
55 |
56 | """Generate payment url.
57 |
58 | Docs: https://wiki.aaio.so/priem-platezhei/sozdanie-zakaza
59 |
60 | :param amount: Order amount.
61 | :param order_id: Order number, which unique in your system, up to 16 characters, without spaces (aA-zZ, 0-9, :, -, _, [, ] , |)
62 | :param currency: Currency. Default to 'RUB' (RUB, UAH, EUR, USD)
63 | :param method: Payment Aaio system code name
64 | :param desc: Order description
65 | :param email: Buyer mail
66 | :param lang: Interface language. Default to 'ru' (ru, en)
67 | :param referal: Referral code
68 | :param us_key: Parameter that you want to get in the notification"""
69 |
70 | params = {
71 | 'merchant_id': self.__shop_id,
72 | 'amount': amount,
73 | 'order_id': order_id,
74 | 'currency': currency,
75 | 'method': method,
76 | 'desc': desc,
77 | 'email': email,
78 | 'lang': lang,
79 | 'referal': referal,
80 | 'us_key': us_key,
81 | 'sign': self.__create_sign(amount, currency, order_id),
82 | }
83 |
84 | self._delete_empty_fields(params)
85 |
86 | headers = self.__headers
87 | headers["Content-Type"] = "application/x-www-form-urlencoded"
88 | response = await self._request(self.__payment_name, self.__post_method, f"{self.API_HOST}/merchant/get_pay_url", headers=headers, data=urlencode(params))
89 |
90 | return response['url']
91 |
92 | async def get_balance(self) -> Balance:
93 | """Get available, referal and hold balance.
94 |
95 | Docs: https://wiki.aaio.so/api/poluchenie-balansa"""
96 |
97 | url = f'{self.API_HOST}/api/balance'
98 |
99 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers)
100 |
101 | return Balance(**response)
102 |
103 | async def get_order_info(self,
104 | order_id: Union[int, str]
105 | ) -> Order:
106 |
107 | """Get information about an order by OrderID.
108 |
109 | Docs: https://wiki.aaio.so/api/informaciya-o-zakaze
110 |
111 | :param order_id: OrderID (in your system)"""
112 |
113 | url = f'{self.API_HOST}/api/info-pay'
114 |
115 | params = {
116 | 'merchant_id': self.__shop_id,
117 | 'order_id': order_id,
118 | }
119 |
120 | self._delete_empty_fields(params)
121 |
122 | response = await self._request(self.__payment_name, self.__post_method, url, data=params, headers=self.__headers)
123 |
124 | return Order(**response)
125 |
126 | async def get_withdrawal_methods(self,
127 | method: Optional[str] = None
128 | ) -> Union[List[WithdrawalMethod], WithdrawalMethod]:
129 |
130 | """Get available methods for withdrawal.
131 |
132 | If method is None -> return dict with all methods.
133 |
134 | If a specific method -> return info about only this method.
135 |
136 | Docs: https://wiki.aaio.so/api/dostupnye-metody-dlya-vyvoda-sredstv
137 |
138 | :param method: Specific method. Default is None"""
139 |
140 | url = f'{self.API_HOST}/api/methods-payoff'
141 |
142 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers)
143 |
144 | if method is not None:
145 | return WithdrawalMethod(**response['list'][method])
146 | return [WithdrawalMethod(**method) for method in response["list"].values()]
147 |
148 | async def get_order_methods(self,
149 | method: Optional[str] = None
150 | ) -> Union[List[OrderMethod], OrderMethod]:
151 |
152 | """Get available methods for order.
153 |
154 | If method is None -> return dict with all methods.
155 |
156 | If a specific method -> return info about only this method.
157 |
158 | Docs: https://wiki.aaio.so/api/dostupnye-metody-dlya-sozdaniya-zakaza
159 |
160 | :param method: Specific method. Default is None"""
161 |
162 | url = f'{self.API_HOST}/api/methods-pay'
163 |
164 | params = {
165 | 'merchant_id': self.__shop_id,
166 | }
167 |
168 | response = await self._request(self.__payment_name, self.__post_method, url, data=params, headers=self.__headers)
169 |
170 | if method is not None:
171 | return OrderMethod.model_validate(response['list'][method])
172 | return [OrderMethod(**method) for method in response["list"].values()]
173 |
174 | async def get_withdrawal_info(self,
175 | my_id: Union[int, str],
176 | ) -> Withdrawal:
177 |
178 | """Get information about a withdrawal by WithdrawalID.
179 |
180 | Docs: https://wiki.aaio.so/api/informaciya-o-zayavke-na-vyvod-sredstv
181 |
182 | :param my_id: WithdrawalID (in your system)"""
183 |
184 | url = f'{self.API_HOST}/api/info-payoff'
185 |
186 | params = {
187 | 'my_id': my_id,
188 | }
189 |
190 | response = await self._request(self.__payment_name, self.__post_method, url, data=params, headers=self.__headers)
191 |
192 | return Withdrawal(**response)
193 |
194 | async def create_withdrawal(self,
195 | my_id: Union[int, str],
196 | method: str,
197 | amount: float,
198 | wallet: str,
199 | commission_type: Optional[int] = 0
200 | ) -> CreateWithdrawalInfo:
201 |
202 | """Create withdrawal.
203 |
204 | Docs: https://wiki.aaio.so/api/vyvod-sredstv
205 |
206 | :param my_id: WithdrawalID (in your system)
207 | :param method: Specific method for withdrawal
208 | :param amount: Withdrawal amount
209 | :param wallet: Wallet or number for withdrawal (Without +, " ", and separators)
210 | :param commission_type: Withdrawal commission type. Default to 0 (from the payment amount)"""
211 |
212 | url = f'{self.API_HOST}/api/create-payoff'
213 |
214 | params = {
215 | 'my_id': my_id,
216 | 'method': method,
217 | 'amount': amount,
218 | 'wallet': wallet,
219 | 'commission_type': commission_type,
220 | }
221 |
222 | response = await self._request(self.__payment_name, self.__post_method, url, data=params, headers=self.__headers)
223 |
224 | return CreateWithdrawalInfo(**response)
--------------------------------------------------------------------------------
/AsyncPayments/aaio/models.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel
2 | from typing import Union, Optional
3 |
4 |
5 | class Balance(BaseModel):
6 | balance: float
7 | referral: float
8 | hold: float
9 |
10 | class Order(BaseModel):
11 | id: str
12 | order_id: Union[int, str]
13 | desc: str
14 | merchant_id: str
15 | merchant_domain: str
16 | method: Optional[str] = None
17 | amount: Union[int, float]
18 | currency: str
19 | profit: Optional[float] = None
20 | commission: Optional[float] = None
21 | commission_client: Optional[float] = None
22 | commission_type: Optional[str] = None
23 | email: Optional[str] = None
24 | status: str
25 | date: str
26 | expired_date: str
27 | complete_date: Optional[str] = None
28 | us_vars: Optional[Union[dict, str, list]] = None
29 |
30 | class OrderMethodCurrencies(BaseModel):
31 | RUB: float
32 | UAH: float
33 | USD: float
34 | EUR: float
35 |
36 | class OrderMethod(BaseModel):
37 | name: str
38 | min: OrderMethodCurrencies
39 | max: OrderMethodCurrencies
40 | commission_percent: float
41 |
42 | class Withdrawal(BaseModel):
43 | id: str
44 | my_id: Union[int, str]
45 | method: str
46 | wallet: str
47 | amount: float
48 | amount_down: float
49 | commission: float
50 | commission_type: int
51 | status: str
52 | cancel_message: Optional[str] = None
53 | date: str
54 | complete_date: Optional[str] = None
55 |
56 | class WithdrawalMethod(BaseModel):
57 | name: str
58 | min: float
59 | max: float
60 | commission_percent: float
61 | commission_sum: float
62 |
63 | class CreateWithdrawalInfo(BaseModel):
64 | id: str
65 | my_id: Union[str, int]
66 | method: str
67 | wallet: str
68 | amount: float
69 | amount_in_currency: float
70 | amount_currency: str
71 | amount_rate: float
72 | amount_down: float
73 | commission: float
74 | commission_type: int
75 | status: str
--------------------------------------------------------------------------------
/AsyncPayments/cryptoBot/__init__.py:
--------------------------------------------------------------------------------
1 | from .api import AsyncCryptoBot
--------------------------------------------------------------------------------
/AsyncPayments/cryptoBot/api.py:
--------------------------------------------------------------------------------
1 | from ..requests import RequestsClient
2 | from typing import Optional, Union, List
3 | from .models import Invoice, MeInfo, Transfer, Balance, Check, ExchangeRate, Currency
4 |
5 |
6 | class AsyncCryptoBot(RequestsClient):
7 | API_HOST: str = "https://t.me/Cryptobot"
8 |
9 | def __init__(self, token: str, is_testnet: bool = False) -> None:
10 | """
11 | Initialize CryptoBot API client
12 | :param token: Your Token
13 | :param is_testnet: Optional. True - Testnet is on. False - Testnet is off. Default to False.
14 | """
15 | super().__init__()
16 | self.__token = token
17 | self.__headers = {
18 | 'Crypto-Pay-API-Token': self.__token,
19 | }
20 | if is_testnet:
21 | self.__base_url = "https://testnet-pay.crypt.bot/api"
22 | else:
23 | self.__base_url = "https://pay.crypt.bot/api"
24 | self.__post_method = "POST"
25 | self.__payment_name = "cryptoBot"
26 | self.check_values()
27 |
28 | def check_values(self):
29 | if not self.__token:
30 | raise ValueError('No Token specified')
31 |
32 | async def get_me(self) -> MeInfo:
33 | """Use this method to test your app's authentication token. Requires no parameters. On success, returns basic information about an app.
34 |
35 | Docs: https://help.crypt.bot/crypto-pay-api#getMe"""
36 |
37 | url = f'{self.__base_url}/getMe/'
38 |
39 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers)
40 |
41 | return MeInfo(**response['result'])
42 |
43 | async def create_invoice(self, amount: Union[int, float], currency_type: Optional[str] = None,
44 | asset: Optional[str] = None, fiat: Optional[str] = None,
45 | accepted_assets: Optional[list] = None, description: Optional[str] = None,
46 | hidden_message: Optional[str] = None, paid_btn_name: Optional[str] = None,
47 | paid_btn_url: Optional[str] = None, payload: Optional[str] = None,
48 | allow_comments: Optional[bool] = True, allow_anonymous: Optional[bool] = True,
49 | expires_in: Optional[int] = 3600) -> Invoice:
50 | """Use this method to create a new invoice.
51 |
52 | Docs: https://help.crypt.bot/crypto-pay-api#createInvoice
53 |
54 | :param amount: Amount of the invoice in float. For example: 125.50
55 | :param currency_type: Optional. Type of the price, can be “crypto” or “fiat”. Defaults to crypto.
56 | :param asset: Optional. Required if currency_type is “crypto”. Cryptocurrency alphabetic code. Supported assets: “USDT”, “TON”, “BTC”, “ETH”, “LTC”, “BNB”, “TRX” and “USDC”.
57 | :param fiat: Optional. Required if currency_type is “fiat”. Fiat currency code. Supported fiat currencies: “USD”, “EUR”, “RUB”, “BYN”, “UAH”, “GBP”, “CNY”, “KZT”, “UZS”, “GEL”, “TRY”, “AMD”, “THB”, “INR”, “BRL”, “IDR”, “AZN”, “AED”, “PLN” and “ILS".
58 | :param accepted_assets: Optional. List of cryptocurrency alphabetic codes separated comma. Assets which can be used to pay the invoice. Available only if currency_type is “fiat”. Supported assets: “USDT”, “TON”, “BTC”, “ETH”, “LTC”, “BNB”, “TRX” and “USDC” (and “JET” for testnet). Defaults to all currencies.
59 | :param description: Optional. Description for the invoice. User will see this description when they pay the invoice. Up to 1024 characters.
60 | :param hidden_message: Optional. Text of the message which will be presented to a user after the invoice is paid. Up to 2048 characters.
61 | :param paid_btn_name: Optional. Label of the button which will be presented to a user after the invoice is paid. Supported names:
62 | viewItem – “View Item”
63 | openChannel – “View Channel”
64 | openBot – “Open Bot”
65 | callback – “Return”
66 | :param paid_btn_url: Optional. Required if paid_btn_name is specified. URL opened using the button which will be presented to a user after the invoice is paid. You can set any callback link (for example, a success link or link to homepage). Starts with https or http.
67 | :param payload: Optional. Any data you want to attach to the invoice (for example, user ID, payment ID, ect). Up to 4kb.
68 | :param allow_comments: Optional. Allow a user to add a comment to the payment. Defaults to True.
69 | :param allow_anonymous: Optional. Allow a user to pay the invoice anonymously. Defaults to True.
70 | :param expires_in: Optional. You can set a payment time limit for the invoice in seconds. Values between 1-2678400 are accepted. Defaults to 3600
71 | """
72 |
73 | if allow_comments is True:
74 | allow_comments = "true"
75 | else:
76 | allow_comments = "false"
77 |
78 | if allow_anonymous is True:
79 | allow_anonymous = "true"
80 | else:
81 | allow_anonymous = "false"
82 |
83 | url = f'{self.__base_url}/createInvoice/'
84 |
85 | if accepted_assets and type(accepted_assets) == list:
86 | accepted_assets = ",".join(map(str, accepted_assets))
87 |
88 | params = {
89 | "asset": asset,
90 | "amount": amount,
91 | "description": description,
92 | "hidden_message": hidden_message,
93 | "paid_btn_name": paid_btn_name,
94 | "paid_btn_url": paid_btn_url,
95 | "payload": payload,
96 | "allow_comments": allow_comments,
97 | "allow_anonymous": allow_anonymous,
98 | "expires_in": expires_in,
99 | "fiat": fiat,
100 | "currency_type": currency_type,
101 | "accepted_assets": accepted_assets,
102 | }
103 |
104 | self._delete_empty_fields(params)
105 |
106 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers,
107 | params=params)
108 |
109 | return Invoice(**response['result'])
110 |
111 | async def delete_invoice(self, invoice_id: int) -> bool:
112 | """Use this method to delete invoices created by your app. Returns True on success.
113 |
114 | Docs: https://help.crypt.bot/crypto-pay-api#deleteInvoice
115 |
116 | :param invoice_id: Invoice ID"""
117 |
118 | url = f'{self.__base_url}/deleteInvoice/'
119 | params = {
120 | "invoice_id": invoice_id,
121 | }
122 |
123 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers,
124 | params=params)
125 |
126 | return bool(response['result'])
127 |
128 | async def create_check(self, amount: Union[float, int], asset: str) -> Check:
129 | """Use this method to create a new check.
130 |
131 | Docs: https://help.crypt.bot/crypto-pay-api#createCheck
132 |
133 | :param amount: Amount of the invoice in float. For example: 125.50
134 | :param asset: Cryptocurrency alphabetic code. Supported assets: “USDT”, “TON”, “BTC”, “ETH”, “LTC”, “BNB”, “TRX” and “USDC” (and “JET” for testnet).
135 | """
136 |
137 |
138 | url = f'{self.__base_url}/createCheck/'
139 |
140 | params = {
141 | "amount": amount,
142 | "asset": asset,
143 | }
144 |
145 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers,
146 | params=params)
147 |
148 | return Check(**response['result'])
149 |
150 | async def delete_check(self, check_id: int) -> bool:
151 | """Use this method to delete checks created by your app. Returns True on success.
152 |
153 | Docs: https://help.crypt.bot/crypto-pay-api#deleteCheck
154 |
155 | :param check_id: Check ID"""
156 |
157 | url = f'{self.__base_url}/deleteCheck/'
158 |
159 | params = {
160 | "check_id": check_id,
161 | }
162 |
163 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers,
164 | params=params)
165 |
166 | return bool(response['result'])
167 |
168 | async def transfer(self, user_id: int, asset: str, amount: Union[float, int], spend_id: str,
169 | comment: Optional[str] = None, disable_send_notification: Optional[bool] = False) -> Transfer:
170 | """Use this method to send coins from your app's balance to a user. This method must first be enabled in the security settings of your app. Open @CryptoBot (@CryptoTestnetBot for testnet), go to CryptoPay → MyApps, choose an app, then go to Security -> Transfers... and tap Enable.
171 |
172 | Docs: https://help.crypt.bot/crypto-pay-api#transfer
173 |
174 | :param user_id: User ID in Telegram. User must have previously used @CryptoBot (@CryptoTestnetBot for testnet).
175 | :param asset: Cryptocurrency alphabetic code. Supported assets: “USDT”, “TON”, “BTC”, “ETH”, “LTC”, “BNB”, “TRX” and “USDC” (and “JET” for testnet).
176 | :parameter amount: Amount of the transfer in float. The minimum and maximum amount limits for each of the supported assets roughly correspond to 1-25000 USD. Use get_exchange_rates() to convert amounts. For example: 125.50
177 | :param spend_id: Random UTF-8 string unique per transfer for idempotent requests. The same spend_id can be accepted only once from your app. Up to 64 symbols.
178 | :param comment: Optional. Comment for the transfer. Users will see this comment in the notification about the transfer. Up to 1024 symbols.
179 | :param disable_send_notification: Optional. Pass true to not send to the user the notification about the transfer. Defaults to false.
180 | """
181 |
182 | url = f'{self.__base_url}/transfer/'
183 |
184 | params = {
185 | "user_id": user_id,
186 | "asset": asset,
187 | "amount": amount,
188 | "spend_id": spend_id,
189 | "comment": comment,
190 | "disable_send_notification": disable_send_notification,
191 | }
192 |
193 | self._delete_empty_fields(params)
194 |
195 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers,
196 | params=params)
197 |
198 | return Transfer(**response['result'])
199 |
200 | async def get_invoices(self, asset: Optional[str] = None, fiat: Optional[str] = None,
201 | invoice_ids: Optional[list] = None, status: Optional[str] = None,
202 | offset: Optional[int] = None, count: Optional[int] = None) -> Union[Invoice, List[Invoice]]:
203 | """Use this method to get invoices created by your app.
204 |
205 | Docs: https://help.crypt.bot/crypto-pay-api#getInvoices
206 |
207 | :param asset: Optional. Cryptocurrency alphabetic code. Supported assets: “USDT”, “TON”, “BTC”, “ETH”, “LTC”, “BNB”, “TRX” and “USDC” (and “JET” for testnet). Defaults to all currencies.
208 | :param fiat: Optional. Fiat currency code. Supported fiat currencies: “USD”, “EUR”, “RUB”, “BYN”, “UAH”, “GBP”, “CNY”, “KZT”, “UZS”, “GEL”, “TRY”, “AMD”, “THB”, “INR”, “BRL”, “IDR”, “AZN”, “AED”, “PLN” and “ILS". Defaults to all currencies.
209 | :param invoice_ids: Optional. List of invoice IDs.
210 | :param status: Optional. Status of invoices to be returned. Available statuses: “active” and “paid”. Defaults to all statuses.
211 | :param offset: Optional. Offset needed to return a specific subset of invoices. Defaults to 0.
212 | :param count: Optional. Number of invoices to be returned. Values between 1-1000 are accepted. Defaults to 100.
213 | """
214 |
215 | url = f"{self.__base_url}/getInvoices"
216 |
217 | if invoice_ids and type(invoice_ids) == list:
218 | invoice_ids = ",".join(map(str, invoice_ids))
219 |
220 | params = {
221 | "asset": asset,
222 | "invoice_ids": invoice_ids,
223 | "fiat": fiat,
224 | "status": status,
225 | "offset": offset,
226 | "count": count,
227 | }
228 |
229 | self._delete_empty_fields(params)
230 |
231 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers,
232 | params=params)
233 |
234 | if len(response["result"]["items"]) > 0:
235 | if invoice_ids and isinstance(invoice_ids, int):
236 | return Invoice(**response["result"]["items"][0])
237 | return [Invoice(**invoice) for invoice in response["result"]["items"]]
238 |
239 | async def get_transfers(self, asset: Optional[str] = None, transfer_ids: Optional[list] = None,
240 | offset: Optional[int] = None, count: Optional[int] = None) -> Union[Transfer, List[Transfer]]:
241 | """Use this method to get transfers created by your app.
242 |
243 | Docs: https://help.crypt.bot/crypto-pay-api#getTransfers
244 |
245 | :param asset: Optional. Cryptocurrency alphabetic code. Supported assets: “USDT”, “TON”, “BTC”, “ETH”, “LTC”, “BNB”, “TRX” and “USDC” (and “JET” for testnet). Defaults to all currencies.
246 | :param transfer_ids: Optional. List of transfer IDs.
247 | :param offset: Optional. Offset needed to return a specific subset of transfers. Defaults to 0.
248 | :param count: Optional. Number of transfers to be returned. Values between 1-1000 are accepted. Defaults to 100.
249 | """
250 | url = f"{self.__base_url}/getTransfers"
251 |
252 | if transfer_ids and type(transfer_ids) == list:
253 | transfer_ids = ",".join(map(str, transfer_ids))
254 |
255 | params = {
256 | "asset": asset,
257 | "transfer_ids": transfer_ids,
258 | "offset": offset,
259 | "count": count,
260 | }
261 |
262 | self._delete_empty_fields(params)
263 |
264 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers,
265 | params=params)
266 |
267 | if len(response["result"]["items"]) > 0:
268 | if transfer_ids and isinstance(transfer_ids, int):
269 | return Transfer(**response["result"]["items"][0])
270 | return [Transfer(**transfer) for transfer in response["result"]["items"]]
271 |
272 | async def get_checks(self, asset: Optional[str] = None, check_ids: Optional[list] = None,
273 | status: Optional[str] = None, offset: Optional[int] = None,
274 | count: Optional[int] = None) -> Union[Check, List[Check]]:
275 | """Use this method to get checks created by your app.
276 |
277 | Docs: https://help.crypt.bot/crypto-pay-api#getChecks
278 |
279 | :param asset: Optional. Cryptocurrency alphabetic code. Supported assets: “USDT”, “TON”, “BTC”, “ETH”, “LTC”, “BNB”, “TRX” and “USDC” (and “JET” for testnet). Defaults to all currencies.
280 | :param check_ids: Optional. List of check IDs.
281 | :param status: Optional. Status of check to be returned. Available statuses: “active” and “activated”. Defaults to all statuses.
282 | :param offset: Optional. Offset needed to return a specific subset of check. Defaults to 0.
283 | :param count: Optional. Number of check to be returned. Values between 1-1000 are accepted. Defaults to 100.
284 | """
285 | url = f"{self.__base_url}/getChecks"
286 |
287 | if check_ids and type(check_ids) == list:
288 | check_ids = ",".join(map(str, check_ids))
289 |
290 | params = {
291 | "asset": asset,
292 | "check_ids": check_ids,
293 | "status": status,
294 | "offset": offset,
295 | "count": count,
296 | }
297 |
298 | self._delete_empty_fields(params)
299 |
300 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers,
301 | params=params)
302 |
303 | if len(response["result"]["items"]) > 0:
304 | if check_ids and isinstance(check_ids, int):
305 | return Check(**response["result"]["items"][0])
306 | return [Check(**check) for check in response["result"]["items"]]
307 |
308 | async def get_balance(self) -> List[Balance]:
309 | """Use this method to get balances of your app.
310 |
311 | Docs: https://help.crypt.bot/crypto-pay-api#getBalance"""
312 | url = f"{self.__base_url}/getBalance"
313 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers)
314 |
315 | return [Balance(**balance) for balance in response["result"]]
316 |
317 | async def get_exchange_rates(self) -> List[ExchangeRate]:
318 | """Use this method to get exchange rates of supported currencies.
319 |
320 | Docs: https://help.crypt.bot/crypto-pay-api#getExchangeRates"""
321 | url = f"{self.__base_url}/getExchangeRates"
322 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers)
323 |
324 | return [ExchangeRate(**rate) for rate in response["result"]]
325 |
326 | async def get_currencies(self) -> List[Currency]:
327 | """Use this method to get a list of supported currencies.
328 |
329 | Docs: https://help.crypt.bot/crypto-pay-api#getCurrencies"""
330 | url = f"{self.__base_url}/getCurrencies"
331 |
332 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers)
333 |
334 | return [Currency(**currency) for currency in response["result"]]
--------------------------------------------------------------------------------
/AsyncPayments/cryptoBot/models.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel
2 | from typing import List, Optional
3 |
4 |
5 | class MeInfo(BaseModel):
6 | app_id: int
7 | name: str
8 | payment_processing_bot_username: str
9 |
10 | class Invoice(BaseModel):
11 | invoice_id: int
12 | hash: str
13 | currency_type: str
14 | asset: Optional[str] = None
15 | fiat: Optional[str] = None
16 | amount: str
17 | paid_asset: Optional[str] = None
18 | paid_amount: Optional[str] = None
19 | paid_fiat_rate: Optional[str] = None
20 | accepted_assets: Optional[List[str]] = None
21 | fee_asset: Optional[str] = None
22 | fee_amount: Optional[float] = None
23 | fee: Optional[str] = None
24 | bot_invoice_url: str
25 | pay_url: str
26 | description: Optional[str] = None
27 | status: str
28 | created_at: str
29 | paid_usd_rate: Optional[str] = None
30 | usd_rate: Optional[str] = None
31 | allow_comments: bool
32 | allow_anonymous: bool
33 | expiration_date: Optional[str] = None
34 | paid_at: Optional[str] = None
35 | paid_anonymously: Optional[bool] = None
36 | comment: Optional[str] = None
37 | hidden_message: Optional[str] = None
38 | payload: Optional[str] = None
39 | paid_btn_name: Optional[str] = None
40 | paid_btn_url: Optional[str] = None
41 |
42 | class Check(BaseModel):
43 | check_id: int
44 | hash: str
45 | asset: str
46 | amount: float
47 | bot_check_url: str
48 | status: str
49 | created_at: str
50 | activated_at: str
51 |
52 | class Transfer(BaseModel):
53 | transfer_id: int
54 | user_id: int
55 | asset: str
56 | amount: float
57 | status: str
58 | completed_at: str
59 | comment: Optional[str] = None
60 |
61 | class Balance(BaseModel):
62 | currency_code: str
63 | available: float
64 | onhold: float
65 |
66 | class ExchangeRate(BaseModel):
67 | is_valid: bool
68 | is_crypto: bool
69 | is_fiat: bool
70 | source: str
71 | target: str
72 | rate: float
73 |
74 | class Currency(BaseModel):
75 | is_blockchain: bool
76 | is_stablecoin: bool
77 | is_fiat: bool
78 | name: str
79 | code: str
80 | url: Optional[str] = None
81 | decimals: int
82 |
--------------------------------------------------------------------------------
/AsyncPayments/cryptomus/__init__.py:
--------------------------------------------------------------------------------
1 | from .api import AsyncCryptomus
--------------------------------------------------------------------------------
/AsyncPayments/cryptomus/api.py:
--------------------------------------------------------------------------------
1 | from ..requests import RequestsClient
2 | from typing import Optional, List
3 | from .models import Balance, Balances, CreatePayment, GenerateStaticWallet, GenerateQrCode, BlockStaticWallet, RefundPaymentsOnBlockedAddress, \
4 | PaymentInfo, ListOfServices, PaymentHistory, Payout, PayoutHistory, ListOfServicesPayout, TransferWallet, RecurringPayment, \
5 | ListOfRecurringPayments, ExchangeRatesList, Discount
6 | import base64
7 | import json
8 | import hashlib
9 |
10 |
11 | class AsyncCryptomus(RequestsClient):
12 | API_HOST: str = "https://cryptomus.com/gateway"
13 |
14 | def __init__(self, payment_api_key: str, merchant_id: str, payout_api_key: str) -> None:
15 | """
16 | Initialize Cryptomus API client
17 | :param payment_api_key: Your payment API key
18 | :param merchant_id: Your merchant ID
19 | :param payout_api_key: Your payout API key
20 | """
21 | super().__init__()
22 | self.__payment_api_key = payment_api_key
23 | self.__merchant_id = merchant_id
24 | self.__payout_api_key = payout_api_key
25 | self.__headers = {
26 | "Content-Type": "application/json",
27 | "merchant": self.__merchant_id,
28 | }
29 | self.__base_url = "https://api.cryptomus.com/v1"
30 | self.__post_method = "POST"
31 | self.__get_method = "GET"
32 | self.__payment_name = "cryptomus"
33 | self.check_values()
34 |
35 | def check_values(self):
36 | if not self.__merchant_id or not self.__payment_api_key or not self.__payout_api_key:
37 | raise ValueError('No Payment API key, merchant ID or Payout API key specified')
38 |
39 | def __generate_sign(self, data: Optional[dict] = None, is_for_payouts: Optional[bool] = False) -> dict:
40 | if data:
41 | data_encoded = base64.b64encode(json.dumps(data).encode()).decode()
42 | else:
43 | data_encoded = ""
44 |
45 | if is_for_payouts:
46 | return hashlib.md5((data_encoded + self.__payout_api_key).encode()).hexdigest()
47 | return hashlib.md5((data_encoded + self.__payment_api_key).encode()).hexdigest()
48 |
49 | async def get_balance(self) -> Balances:
50 | """Get list of your balances.
51 |
52 | Docs: https://doc.cryptomus.com/ru/business/balance"""
53 |
54 | self.__headers["sign"] = self.__generate_sign()
55 | response = await self._request(self.__payment_name, self.__post_method, f'{self.__base_url}/balance', headers=self.__headers)
56 |
57 | return Balances(merchant=[Balance(**balance) for balance in response['result'][0]['balance']['merchant']],
58 | user=[Balance(**balance) for balance in response['result'][0]['balance']['user']])
59 |
60 | async def create_payment(self, amount: str, currency: str, order_id: str, network: Optional[str] = None, url_return: Optional[str] = None,
61 | url_success: Optional[str] = None, url_callback: Optional[str] = None, is_payment_multiple: Optional[bool] = True,
62 | lifetime: Optional[int] = 3600, to_currency: Optional[str] = None, subtract: Optional[int] = 0,
63 | accuracy_payment_percent: Optional[int] = 0, additional_data: Optional[str] = None, currencies: Optional[list] = None,
64 | except_currencies: Optional[list] = None, course_source: Optional[str] = None, from_referral_code: Optional[str] = None,
65 | discount_percent: Optional[int] = None, is_refresh: Optional[bool] = False) -> CreatePayment:
66 |
67 | """Create payment.
68 |
69 | :param amount: Amount to be paid. If there are pennies in the amount, then send them with a separator '.'. Example: 10.28
70 | :param currency: Currency code.
71 | :param order_id: Order ID in your system. The parameter should be a string consisting of alphabetic characters, numbers, underscores, and dashes. It should not contain any spaces or special characters. The order_id must be unique within the merchant invoices/static wallets/recurrence payments. When we find an existing invoice with order_id, we return its details, a new invoice will not be created.
72 | :param network: Blockchain network code.
73 | :param url_return: Before paying, the user can click on the button on the payment form and return to the store page at this URL.
74 | :param url_success: After successful payment, the user can click on the button on the payment form and return to this URL.
75 | :param url_callback: Url to which webhooks with payment status will be sent.
76 | :param is_payment_multiple: Whether the user is allowed to pay the remaining amount. This is useful when the user has not paid the entire amount of the invoice for one transaction, and you want to allow him to pay up to the full amount. If you disable this feature, the invoice will finalize after receiving the first payment and you will receive funds to your balance.
77 | :param lifetime: Min: 300. Max: 43200. The lifespan of the issued invoice (in seconds).
78 | :param to_currency: The parameter is used to specify the target currency for converting the invoice amount. When creating an invoice, you provide an amount and currency, and the API will convert that amount to the equivalent value in the to_currency. For example, to create an invoice for 20 USD in bitcoin: amount: 20, currency: USD, to_currency: BTC. The API will convert 20 USD amount to its equivalent in BTC based on the current exchange rate and the user will pay in BTC. The to_currency should always be the cryptocurrency code, not a fiat currency code.
79 | :param subtract: Min: 0. Max: 100. Percentage of the payment commission charged to the client. If you have a rate of 1%, then if you create an invoice for 100 USDT with subtract = 100 (the client pays 100% commission), the client will have to pay 101 USDT.
80 | :param accuracy_payment_percent: Min: 0. Max: 5. Acceptable inaccuracy in payment. For example, if you pass the value 5, the invoice will be marked as Paid even if the client has paid only 95% of the amount. The actual payment amount will be credited to the balance.
81 | :param additional_data: Max: 255. Additional information for you (not shown to the client).
82 | :param currencies: List of allowed currencies for payment. This is useful if you want to limit the list of coins that your customers can use to pay invoices.
83 | :param except_currencies: List of excluded currencies for payment.
84 | :param course_source: Min: 4. Max: 20. The service from which the exchange rates are taken for conversion in the invoice.
85 | :param from_referral_code: The merchant who makes the request connects to a referrer by code. For example, you are an application that generates invoices via the Cryptomus API and your customers are other stores. They enter their api key and merchant id in your application, and you send requests with their credentials and passing your referral code. Thus, your clients become referrals on your Cryptomus account and you will receive income from their turnover.
86 | :param discount_percent: Min: -99. Max: 100. Positive numbers: Allows you to set a discount. To set a 5% discount for the payment, you should pass a value: 5. Negative numbers: Allows you to set custom additional commission. To set an additional commission of 10% for the payment, you should pass a value: -10. The discount percentage when creating an invoice is taken into account only if the invoice has a specific cryptocurrency.
87 | :param is_refresh: Using this parameter, you can update the lifetime and get a new address for the invoice if the lifetime has expired. To do that, you need to pass all required parameters, and the invoice with passed order_id will be refreshed. Only address, payment_status and expired_at are changed. No other fields are changed, regardless of the parameters passed.
88 |
89 | Docs: https://doc.cryptomus.com/business/payments/creating-invoice
90 | """
91 |
92 | url = f"{self.__base_url}/payment"
93 | params = {
94 | "amount": amount,
95 | "currency": currency,
96 | "order_id": order_id,
97 | "network": network,
98 | "url_return": url_return,
99 | "url_success": url_success,
100 | "url_callback": url_callback,
101 | "is_payment_multiple": is_payment_multiple,
102 | "lifetime": lifetime,
103 | "to_currency": to_currency,
104 | "subtract": subtract,
105 | "accuracy_payment_percent": accuracy_payment_percent,
106 | "additional_data": additional_data,
107 | "currencies": currencies,
108 | "except_currencies": except_currencies,
109 | "course_source": course_source,
110 | "from_referral_code": from_referral_code,
111 | "discount_percent": discount_percent,
112 | "is_refresh": is_refresh,
113 | }
114 | self._delete_empty_fields(params)
115 | self.__headers["sign"] = self.__generate_sign(params)
116 |
117 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, json=params)
118 |
119 | return CreatePayment(**response['result'])
120 |
121 | async def payment_info(self, uuid: Optional[str] = None, order_id: Optional[str] = None) -> PaymentInfo:
122 | """Payment information.
123 |
124 | :param uuid: Invoice uuid.
125 | :param order_id: Invoice order ID.
126 |
127 | Docs: https://doc.cryptomus.com/business/payments/payment-information
128 | """
129 | url = f"{self.__base_url}/payment/info"
130 | params = {
131 | "uuid": uuid,
132 | "order_id": order_id,
133 | }
134 | self._delete_empty_fields(params)
135 | self.__headers["sign"] = self.__generate_sign(params)
136 |
137 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, json=params)
138 |
139 | return PaymentInfo(**response['result'])
140 |
141 | async def generate_static_wallet(self, currency: str, network: str, order_id: str, url_callback: Optional[str] = None,
142 | from_referral_code: Optional[str] = None) -> GenerateStaticWallet:
143 | """Creating a Static wallet.
144 |
145 | :param currency: Currency code.
146 | :param network: Blockchain network code.
147 | :param order_id: Order ID in your system. The parameter should be a string consisting of alphabetic characters, numbers, underscores, and dashes. It should not contain any spaces or special characters. The order_id must be unique within the merchant invoices/static wallets/recurrence payments. When we find an existing invoice with order_id, we return its details, a new invoice will not be created.
148 | :param url_callback: URL, to which the webhook will be sent after each top-up of the wallet
149 | :param from_referral_code: The merchant who makes the request connects to a referrer by code.
150 |
151 |
152 | Docs: https://doc.cryptomus.com/business/payments/creating-static
153 | """
154 | url = f"{self.__base_url}/wallet"
155 | params = {
156 | "currency": currency,
157 | "network": network,
158 | "order_id": order_id,
159 | "url_callback": url_callback,
160 | "from_referral_code": from_referral_code,
161 | }
162 | self._delete_empty_fields(params)
163 | self.__headers["sign"] = self.__generate_sign(params)
164 |
165 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, json=params)
166 |
167 | return GenerateStaticWallet(**response['result'])
168 |
169 | async def generate_qr_code_for_wallet(self, wallet_address_uuid: str) -> GenerateQrCode:
170 | """Generate a QR-code for the static wallet address.
171 |
172 | :param wallet_address_uuid: Uuid of a static wallet.
173 |
174 | Docs: https://doc.cryptomus.com/business/payments/qr-code-pay-form
175 | """
176 | url = f"{self.__base_url}/wallet/qr"
177 | params = {
178 | "wallet_address_uuid": wallet_address_uuid,
179 | }
180 | self.__headers["sign"] = self.__generate_sign(params)
181 |
182 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, json=params)
183 |
184 | return GenerateQrCode(**response['result'])
185 |
186 | async def generate_qr_code_for_invoice(self, merchant_payment_uuid: str) -> GenerateQrCode:
187 | """Generate a QR-code for the invoice address.
188 |
189 | :param merchant_payment_uuid: Invoice uuid.
190 |
191 | Docs: https://doc.cryptomus.com/business/payments/qr-code-pay-form
192 | """
193 | url = f"{self.__base_url}/payment/qr"
194 | params = {
195 | "merchant_payment_uuid": merchant_payment_uuid,
196 | }
197 | self.__headers["sign"] = self.__generate_sign(params)
198 |
199 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, json=params)
200 |
201 | return GenerateQrCode(**response['result'])
202 |
203 | async def block_static_wallet(self, uuid: Optional[str] = None, order_id: Optional[str] = None, is_force_refund: Optional[bool] = False) -> BlockStaticWallet:
204 | """Block static wallet.
205 |
206 | :param uuid: Uuid of a static wallet.
207 | :param order_id: Order ID of a static wallet.
208 | :param is_force_refund: Refund all incoming payments to sender’s address.
209 |
210 | Docs: https://doc.cryptomus.com/business/payments/block-wallet
211 | """
212 | url = f"{self.__base_url}/wallet/block-address"
213 | params = {
214 | "uuid": uuid,
215 | "order_id": order_id,
216 | "is_force_refund": is_force_refund,
217 | }
218 | self._delete_empty_fields(params)
219 | self.__headers["sign"] = self.__generate_sign(params)
220 |
221 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, json=params)
222 |
223 | return BlockStaticWallet(**response['result'])
224 |
225 | async def refund_payments_on_blocked_address(self, address: str, uuid: Optional[str] = None, order_id: Optional[str] = None) -> RefundPaymentsOnBlockedAddress:
226 | """Refund payments on blocked address.
227 |
228 | :param address: Uuid of a static wallet.
229 | :param uuid: Order ID of a static wallet.
230 | :param order_id: Refund all blocked funds to this address.
231 |
232 | Docs: https://doc.cryptomus.com/business/payments/refundblocked
233 | """
234 | url = f"{self.__base_url}/blocked-address-refund"
235 | params = {
236 | "address": address,
237 | "uuid": uuid,
238 | "order_id": order_id,
239 | }
240 | self._delete_empty_fields(params)
241 | self.__headers["sign"] = self.__generate_sign(params)
242 |
243 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, json=params)
244 |
245 | return RefundPaymentsOnBlockedAddress(**response['result'])
246 |
247 | async def refund(self, address: str, is_subtract: bool, uuid: Optional[str] = None, order_id: Optional[str] = None) -> bool:
248 | """Refund.
249 |
250 | :param address: The address to which the refund should be made.
251 | :param is_subtract: Whether to take a commission from the merchant's balance or from the refund amount. True - take the commission from merchant balance. False - reduce the refundable amount by the commission amount.
252 | :param uuid: Invoice uuid.
253 | :param order_id: Invoice order ID.
254 |
255 | Docs: https://doc.cryptomus.com/business/payments/refund
256 | """
257 | url = f"{self.__base_url}/payment/refund"
258 | params = {
259 | "address": address,
260 | "is_subtract": is_subtract,
261 | "uuid": uuid,
262 | "order_id": order_id,
263 | }
264 | self._delete_empty_fields(params)
265 | self.__headers["sign"] = self.__generate_sign(params)
266 |
267 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, json=params)
268 |
269 | return True if response['state'] == 0 else False
270 |
271 | async def resend_webhook(self, uuid: Optional[str] = None, order_id: Optional[str] = None) -> bool:
272 | """Resend webhook.
273 |
274 | :param uuid: Invoice uuid.
275 | :param order_id: Invoice order ID.
276 |
277 | Docs: https://doc.cryptomus.com/business/payments/resend-webhook
278 | """
279 | url = f"{self.__base_url}/payment/resend"
280 | params = {
281 | "uuid": uuid,
282 | "order_id": order_id,
283 | }
284 | self._delete_empty_fields(params)
285 | self.__headers["sign"] = self.__generate_sign(params)
286 |
287 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, json=params)
288 |
289 | return True if response['state'] == 0 else False
290 |
291 | async def test_webhook_payment(self, url_callback: str, currency: str, network: str, status: str, uuid: Optional[str] = None,
292 | order_id: Optional[str] = None) -> bool:
293 | """Testing payment webhook.
294 |
295 | :param url_callback: Url to which webhooks with payment status will be sent.
296 | :param currency: Invoice currency code.
297 | :param network: Invoice network code.
298 | :param status: Payment status.
299 | :param uuid: uuid of the invoice.
300 | :param order_id: Order ID of the invoice.
301 |
302 | Docs: https://doc.cryptomus.com/business/payments/testing-webhook
303 | """
304 | url = f"{self.__base_url}/test-webhook/payment"
305 | params = {
306 | "url_callback": url_callback,
307 | "currency": currency,
308 | "network": network,
309 | "status": status,
310 | "uuid": uuid,
311 | "order_id": order_id,
312 | }
313 | self._delete_empty_fields(params)
314 | self.__headers["sign"] = self.__generate_sign(params)
315 |
316 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, json=params)
317 |
318 | return True if response['state'] == 0 else False
319 |
320 | async def test_webhook_wallet(self, url_callback: str, currency: str, network: str, status: str, uuid: Optional[str] = None,
321 | order_id: Optional[str] = None) -> bool:
322 | """Testing wallet webhook.
323 |
324 | :param url_callback: Url to which webhooks with payment status will be sent.
325 | :param currency: Invoice currency code.
326 | :param network: Invoice network code.
327 | :param status: Payment status.
328 | :param uuid: uuid of the invoice.
329 | :param order_id: Order ID of the invoice.
330 |
331 | Docs: https://doc.cryptomus.com/business/payments/testing-webhook
332 | """
333 | url = f"{self.__base_url}/test-webhook/wallet"
334 | params = {
335 | "url_callback": url_callback,
336 | "currency": currency,
337 | "network": network,
338 | "status": status,
339 | "uuid": uuid,
340 | "order_id": order_id,
341 | }
342 | self._delete_empty_fields(params)
343 | self.__headers["sign"] = self.__generate_sign(params)
344 |
345 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, json=params)
346 |
347 | return True if response['state'] == 0 else False
348 |
349 | async def test_webhook_payout(self, url_callback: str, currency: str, network: str, status: str, uuid: Optional[str] = None,
350 | order_id: Optional[str] = None) -> bool:
351 | """Testing payout webhook.
352 |
353 | :param url_callback: Url to which webhooks with payment status will be sent.
354 | :param currency: Payout currency code.
355 | :param network: Payout network code.
356 | :param status: Payout status.
357 | :param uuid: uuid of the Payout.
358 | :param order_id: Order ID of the Payout.
359 |
360 | Docs: https://doc.cryptomus.com/business/payments/testing-webhook
361 | """
362 | url = f"{self.__base_url}/test-webhook/payout"
363 | params = {
364 | "url_callback": url_callback,
365 | "currency": currency,
366 | "network": network,
367 | "status": status,
368 | "uuid": uuid,
369 | "order_id": order_id,
370 | }
371 | self._delete_empty_fields(params)
372 | self.__headers["sign"] = self.__generate_sign(params)
373 |
374 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, json=params)
375 |
376 | return True if response['state'] == 0 else False
377 |
378 | async def list_of_services(self) -> List[ListOfServices]:
379 | """List of services.
380 |
381 | Docs: https://doc.cryptomus.com/business/payments/list-of-services
382 | """
383 | url = f"{self.__base_url}/payment/services"
384 | self.__headers["sign"] = self.__generate_sign()
385 |
386 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers)
387 |
388 | return [ListOfServices(**service) for service in response["result"]]
389 |
390 | async def payment_history(self, date_from: Optional[str] = None, date_to: Optional[str] = None, cursor: Optional[str] = None) -> PaymentHistory:
391 | """Payment history.
392 |
393 | :param date_from: Filtering by creation date, from. Format: YYYY-MM-DD H:mm:ss
394 | :param date_to: Filtering by creation date, to. Format: YYYY-MM-DD H:mm:ss
395 | :param cursor: Cursor to page.
396 |
397 | Docs: https://doc.cryptomus.com/business/payments/payment-history
398 | """
399 | url = f"{self.__base_url}/payment/list"
400 | if cursor:
401 | url += f"?cursor={cursor}"
402 | params = {
403 | "date_from": date_from,
404 | "date_to": date_to,
405 | }
406 | self._delete_empty_fields(params)
407 | self.__headers["sign"] = self.__generate_sign(params)
408 |
409 | response = await self._request(self.__payment_name, self.__post_method, url, json=params, headers=self.__headers)
410 |
411 | return PaymentHistory(**response['result'])
412 |
413 | async def create_payout(self, amount: str, currency: str, order_id: str, address: str, is_subtract: bool, network: str,
414 | url_callback: Optional[str] = None, to_currency: Optional[str] = None,
415 | course_source: Optional[str] = None, from_currency: Optional[str] = None,
416 | priority: Optional[str] = None, memo: Optional[str] = None) -> Payout:
417 | """Creating a payout.
418 |
419 | :param amount: Payout amount.
420 | :param currency: Currency code for the payout. If Currency is fiat, the to_currency parameter is required.
421 | :param order_id: Order ID in your system. The parameter should be a string consisting of alphabetic characters, numbers, underscores, and dashes. It should not contain any spaces or special characters. The order_id must be unique within the merchant payouts. When we find an existing payout with order_id, we return its details, a new payout will not be created.
422 | :param address: The address of the wallet to which the withdrawal will be made.
423 | :param is_subtract: Defines where the withdrawal fee will be deducted. True - from your balance. False - from payout amount, the payout amount will be decreased.
424 | :param network: Blockchain network code. Not required when the currency/to_currency parameters is a cryptocurrency and has only one network, for example BTC.
425 | :param url_callback: URL to which webhooks with payout status will be sent.
426 | :param to_currency: Cryptocurrency code in which the payout will be made. It is used when the currency parameter is fiat.
427 | :param course_source: The service from which the exchange rates are taken for conversion in the invoice. The parameter is applied only if the currency is fiat, otherwise the default value is taken from the merchant's settings. Available values: Binance, BinanceP2p, Exmo, Kucoin, Garantexio.
428 | :param from_currency: Allows to automatically convert the withdrawal amount and use the from_currency balance. Only USDT is available.
429 | :param priority: The parameter for selecting the withdrawal priority. The cost of the withdrawal fee depends on the selected parameter. This parameter is applied only in case of using the BTC, ETH, POLYGON, and BSC networks. Available values: recommended, economy, high, highest.
430 | :param memo: Additional identifier for TON, used to specify a particular recipient or target.
431 |
432 | Docs: https://doc.cryptomus.com/business/payouts/creating-payout
433 | """
434 | url = f"{self.__base_url}/payout"
435 | params = {
436 | "amount": amount,
437 | "currency": currency,
438 | "order_id": order_id,
439 | "address": address,
440 | "is_subtract": is_subtract,
441 | "network": network,
442 | "url_callback": url_callback,
443 | "to_currency": to_currency,
444 | "course_source": course_source,
445 | "from_currency": from_currency,
446 | "priority": priority,
447 | "memo": memo,
448 | }
449 | self._delete_empty_fields(params)
450 | self.__headers["sign"] = self.__generate_sign(params, True)
451 |
452 | response = await self._request(self.__payment_name, self.__post_method, url, json=params, headers=self.__headers)
453 |
454 | return Payout(**response['result'])
455 |
456 | async def payout_info(self, uuid: Optional[str] = None, order_id: Optional[str] = None) -> Payout:
457 | """Payout information.
458 |
459 | :param uuid: Payout uuid.
460 | :param order_id: Payout order ID.
461 |
462 | Docs: https://doc.cryptomus.com/business/payouts/payout-information
463 | """
464 | url = f"{self.__base_url}/payout/info"
465 | params = {
466 | "uuid": uuid,
467 | "order_id": order_id,
468 | }
469 | self._delete_empty_fields(params)
470 | self.__headers["sign"] = self.__generate_sign(params, True)
471 |
472 | response = await self._request(self.__payment_name, self.__post_method, url, json=params, headers=self.__headers)
473 |
474 | return Payout(**response['result'])
475 |
476 | async def payout_history(self, date_from: Optional[str] = None, date_to: Optional[str] = None, cursor: Optional[str] = None) -> PayoutHistory:
477 | """Payout history.
478 |
479 | :param date_from: Filtering by creation date, from. Format: YYYY-MM-DD H:mm:ss.
480 | :param date_to: Filtering by creation date, to. Format: YYYY-MM-DD H:mm:ss.
481 | :param cursor: Cursor to page.
482 |
483 | Docs: https://doc.cryptomus.com/business/payouts/payout-history
484 | """
485 | url = f"{self.__base_url}/payout/list"
486 | if cursor:
487 | url += f"?cursor={cursor}"
488 | params = {
489 | "date_from": date_from,
490 | "date_to": date_to,
491 | }
492 | self._delete_empty_fields(params)
493 | self.__headers["sign"] = self.__generate_sign(params, True)
494 |
495 | response = await self._request(self.__payment_name, self.__post_method, url, json=params, headers=self.__headers)
496 |
497 | return PayoutHistory(**response['result'])
498 |
499 | async def list_of_services_payout(self) -> List[ListOfServicesPayout]:
500 | """List of services.
501 |
502 | Docs: https://doc.cryptomus.com/business/payouts/list-of-services
503 | """
504 | url = f"{self.__base_url}/payout/services"
505 | self.__headers["sign"] = self.__generate_sign(dict(), True)
506 |
507 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers)
508 |
509 | return [ListOfServicesPayout(**service) for service in response["result"]]
510 |
511 | async def transfer_to_personal_wallet(self, amount: str, currency: str) -> TransferWallet:
512 | """Transfer to personal wallet.
513 |
514 | :param amount: Amount to transfer.
515 | :param currency: Currency code. Only cryptocurrency code is allowed..
516 |
517 | Docs: https://doc.cryptomus.com/business/payouts/transfer-to-personal
518 | """
519 | url = f"{self.__base_url}/transfer/to-personal"
520 | params = {
521 | "amount": amount,
522 | "currency": currency,
523 | }
524 | self.__headers["sign"] = self.__generate_sign(params, True)
525 |
526 | response = await self._request(self.__payment_name, self.__post_method, url, json=params, headers=self.__headers)
527 |
528 | return TransferWallet(**response['result'])
529 |
530 |
531 |
532 | async def transfer_to_business_wallet(self, amount: str, currency: str) -> TransferWallet:
533 | """Transfer to business wallet.
534 |
535 | :param amount: Amount to transfer.
536 | :param currency: Currency code. Only cryptocurrency code is allowed..
537 |
538 | Docs: https://doc.cryptomus.com/business/payouts/transfer-to-personal
539 | """
540 | url = f"{self.__base_url}/transfer/to-business"
541 | params = {
542 | "amount": amount,
543 | "currency": currency,
544 | }
545 | self.__headers["sign"] = self.__generate_sign(params, True)
546 |
547 | response = await self._request(self.__payment_name, self.__post_method, url, json=params, headers=self.__headers)
548 |
549 | return TransferWallet(**response['result'])
550 |
551 | async def creating_recurring_payment(self, amount: str, currency: str, name: str, period: str, to_currency: Optional[str] = None,
552 | order_id: Optional[str] = None, url_callback: Optional[str] = None, discount_days: Optional[str] = None,
553 | discount_amount: Optional[str] = None, additional_data: Optional[str] = None) -> RecurringPayment:
554 | """Creating recurring payment.
555 |
556 | :param amount: Recurring payment amount.
557 | :param currency: Currency code.
558 | :param name: Recurring payment name.
559 | :param period: Recurring payment period. Available: weekly, monthly, three_month.
560 | :param to_currency: Currency code for accepting payments. The parameter is used to specify the target currency for converting the recurrent payment amount. For example, to create an recurrent payment for 20 USD in bitcoin: amount: 20, currency: USD, to_currency: BTC. The API will convert 20 USD amount to its equivalent in BTC based on the current exchange rate and the user will pay in BTC. The to_currency should always be the cryptocurrency code, not a fiat currency code.
561 | :param order_id: Order ID in your system.
562 | :param url_callback: Url to which webhooks with payment status will be sent.
563 | :param discount_days: Discount period days (required with 'discount_amount').
564 | :param discount_amount: Discount amount (required with 'discount_days').Here the amount in the currency of the parameter ‘currency’.
565 | :param additional_data: Additional recurring payment details.
566 |
567 | Docs: https://doc.cryptomus.com/business/recurring/creating
568 | """
569 | url = f"{self.__base_url}/recurrence/create"
570 | params = {
571 | "amount": amount,
572 | "currency": currency,
573 | "name": name,
574 | "period": period,
575 | "to_currency": to_currency,
576 | "order_id": order_id,
577 | "url_callback": url_callback,
578 | "discount_days": discount_days,
579 | "discount_amount": discount_amount,
580 | "additional_data": additional_data,
581 | }
582 | self._delete_empty_fields(params)
583 | self.__headers["sign"] = self.__generate_sign(params)
584 |
585 | response = await self._request(self.__payment_name, self.__post_method, url, json=params, headers=self.__headers)
586 |
587 | return RecurringPayment(**response['result'])
588 |
589 | async def recurring_payment_info(self, uuid: Optional[str] = None, order_id: Optional[str] = None) -> RecurringPayment:
590 | """Payment information.
591 |
592 | :param uuid: Recurrence uuid.
593 | :param order_id: Recurrence order ID.
594 |
595 | Docs: https://doc.cryptomus.com/business/recurring/info"""
596 | url = f"{self.__base_url}/recurrence/info"
597 | params = {
598 | "uuid": uuid,
599 | "order_id": order_id,
600 | }
601 | self._delete_empty_fields(params)
602 | self.__headers["sign"] = self.__generate_sign(params)
603 |
604 | response = await self._request(self.__payment_name, self.__post_method, url, json=params, headers=self.__headers)
605 |
606 | return RecurringPayment(**response['result'])
607 |
608 | async def list_of_recurring_payments(self, cursor: Optional[str] = None) -> ListOfRecurringPayments:
609 | """List of recurring payments.
610 |
611 | Docs: https://doc.cryptomus.com/business/recurring/list
612 | """
613 | url = f"{self.__base_url}/recurrence/list"
614 | if cursor:
615 | url += f"?cursor={cursor}"
616 | self.__headers["sign"] = self.__generate_sign()
617 |
618 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers)
619 |
620 | return ListOfRecurringPayments(**response['result'])
621 |
622 | async def cancel_recurring_payment(self, uuid: Optional[str] = None, order_id: Optional[str] = None) -> RecurringPayment:
623 | """Cancel recurring payment
624 |
625 | :param uuid: Recurrence uuid.
626 | :param order_id: Order ID in your system.
627 |
628 | Docs: https://doc.cryptomus.com/business/recurring/cancel
629 | """
630 | url = f"{self.__base_url}/recurrence/cancel"
631 | params = {
632 | "uuid": uuid,
633 | "order_id": order_id,
634 | }
635 | self.__headers["sign"] = self.__generate_sign(params)
636 |
637 | response = await self._request(self.__payment_name, self.__post_method, url, json=params, headers=self.__headers)
638 |
639 | return RecurringPayment(**response['result'])
640 |
641 | async def exchange_rates_list(self, currency: str) -> List[ExchangeRatesList]:
642 | """Exchange rates list.
643 |
644 | Docs: https://doc.cryptomus.com/business/exchange-rates/list
645 | """
646 | url = f"{self.__base_url}/exchange-rate/{currency}/list"
647 | self.__headers["sign"] = self.__generate_sign()
648 |
649 | response = await self._request(self.__payment_name, self.__get_method, url, headers=self.__headers)
650 |
651 | return [ExchangeRatesList(**rate) for rate in response["result"]]
652 |
653 | async def list_of_discounts(self) -> List[Discount]:
654 | """List of discounts.
655 |
656 | Docs: https://doc.cryptomus.com/business/discount/list
657 | """
658 | url = f"{self.__base_url}/payment/discount/list"
659 | self.__headers["sign"] = self.__generate_sign()
660 |
661 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers)
662 |
663 | return [Discount(**discount) for discount in response["result"]]
664 |
665 | async def set_discount_to_payment_method(self, currency: str, network: str, discount_percent: int) -> Discount:
666 | """Set discount to payment method.
667 |
668 | :param currency: Currency code.
669 | :param network: Blockchain network code.
670 | :param discount_percent: Discount percent.
671 |
672 | Docs: https://doc.cryptomus.com/business/discount/set
673 | """
674 | url = f"{self.__base_url}/payment/discount/set"
675 | params = {
676 | "currency": currency,
677 | "network": network,
678 | "discount_percent": discount_percent,
679 | }
680 | self.__headers["sign"] = self.__generate_sign(params)
681 |
682 | response = await self._request(self.__payment_name, self.__post_method, url, json=params, headers=self.__headers)
683 |
684 | return Discount(**response["result"])
--------------------------------------------------------------------------------
/AsyncPayments/cryptomus/models.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel, Field
2 | from typing import Optional, Union, List
3 |
4 |
5 | class Balances(BaseModel):
6 | merchant: list
7 | user: list
8 |
9 |
10 | class Balance(BaseModel):
11 | uuid: str
12 | balance: str
13 | currency_code: str
14 | balance_usd: str
15 |
16 |
17 | class CreatePayment(BaseModel):
18 | uuid: str
19 | order_id: str
20 | amount: str
21 | payment_amount: Optional[Union[str, int]] = None
22 | payment_amount_usd: Optional[Union[str, int]] = None
23 | payer_amount: Optional[Union[str, int]] = None
24 | payer_amount_exchange_rate: Optional[Union[str, int]] = None
25 | discount_percent: Optional[Union[str, int]] = None
26 | discount: str
27 | payer_currency: Optional[Union[str, int]] = None
28 | currency: str
29 | comments: Optional[Union[str, dict, list]] = None
30 | merchant_amount: Optional[Union[str, int]] = None
31 | network: Optional[str] = None
32 | address: Optional[str] = None
33 | from_: Optional[str] = Field(alias="from", default=None)
34 | txid: Optional[str] = None
35 | payment_status: str
36 | url: str
37 | expired_at: int
38 | status: str
39 | is_final: bool
40 | aditional_data: Optional[str] = None
41 | created_at: str
42 | updated_at: str
43 | commission: Optional[Union[str, int]] = None
44 | address_qr_code: Optional[str] = None
45 | mercuryo_payment_link: Optional[str] = None
46 |
47 |
48 | class GenerateStaticWallet(BaseModel):
49 | wallet_uuid: str
50 | uuid: str
51 | address: str
52 | network: str
53 | currency: str
54 | url: str
55 |
56 |
57 | class GenerateQrCode(BaseModel):
58 | image: str
59 |
60 |
61 | class BlockStaticWallet(BaseModel):
62 | uuid: str
63 | status: str
64 |
65 |
66 | class RefundPaymentsOnBlockedAddress(BaseModel):
67 | commission: str
68 | amount: str
69 |
70 |
71 | class PaymentInfo(BaseModel):
72 | uuid: str
73 | order_id: str
74 | amount: str
75 | payment_amount: Optional[str] = None
76 | payer_amount: Optional[str] = None
77 | discount_percent: Optional[Union[int, float, str]] = None
78 | discount: str
79 | payer_currency: Optional[str] = None
80 | currency: str
81 | merchant_amount: Optional[str] = None
82 | network: Optional[str] = None
83 | address: Optional[str] = None
84 | from_: Optional[str] = Field(alias="from", default=None)
85 | txid: Optional[str] = None
86 | payment_status: str
87 | url: str
88 | expired_at: int
89 | status: str
90 | is_final: bool
91 | additional_data: Optional[str] = None
92 | created_at: str
93 | updated_at: str
94 |
95 |
96 | class ServiceInfo:
97 | class ServiceLimit(BaseModel):
98 | min_amount: str
99 | max_amount: str
100 |
101 |
102 | class ServiceCommission(BaseModel):
103 | fee_amount: str
104 | percent: str
105 |
106 |
107 | class ListOfServices(BaseModel):
108 | network: str
109 | currency: str
110 | is_available: bool
111 | limit: ServiceInfo.ServiceLimit
112 | commission: ServiceInfo.ServiceCommission
113 |
114 |
115 | class HistoryPaginate(BaseModel):
116 | count: int
117 | hasPages: bool
118 | nextCursor: Optional[str] = None
119 | previousCursor: Optional[str] = None
120 | perPage: int
121 |
122 |
123 | class PaymentHistory(BaseModel):
124 | items: List[PaymentInfo]
125 | paginate: HistoryPaginate
126 |
127 |
128 | class PayoutHistoryItem(BaseModel):
129 | uuid: str
130 | amount: str
131 | currency: str
132 | network: str
133 | address: str
134 | txid: Optional[str] = None
135 | status: str
136 | is_final: bool
137 | balance: Union[str, int]
138 | created_at: str
139 | updated_at: str
140 |
141 |
142 | class PayoutHistory(BaseModel):
143 | merchant_uuid: Optional[str] = None
144 | items: List[PayoutHistoryItem]
145 | paginate: HistoryPaginate
146 |
147 |
148 | class Payout(BaseModel):
149 | uuid: str
150 | amount: str
151 | currency: str
152 | network: str
153 | address: str
154 | txid: Optional[str] = None
155 | status: str
156 | is_final: bool
157 | balance: Union[str, int]
158 | payer_currency: str
159 | payer_amount: Union[str, int]
160 |
161 |
162 | class ListOfServicesPayout(BaseModel):
163 | network: str
164 | currency: str
165 | is_available: bool
166 | limit: ServiceInfo.ServiceLimit
167 | commission: ServiceInfo.ServiceCommission
168 |
169 |
170 | class TransferWallet(BaseModel):
171 | user_wallet_transaction_uuid: str
172 | user_wallet_balance: str
173 | merchant_transaction_uuid: str
174 | merchant_balance: str
175 |
176 |
177 | class RecurringPayment(BaseModel):
178 | uuid: str
179 | name: str
180 | order_id: Optional[str] = None
181 | amount: str
182 | currency: str
183 | payer_currency: str
184 | payer_amount_usd: str
185 | payer_amount: str
186 | url_callback: Optional[str] = None
187 | period: str
188 | status: str
189 | url: str
190 | last_pay_off: Optional[str] = None
191 | additional_data: Optional[str] = None
192 |
193 |
194 | class ListOfRecurringPayments(BaseModel):
195 | merchant_uuid: Optional[str] = None
196 | items: List[RecurringPayment]
197 | paginate: HistoryPaginate
198 |
199 |
200 | class ExchangeRatesList(BaseModel):
201 | from_: Optional[str] = Field(alias="from", default=None)
202 | to: str
203 | course: str
204 |
205 |
206 | class Discount(BaseModel):
207 | currency: str
208 | network: str
209 | discount: Union[str, int, float]
210 |
211 |
212 | class CurrenciesNames:
213 | USDC: str = "USDC"
214 | ETH: str = "ETH"
215 | USDT: str = "USDT"
216 | AVAX: str = "AVAX"
217 | BCH: str = "BCH"
218 | BNB: str = "BNB"
219 | CGPT: str = "CGPT"
220 | DAI: str = "DAI"
221 | BTC: str = "BTC"
222 | DASH: str = "DASH"
223 | DOGE: str = "DOGE"
224 | SHIB: str = "SHIB"
225 | MATIC: str = "MATIC"
226 | VERSE: str = "VERSE"
227 | LTC: str = "LTC"
228 | CRMS: str = "CRMS"
229 | SOL: str = "SOL"
230 | TON: str = "TON"
231 | HMSTR: str = "HMSTR"
232 | TRX: str = "TRX"
233 | XMR: str = "XMR"
234 |
235 |
236 | class NetworkNames:
237 | ARBITRUM: str = "ARBITRUM"
238 | AVALANCHE: str = "AVALANCHE"
239 | BCH: str = "BCH"
240 | BSC: str = "BSC"
241 | BTC: str = "BTC"
242 | DASH: str = "DASH"
243 | DOGE: str = "DOGE"
244 | ETH: str = "ETH"
245 | LTC: str = "LTC"
246 | POLYGON: str = "POLYGON"
247 | SOL: str = "SOL"
248 | TON: str = "TON"
249 | TRON: str = "TRON"
250 | XMR: str = "XMR"
251 |
252 |
253 | class InvoiceStatuses:
254 | PROCESS: str = "process"
255 | CHECK: str = "check"
256 | CONFIRM_CHECK: str = "confirm_check"
257 | PAID: str = "paid"
258 | PAID_OVER: str = "paid_over"
259 | FAIL: str = "fail"
260 | WRONG_AMOUNT: str = "wrong_amount"
261 | WRONG_AMOUNT_WAITING = "wrong_amount_waiting"
262 | CANCEL: str = "cancel"
263 | SYSTEM_FAIL: str = "system_fail"
264 | REFUND_PROCESS: str = "refund_process"
265 | REFUND_FAIL: str = "refund_fail"
266 | REFUND_PAID: str = "refund_paid"
267 | LOCKED: str = "locked"
268 |
269 |
270 | class PayoutStatuses:
271 | PROCESS: str = "process"
272 | CHECK: str = "check"
273 | PAID: str = "paid"
274 | FAIL: str = "fail"
275 | CANCEL: str = "cancel"
276 | SYSTEM_FAIL: str = "system_fail"
--------------------------------------------------------------------------------
/AsyncPayments/crystalPay/__init__.py:
--------------------------------------------------------------------------------
1 | from .api import AsyncCrystalPay
--------------------------------------------------------------------------------
/AsyncPayments/crystalPay/api.py:
--------------------------------------------------------------------------------
1 | from ..requests import RequestsClient
2 | from typing import Optional, Union, List
3 | from .models import CreatePayment, CassaInfo, PayoffCreate, TickersRate, PayoffRequest, \
4 | PaymentInfo, BalancesList, Balance, Methods, Method, SwapPair, \
5 | CreateSwap, SwapInfo, CreateTransfer, TransferInfo, Stats
6 | import json
7 | import hashlib
8 |
9 |
10 | class AsyncCrystalPay(RequestsClient):
11 | API_HOST: str = "https://crystalpay.io"
12 |
13 | def __init__(self, login: str, secret: str, salt: str) -> None:
14 | """
15 | Initialize CrystalPay API client
16 | :param login: Your Login
17 | :param secret: Your Secret
18 | :param salt: Your Salt
19 | """
20 | super().__init__()
21 | self.__login = login
22 | self.__secret = secret
23 | self.__salt = salt
24 | self.__headers = {
25 | 'Content-Type': 'application/json',
26 | }
27 | self.__base_url = "https://api.crystalpay.io/v3"
28 | self.__post_method = "POST"
29 | self.__payment_name = "crystalPay"
30 | self.check_values()
31 |
32 | def check_values(self):
33 | if not self.__login or not self.__secret or not self.__salt:
34 | raise ValueError('No Secret, Login or Salt specified')
35 |
36 | async def get_cassa_info(self, hide_empty: Optional[bool]= False) -> CassaInfo:
37 | """Get cash info.
38 |
39 | Docs: https://docs.crystalpay.io/metody-api/me-kassa/poluchenie-informacii-o-kasse"""
40 |
41 | url = f'{self.__base_url}/me/info/'
42 |
43 | params = {
44 | "auth_login": self.__login,
45 | "auth_secret": self.__secret,
46 | "hide_empty": hide_empty,
47 | }
48 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
49 |
50 | return CassaInfo(**response)
51 |
52 | async def get_balance_list(self, hide_empty: Optional[bool] = False) -> BalancesList:
53 | """Get balances list.
54 |
55 | Docs: https://docs.crystalpay.io/metody-api/balance-balansy/poluchenie-spiska-balansov
56 |
57 | :param hide_empty: Optional. Hide empty balances. Defaults to False"""
58 |
59 | url = f'{self.__base_url}/balance/list/'
60 |
61 | params = {
62 | "auth_login": self.__login,
63 | "auth_secret": self.__secret,
64 | "hide_empty": hide_empty,
65 | }
66 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
67 | if response['items']:
68 | return BalancesList(**response['items'])
69 | else:
70 | return []
71 |
72 | async def get_balance(self, method: str) -> Balance:
73 | """Get balance of the method.
74 |
75 | Docs: https://docs.crystalpay.io/metody-api/balance-balansy/poluchenie-balansa
76 |
77 | :param method: Internal name of the account/method."""
78 |
79 | url = f'{self.__base_url}/balance/get/'
80 |
81 | params = {
82 | "auth_login": self.__login,
83 | "auth_secret": self.__secret,
84 | "method": method,
85 | }
86 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
87 | return Balance(**response)
88 |
89 | async def get_payment_methods(self, compact: Optional[bool] = False) -> Methods:
90 | """Get list of a methods.
91 |
92 | Docs: https://docs.crystalpay.io/metody-api/method-metody/poluchenie-spiska-metodov
93 |
94 | :param compact: Displaying only basic information."""
95 |
96 | url = f'{self.__base_url}/method/list/'
97 |
98 | params = {
99 | "auth_login": self.__login,
100 | "auth_secret": self.__secret,
101 | "compact": compact,
102 | }
103 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
104 |
105 | return Methods(**response['items'])
106 |
107 |
108 | async def get_payment_method(self, method: str) -> Method:
109 | """Get info about a method.
110 |
111 | Docs: https://docs.crystalpay.io/metody-api/method-metody/poluchenie-metoda
112 |
113 | :param compact: The internal name of the method."""
114 |
115 | url = f'{self.__base_url}/method/get/'
116 |
117 | params = {
118 | "auth_login": self.__login,
119 | "auth_secret": self.__secret,
120 | "method": method,
121 | }
122 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
123 |
124 | return Method(**response)
125 |
126 |
127 | async def edit_payment_method(self, method: str, extra_commission_percent: Union[int, float], enabled: bool) -> bool:
128 | """Edit payment method
129 |
130 | Dosc: https://docs.crystalpay.io/api/metody-oplaty/izmenenie-nastroek-metoda-oplaty
131 |
132 | :param method: Payment method, for example: LZTMARKET, BITCOIN
133 | :param extra_commission_percent: Additional cash desk commission for payment method, in percent
134 | :param enabled: Enable/Disable payment method
135 |
136 | :return: True if successful, else exception BadRequest
137 | """
138 |
139 | url = f'{self.__base_url}/method/edit/'
140 |
141 | params = {
142 | "auth_login": self.__login,
143 | "auth_secret": self.__secret,
144 | "method": method,
145 | "extra_commission_percent": extra_commission_percent,
146 | "enabled": enabled,
147 | }
148 |
149 | await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
150 |
151 | return True
152 |
153 | async def create_payment(
154 | self, amount: Union[int, float], amount_currency: Optional[str] = "RUB", required_methods: Optional[str] = None,
155 | _type: Optional[str] = "purchase", description: Optional[str] = None, redirect_url: Optional[str] = None,
156 | callback_url: Optional[str] = None, extra: Optional[str] = None, payer_details: Optional[str] = None,
157 | lifetime: Optional[int] = 60) -> CreatePayment:
158 | """Generate payment url.
159 |
160 | Docs: https://docs.crystalpay.io/metody-api/invoice-platezhi/sozdanie-invoisa
161 |
162 | :param amount: Order amount.
163 | :param amount_currency: Currency. Default to 'RUB', for example: USD, BTC, ETH
164 | :param required_methods: Pre-selected payment method, for example: LZTMARKET, BITCOIN
165 | :param _type: Invoice type. possible options: purchase, topup
166 | :param description: The description or purpose of the payment is displayed to the payer on the payment page, for example: Account purchase #12345678
167 | :param redirect_url: Redirect link after payment
168 | :param callback_url: Link for HTTP Callback notification after successful payment
169 | :param extra: Any internal data, for example: Payment ID in your system
170 | :param payer_details: Payer email
171 | :param lifetime: Invoice lifetime in minutes, maximum - 4320. Default to 60"""
172 |
173 | url = f'{self.__base_url}/invoice/create/'
174 |
175 | params = {
176 | "auth_login": self.__login,
177 | "auth_secret": self.__secret,
178 | "amount": amount,
179 | "amount_currency": amount_currency,
180 | "required_methods": required_methods,
181 | "type": _type,
182 | "description": description,
183 | "redirect_url": redirect_url,
184 | "callback_url": callback_url,
185 | "extra": extra,
186 | "payer_details": payer_details,
187 | "lifetime": lifetime,
188 | }
189 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
190 |
191 | return CreatePayment(**response)
192 |
193 | async def get_payment_info(self, invoice_id: str) -> PaymentInfo:
194 | """Get info about payment.
195 |
196 | Docs: https://docs.crystalpay.io/metody-api/invoice-platezhi/poluchenie-informacii-ob-invoise
197 |
198 | :param invoice_id: Invoice ID"""
199 |
200 | url = f'{self.__base_url}/invoice/info/'
201 |
202 | params = {
203 | "auth_login": self.__login,
204 | "auth_secret": self.__secret,
205 | "id": invoice_id,
206 | }
207 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
208 |
209 | return PaymentInfo(**response)
210 |
211 | async def create_payoff(self, amount: Union[int, float], method: str, wallet: str, subtract_from: str,
212 | amount_currency: Optional[str] = None, callback_url: Optional[str] = None,
213 | extra: Optional[str] = None, wallet_extra: Optional[str] = None) -> PayoffCreate:
214 | """Create payoff request.
215 |
216 | Docs: https://docs.crystalpay.io/metody-api/payoff-vyvody/sozdanie-vyvoda
217 |
218 | :param amount: Payoff amount, for example: 10, 0.0015
219 | :param amount_currency: The currency of the amount is automatically converted into the currency of the withdrawal method, for example: RUB, USD, BTC
220 | :param method: Payoff method, for example: LZTMARKET, BITCOIN
221 | :param wallet: Recipient's wallet details
222 | :param subtract_from: Where to write off the commission amount, possible options: balance, amount
223 | :param callback_url: Link for HTTP Callback notification after output is complete
224 | :param extra: Any internal data, for example: Payment ID in your system
225 | :param wallet_extra: Optional. Additional information about the recipient's details.
226 |
227 | More about subtract_from:
228 |
229 | amount - The commission will be deducted from the withdrawal amount. The amount will be credited to your wallet.
230 | balance - The commission will be deducted from the balance. The exact amount will be sent to your wallet."""
231 |
232 | url = f'{self.__base_url}/payoff/create/'
233 |
234 | signature = hashlib.sha1(str.encode(f"{amount}:{method}:{wallet}:{self.__salt}")).hexdigest()
235 |
236 | params = {
237 | "auth_login": self.__login,
238 | "auth_secret": self.__secret,
239 | "signature": signature,
240 | "amount": amount,
241 | "amount_currency": amount_currency,
242 | "method": method,
243 | "wallet": wallet,
244 | "wallet_extra": wallet_extra,
245 | "subtract_from": subtract_from,
246 | "callback_url": callback_url,
247 | "extra": extra,
248 | }
249 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
250 |
251 | return PayoffCreate(**response)
252 |
253 | async def submit_payoff(self, payoff_id: str) -> PayoffRequest:
254 | """Submit payoff request
255 |
256 | Docs: https://docs.crystalpay.io/metody-api/payoff-vyvody/podtverzhdenie-vyvoda
257 |
258 | :param payoff_id: Payoff ID"""
259 |
260 | signature = hashlib.sha1(str.encode(f"{payoff_id}:{self.__salt}")).hexdigest()
261 |
262 | url = f"{self.__base_url}/payoff/submit/"
263 |
264 | params = {
265 | "auth_login": self.__login,
266 | "auth_secret": self.__secret,
267 | "signature": signature,
268 | "id": payoff_id,
269 | }
270 |
271 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
272 |
273 | return PayoffRequest(**response)
274 |
275 |
276 | async def cancel_payoff(self, payoff_id: str) -> PayoffRequest:
277 | """Cancel payoff request
278 |
279 | Docs: https://docs.crystalpay.io/metody-api/payoff-vyvody/otmena-vyvoda
280 |
281 | :param payoff_id: Payoff ID"""
282 |
283 | signature = hashlib.sha1(str.encode(f"{payoff_id}:{self.__salt}")).hexdigest()
284 |
285 | url = f"{self.__base_url}/payoff/cancel/"
286 |
287 | params = {
288 | "auth_login": self.__login,
289 | "auth_secret": self.__secret,
290 | "signature": signature,
291 | "id": payoff_id,
292 | }
293 |
294 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
295 |
296 | return PayoffRequest(**response)
297 |
298 | async def get_payoff(self, payoff_id: str) -> PayoffRequest:
299 | """Get info about payoff request
300 |
301 | Docs: https://docs.crystalpay.io/metody-api/payoff-vyvody/poluchenie-informacii-o-vyvode
302 |
303 | :param payoff_id: Payoff ID"""
304 |
305 | url = f"{self.__base_url}/payoff/info/"
306 |
307 | params = {
308 | "auth_login": self.__login,
309 | "auth_secret": self.__secret,
310 | "id": payoff_id,
311 | }
312 |
313 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
314 |
315 | return PayoffRequest(**response)
316 |
317 | async def get_tickers_list(self) -> list:
318 | """Get a list of available currencies
319 |
320 | Dosc: https://docs.crystalpay.io/api/valyuty/poluchenie-spiska-dostupnykh-valyut"""
321 |
322 | url = f"{self.__base_url}/ticker/list/"
323 |
324 | params = {
325 | "auth_login": self.__login,
326 | "auth_secret": self.__secret,
327 | }
328 |
329 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
330 |
331 | return list(response['tickers'])
332 |
333 | async def get_tickers_rate(self, tickers: list, base_currency: Optional[str] = "RUB") -> TickersRate:
334 | """Get the exchange rate against
335 |
336 | Docs: https://docs.crystalpay.io/api/valyuty/poluchenie-kursa-valyut
337 |
338 | :param tickers: Array of currencies, for example: [“BTC”, “LTC”]
339 | :param base_currency: Base currency, RUB by default."""
340 |
341 | url = f"{self.__base_url}/ticker/get/"
342 |
343 | params = {
344 | "auth_login": self.__login,
345 | "auth_secret": self.__secret,
346 | "tickers": tickers,
347 | "base_currency": base_currency,
348 | }
349 |
350 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
351 |
352 | return TickersRate(**response)
353 |
354 | async def get_list_swap_pairs(self, page: Optional[int] = 1, items: Optional[int] = 20, source: Optional[str] = None,
355 | target: Optional[str] = None) -> List[SwapPair]:
356 | """Getting a list of swap pairs.
357 |
358 | Docs: https://docs.crystalpay.io/metody-api/swap-obmeny/obmennye-pary/poluchenie-spiska-obmennykh-par
359 |
360 | :param page: Optional. Page Number. Default is 1.
361 | :param items: Optional. Number of items per page. Default is 20.
362 | :param source: Optional. The original currency, deducted during the exchange. Filter by source.
363 | :param target: Optional. The currency received is credited during the exchange. Filter by target.
364 | """
365 |
366 | url = f"{self.__base_url}/swap/pair/list/"
367 |
368 | params = {
369 | "auth_login": self.__login,
370 | "auth_secret": self.__secret,
371 | "page": page,
372 | "items": items,
373 | "source": source,
374 | "target": target,
375 | }
376 | self._delete_empty_fields(params)
377 |
378 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
379 |
380 | return [SwapPair(**swapPair) for swapPair in response['items'].values()]
381 |
382 | async def get_swap_pair(self, pair_id: int) -> SwapPair:
383 | """Get a swap pair.
384 |
385 | Docs: https://docs.crystalpay.io/metody-api/swap-obmeny/obmennye-pary/poluchenie-obmennoi-pary
386 |
387 | :param pair_id: ID of the swap pair.
388 | """
389 |
390 | url = f"{self.__base_url}/swap/pair/get/"
391 |
392 | params = {
393 | "auth_login": self.__login,
394 | "auth_secret": self.__secret,
395 | "pair_id": pair_id,
396 | }
397 |
398 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
399 |
400 | return SwapPair(**response)
401 |
402 | async def create_swap(self, pair_id: int, amount: int, amount_type: str) -> CreateSwap:
403 | """Create swap.
404 |
405 | Docs: https://docs.crystalpay.io/metody-api/swap-obmeny/sozdanie-obmena
406 |
407 | :param pair_id: ID of the swap pair.
408 | :param amount: Amount of the swap.
409 | :param amount_type: Type of the amount. source - The amount specified in the original currency. target - The amount specified in the received currency.
410 | """
411 |
412 | url = f"{self.__base_url}/swap/create/"
413 | signature = hashlib.sha1(str.encode(f"{amount}:{pair_id}:{self.__salt}")).hexdigest()
414 |
415 | params = {
416 | "auth_login": self.__login,
417 | "auth_secret": self.__secret,
418 | "pair_id": pair_id,
419 | "amount": amount,
420 | "amount_type": amount_type,
421 | "signature": signature,
422 | }
423 |
424 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
425 |
426 | return CreateSwap(**response)
427 |
428 | async def swap_submit(self, swap_id: str) -> SwapInfo:
429 | """Submit swap request.
430 |
431 | Docs: https://docs.crystalpay.io/metody-api/swap-obmeny/podtverzhdenie-obmena
432 |
433 | :param swap_id: ID of the swap.
434 | """
435 |
436 | url = f"{self.__base_url}/swap/submit/"
437 | signature = hashlib.sha1(str.encode(f"{swap_id}:{self.__salt}")).hexdigest()
438 |
439 | params = {
440 | "auth_login": self.__login,
441 | "auth_secret": self.__secret,
442 | "id": swap_id,
443 | "signature": signature,
444 | }
445 |
446 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
447 |
448 | return SwapInfo(**response)
449 |
450 | async def swap_cancel(self, swap_id: str) -> SwapInfo:
451 | """Cancel swap request.
452 |
453 | Docs: https://docs.crystalpay.io/metody-api/swap-obmeny/otmena-obmena
454 |
455 | :param swap_id: ID of the swap.
456 | """
457 |
458 | url = f"{self.__base_url}/swap/cancel/"
459 | signature = hashlib.sha1(str.encode(f"{swap_id}:{self.__salt}")).hexdigest()
460 |
461 | params = {
462 | "auth_login": self.__login,
463 | "auth_secret": self.__secret,
464 | "id": swap_id,
465 | "signature": signature,
466 | }
467 |
468 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
469 |
470 | return SwapInfo(**response)
471 |
472 | async def get_swap_info(self, swap_id: str) -> SwapInfo:
473 | """Get swap info.
474 |
475 | Docs: https://docs.crystalpay.io/metody-api/swap-obmeny/poluchenie-informacii-ob-obmene
476 |
477 | :param swap_id: ID of the swap.
478 | """
479 |
480 | url = f"{self.__base_url}/swap/info/"
481 |
482 |
483 | params = {
484 | "auth_login": self.__login,
485 | "auth_secret": self.__secret,
486 | "id": swap_id,
487 | }
488 |
489 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
490 |
491 | return SwapInfo(**response)
492 |
493 | async def create_transfer(self, method: str, amount: str, receiver: str,
494 | description: Optional[str] = None) -> CreateTransfer:
495 | """Create a transfer.
496 |
497 | Docs: https://docs.crystalpay.io/metody-api/transfer-perevody/sozdanie-perevoda
498 |
499 | :param method: The internal name of the method.
500 | :param amount: Amount of the transfer.
501 | :param receiver: The recipient's cashier's login.
502 | :param description: Optional. Description of the transfer.
503 | """
504 |
505 | url = f"{self.__base_url}/transfer/create/"
506 | signature = hashlib.sha1(str.encode(f"{amount}:{method}:{receiver}:{self.__salt}")).hexdigest()
507 |
508 | params = {
509 | "auth_login": self.__login,
510 | "auth_secret": self.__secret,
511 | "method": method,
512 | "amount": amount,
513 | "receiver": receiver,
514 | "signature": signature,
515 | "description": description,
516 | }
517 |
518 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
519 |
520 | return CreateTransfer(**response)
521 |
522 | async def submit_transfer(self, transfer_id: str) -> TransferInfo:
523 | """Submit the transfer.
524 |
525 | Docs: https://docs.crystalpay.io/metody-api/transfer-perevody/podtverzhdenie-perevoda
526 |
527 | :param transfer_id: ID of the transfer.
528 | """
529 |
530 | url = f"{self.__base_url}/transfer/submit/"
531 | signature = hashlib.sha1(str.encode(f"{transfer_id}:{self.__salt}")).hexdigest()
532 |
533 | params = {
534 | "auth_login": self.__login,
535 | "auth_secret": self.__secret,
536 | "id": transfer_id,
537 | "signature": signature,
538 | }
539 |
540 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
541 |
542 | return TransferInfo(**response)
543 |
544 | async def cancel_transfer(self, transfer_id: str) -> TransferInfo:
545 | """Cancel the transfer.
546 |
547 | Docs: https://docs.crystalpay.io/metody-api/transfer-perevody/otmena-perevoda
548 |
549 | :param transfer_id: ID of the transfer.
550 | """
551 |
552 | url = f"{self.__base_url}/transfer/submit/"
553 | signature = hashlib.sha1(str.encode(f"{transfer_id}:{self.__salt}")).hexdigest()
554 |
555 | params = {
556 | "auth_login": self.__login,
557 | "auth_secret": self.__secret,
558 | "id": transfer_id,
559 | "signature": signature,
560 | }
561 |
562 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
563 |
564 | return TransferInfo(**response)
565 |
566 | async def get_transfer_info(self, transfer_id: str) -> TransferInfo:
567 | """Get info about the transfer.
568 |
569 | Docs: https://docs.crystalpay.io/metody-api/transfer-perevody/poluchenie-informacii-o-perevode
570 |
571 | :param transfer_id: ID of the transfer.
572 | """
573 |
574 | url = f"{self.__base_url}/transfer/info/"
575 |
576 | params = {
577 | "auth_login": self.__login,
578 | "auth_secret": self.__secret,
579 | "id": transfer_id,
580 | }
581 |
582 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
583 |
584 | return TransferInfo(**response)
585 |
586 | async def get_history_payments(self, page: Optional[int] = 1, items: Optional[int] = 20, period: Optional[int] = 1,
587 | export_csv: Optional[bool] = False) -> List[PaymentInfo]:
588 | """Get payments history.
589 |
590 | Docs: https://docs.crystalpay.io/metody-api/report-otchyoty-i-statistika/invoice-platezhi/poluchenie-istorii
591 |
592 | :param page: Optional. Page number. Default is 1.
593 | :param items: Optional. Number of items per page. Default is 20.
594 | :param period: Optional. The period from the current date, in days. Default is 1.
595 | :param export_csv: Optional. Export as a csv format table. Default is False.
596 | """
597 |
598 | url = f"{self.__base_url}/report/invoice/history/"
599 |
600 | params = {
601 | "auth_login": self.__login,
602 | "auth_secret": self.__secret,
603 | "page": page,
604 | "items": items,
605 | "period": period,
606 | "export_csv": export_csv,
607 | }
608 |
609 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
610 |
611 | if response["items"]:
612 | return [PaymentInfo(**payment) for payment in response['items']]
613 | else:
614 | return []
615 |
616 | async def get_stats_payments(self, period: Optional[int] = 1,
617 | export_pdf: Optional[bool] = False) -> Stats:
618 | """Get payments stats.
619 |
620 | Docs: https://docs.crystalpay.io/metody-api/report-otchyoty-i-statistika/invoice-platezhi/poluchenie-statistiki
621 |
622 | :param period: Optional. The period from the current date, in days. Default is 1.
623 | :param export_pdf: Optional. Export as a pdf format. Default is False.
624 | """
625 |
626 | url = f"{self.__base_url}/report/invoice/summary/"
627 |
628 | params = {
629 | "auth_login": self.__login,
630 | "auth_secret": self.__secret,
631 | "period": period,
632 | "export_pdf": export_pdf,
633 | }
634 |
635 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
636 |
637 | return Stats(**response)
638 |
639 | async def get_history_payoffs(self, page: Optional[int] = 1, items: Optional[int] = 20, period: Optional[int] = 1,
640 | export_csv: Optional[bool] = False) -> List[PayoffRequest]:
641 | """Get payoffs history.
642 |
643 | Docs: https://docs.crystalpay.io/metody-api/report-otchyoty-i-statistika/payoff-vyvody/poluchenie-istorii
644 |
645 | :param page: Optional. Page number. Default is 1.
646 | :param items: Optional. Number of items per page. Default is 20.
647 | :param period: Optional. The period from the current date, in days. Default is 1.
648 | :param export_csv: Optional. Export as a csv format table. Default is False.
649 | """
650 |
651 | url = f"{self.__base_url}/report/payoff/history/"
652 |
653 | params = {
654 | "auth_login": self.__login,
655 | "auth_secret": self.__secret,
656 | "page": page,
657 | "items": items,
658 | "period": period,
659 | "export_csv": export_csv,
660 | }
661 |
662 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
663 |
664 | if response['items']:
665 | return [PayoffRequest(**payment) for payment in response['items']]
666 | else:
667 | return []
668 |
669 | async def get_stats_payoffs(self, period: Optional[int] = 1,
670 | export_pdf: Optional[bool] = False) -> Stats:
671 | """Get payoff stats.
672 |
673 | Docs: https://docs.crystalpay.io/metody-api/report-otchyoty-i-statistika/payoff-vyvody/poluchenie-statistiki
674 |
675 | :param period: Optional. The period from the current date, in days. Default is 1.
676 | :param export_pdf: Optional. Export as a pdf format. Default is False.
677 | """
678 |
679 | url = f"{self.__base_url}/report/payoff/summary/"
680 |
681 | params = {
682 | "auth_login": self.__login,
683 | "auth_secret": self.__secret,
684 | "period": period,
685 | "export_pdf": export_pdf,
686 | }
687 |
688 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
689 |
690 | return Stats(**response)
691 |
692 |
693 | async def get_history_swaps(self, page: Optional[int] = 1, items: Optional[int] = 20, period: Optional[int] = 1,
694 | export_csv: Optional[bool] = False) -> List[SwapInfo]:
695 | """Get swaps history.
696 |
697 | Docs: https://docs.crystalpay.io/metody-api/report-otchyoty-i-statistika/swap-obmeny/poluchenie-istorii
698 |
699 | :param page: Optional. Page number. Default is 1.
700 | :param items: Optional. Number of items per page. Default is 20.
701 | :param period: Optional. The period from the current date, in days. Default is 1.
702 | :param export_csv: Optional. Export as a csv format table. Default is False.
703 | """
704 |
705 | url = f"{self.__base_url}/report/swap/history/"
706 |
707 | params = {
708 | "auth_login": self.__login,
709 | "auth_secret": self.__secret,
710 | "page": page,
711 | "items": items,
712 | "period": period,
713 | "export_csv": export_csv,
714 | }
715 |
716 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
717 |
718 | if response["items"]:
719 | return [SwapInfo(**payment) for payment in response['items']]
720 | else:
721 | return []
722 |
723 | async def get_history_transfers(self, page: Optional[int] = 1, items: Optional[int] = 20, period: Optional[int] = 1,
724 | export_csv: Optional[bool] = False) -> List[TransferInfo]:
725 | """Get swaps history.
726 |
727 | Docs: https://docs.crystalpay.io/metody-api/report-otchyoty-i-statistika/transfer-perevody/poluchenie-istorii
728 |
729 | :param page: Optional. Page number. Default is 1.
730 | :param items: Optional. Number of items per page. Default is 20.
731 | :param period: Optional. The period from the current date, in days. Default is 1.
732 | :param export_csv: Optional. Export as a csv format table. Default is False.
733 | """
734 |
735 | url = f"{self.__base_url}/report/transfer/history/"
736 |
737 | params = {
738 | "auth_login": self.__login,
739 | "auth_secret": self.__secret,
740 | "page": page,
741 | "items": items,
742 | "period": period,
743 | "export_csv": export_csv,
744 | }
745 |
746 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
747 |
748 | if response["items"]:
749 | return [TransferInfo(**payment) for payment in response['items']]
750 | else:
751 | return []
752 |
--------------------------------------------------------------------------------
/AsyncPayments/crystalPay/models.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel, Field
2 | from typing import Optional
3 |
4 |
5 | class CassaInfo(BaseModel):
6 | id: int
7 | name: str
8 | status_level: int
9 | created_at: str
10 |
11 |
12 | class BalanceListField(BaseModel):
13 | name: str
14 | amount: str
15 | currency: str
16 | amount_accuracy: int
17 |
18 |
19 | class Method(BaseModel):
20 | name: str
21 | currency: str
22 | amount_accuracy: int
23 | minimal_status_level: int
24 | settings: dict
25 | in_: Optional[dict] = Field(alias="in", default=None)
26 | out: Optional[dict] = None
27 |
28 |
29 | class Methods(BaseModel):
30 | BITCOIN: Method
31 | BITCOINCASH: Method
32 | BNBCRYPTOBOT: Method
33 | BNBSMARTCHAIN: Method
34 | BTCCRYPTOBOT: Method
35 | CARDRUBP2P: Method
36 | DASH: Method
37 | DOGECOIN: Method
38 | ETHCRYPTOBOT: Method
39 | ETHEREUM: Method
40 | LITECOIN: Method
41 | LTCCRYPTOBOT: Method
42 | LZTMARKET: Method
43 | POLYGON: Method
44 | SBERPAYP2P: Method
45 | SBPP2P: Method
46 | TONCOIN: Method
47 | TONCRYPTOBOT: Method
48 | TRON: Method
49 | USDCTRC: Method
50 | USDTCRYPTOBOT: Method
51 | USDTTRC: Method
52 |
53 |
54 | class BalancesList(BaseModel):
55 | BITCOIN: BalanceListField
56 | BITCOINCASH: BalanceListField
57 | BNBCRYPTOBOT: BalanceListField
58 | BNBSMARTCHAIN: BalanceListField
59 | BTCCRYPTOBOT: BalanceListField
60 | CARDRUBP2P: BalanceListField
61 | DASH: BalanceListField
62 | DOGECOIN: BalanceListField
63 | ETHCRYPTOBOT: BalanceListField
64 | ETHEREUM: BalanceListField
65 | LITECOIN: BalanceListField
66 | LTCCRYPTOBOT: BalanceListField
67 | LZTMARKET: BalanceListField
68 | POLYGON: BalanceListField
69 | SBERPAYP2P: BalanceListField
70 | SBPP2P: BalanceListField
71 | TONCOIN: BalanceListField
72 | TONCRYPTOBOT: BalanceListField
73 | TRON: BalanceListField
74 | USDCTRC: BalanceListField
75 | USDTCRYPTOBOT: BalanceListField
76 | USDTTRC: BalanceListField
77 |
78 |
79 | class CreatePayment(BaseModel):
80 | id: str
81 | url: str
82 | type_: str = Field(alias="type")
83 | rub_amount: str
84 |
85 |
86 | class Balance(BaseModel):
87 | method: str
88 | name: str
89 | amount: str
90 | currency: str
91 | amount_accuracy: int
92 |
93 |
94 | class PaymentInfo(BaseModel):
95 | id: str
96 | url: str
97 | state: str
98 | type_: str = Field(alias="type")
99 | method: Optional[str] = None
100 | required_method: Optional[str] = None
101 | amount_currency: str
102 | rub_amount: str
103 | initial_amount: str
104 | remaining_amount: str
105 | balance_amount: str
106 | commission_amount: str
107 | description: Optional[str] = None
108 | redirect_url: Optional[str] = None
109 | callback_url: Optional[str] = None
110 | extra: Optional[str] = None
111 | created_at: str
112 | expired_at: str
113 | final_at: Optional[str] = None
114 |
115 |
116 | class PayoffCreate(BaseModel):
117 | id: str
118 | method: str
119 | commission_amount: str
120 | amount: str
121 | rub_amount: str
122 | receive_amount: str
123 | deduction_amount: str
124 | subtract_from: str
125 | amount_currency: str
126 | wallet: str
127 |
128 |
129 | class PayoffRequest(BaseModel):
130 | id: str
131 | state: str
132 | method: str
133 | amount: str
134 | amount_currency: str
135 | commission_amount: str
136 | rub_amount: str
137 | receive_amount: str
138 | deduction_amount: str
139 | subtract_from: str
140 | wallet: str
141 | message: Optional[str] = None
142 | callback_url: Optional[str] = None
143 | extra: Optional[str] = None
144 | created_at: str
145 | final_at: Optional[str] = None
146 |
147 |
148 | class SwapPair(BaseModel):
149 | pair_id: Optional[int] = None
150 | source: dict
151 | target: dict
152 | price: str
153 |
154 |
155 | class CreateSwap(BaseModel):
156 | id: str
157 | pair_id: int
158 | amount_type: str
159 | amount: str
160 | source: dict
161 | target: dict
162 | price: str
163 |
164 |
165 | class SwapInfo(BaseModel):
166 | id: str
167 | state: str
168 | pair_id: int
169 | amount_type: str
170 | amount: str
171 | source: dict
172 | target: dict
173 | price: str
174 | created_at: str
175 | expired_at: str
176 | final_at: Optional[str] = None
177 |
178 |
179 | class TickersRate(BaseModel):
180 | base_currency: str
181 | currencies: dict
182 |
183 |
184 | class CreateTransfer(BaseModel):
185 | id: int
186 | method: str
187 | amount_currency: str
188 | amount: str
189 | sender: str
190 | receiver: str
191 |
192 |
193 | class TransferInfo(BaseModel):
194 | id: int
195 | state: str
196 | type_: str = Field(alias="type")
197 | method: str
198 | amount_currency: str
199 | amount: str
200 | sender: str
201 | receiver: str
202 | description: Optional[str] = None
203 | created_at: str
204 | final_at: str
205 |
206 |
207 | class Stats(BaseModel):
208 | payed_rub_amount: str
209 | payed_count: int
210 | total_count: int
211 | conversion_percent: int
212 |
--------------------------------------------------------------------------------
/AsyncPayments/exceptions/__init__.py:
--------------------------------------------------------------------------------
1 | from .exceptions import BadRequest, RequestError, MissingScopeError
2 |
--------------------------------------------------------------------------------
/AsyncPayments/exceptions/exceptions.py:
--------------------------------------------------------------------------------
1 | class BadRequest(Exception):
2 | pass
3 |
4 |
5 | class RequestError(Exception):
6 | pass
7 |
8 |
9 | class MissingScopeError(Exception):
10 | pass
11 |
--------------------------------------------------------------------------------
/AsyncPayments/freeKassa/__init__.py:
--------------------------------------------------------------------------------
1 | from .api import AsyncFreeKassa
--------------------------------------------------------------------------------
/AsyncPayments/freeKassa/api.py:
--------------------------------------------------------------------------------
1 | from ..requests import RequestsClient
2 | from typing import Optional, Union, List
3 | from .models import Balance, Order, Orders, CreateOrder, Currency, WithdrawalCurrency, Store, Withdrawal, Withdrawals, CreateWithdrawal
4 |
5 | import json
6 | import hashlib
7 | import time
8 | import hmac
9 |
10 |
11 | class AsyncFreeKassa(RequestsClient):
12 | API_HOST: str = "https://freekassa.com/"
13 |
14 | def __init__(self, apiKey: str, shopId: int) -> None:
15 | """
16 | Initialize FreeKassa API client
17 | :param apiKey: Your api key
18 | :param shopId: Your shop id
19 | """
20 | super().__init__()
21 | self.__apiKey = apiKey
22 | self.__shopId = shopId
23 | self.__headers = {
24 | 'Content-Type': 'application/json',
25 | }
26 | self.__base_url = "https://api.freekassa.com/v1"
27 | self.__post_method = "POST"
28 | self.__payment_name = "freeKassa"
29 | self.check_values()
30 |
31 | def check_values(self):
32 | if not self.__shopId or not self.__apiKey:
33 | raise ValueError('No ShopID or ApiKey specified')
34 |
35 | def __generate_sign(self, data: dict) -> str:
36 | data = dict(sorted(data.items()))
37 | return hmac.new(self.__apiKey.encode(), '|'.join(map(str, data.values())).encode(), hashlib.sha256).hexdigest()
38 |
39 | async def get_balance(self) -> List[Balance]:
40 | """Get balance or your store.
41 |
42 | Docs: https://docs.freekassa.com/#operation/getBalance
43 | """
44 | url = f"{self.__base_url}/balance"
45 |
46 | params = {
47 | "shopId": self.__shopId,
48 | "nonce": time.time_ns(),
49 | }
50 | params['signature'] = self.__generate_sign(params)
51 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
52 |
53 | return [Balance(**balance) for balance in response['balance']]
54 |
55 | async def get_orders(self, orderId: Optional[int] = None, paymentId: Optional[str] = None,
56 | orderStatus: Optional[int] = None, dateFrom: Optional[str] = None,
57 | dateTo: Optional[str] = None, page: Optional[int] = None) -> Orders:
58 | """Get orders of your store.
59 |
60 | Docs: https://docs.freekassa.com/#operation/getOrders
61 |
62 | :param orderId: Optional. Freekassa Order Number. Example: orderId=123456789.
63 | :param paymentId: Optional. The order number in your store. Example: paymentId=987654321.
64 | :param orderStatus: Optional. Order status. Example: orderStatus=1.
65 | :param dateFrom: Optional. Date from. Example: dateFrom=2021-01-01 13:45:21.
66 | :param dateTo: Optional. Date by. Example: dateTo=2021-01-02 13:45:21.
67 | :param page: Optional. Page number.
68 | """
69 | url = f"{self.__base_url}/orders"
70 | params = {
71 | "shopId": self.__shopId,
72 | "nonce": time.time_ns(),
73 | "orderId": orderId,
74 | "paymentId": paymentId,
75 | "orderStatus": orderStatus,
76 | "dateFrom": dateFrom,
77 | "dateTo": dateTo,
78 | "page": page,
79 | }
80 | self._delete_empty_fields(params)
81 | params['signature'] = self.__generate_sign(params)
82 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
83 |
84 | return Orders(pages=int(response['pages']), orders=[Order(**order) for order in response["orders"]])
85 |
86 | async def create_order(self, i: int, email: str, ip: str, amount: Union[int, float], currency: str,
87 | tel: Optional[str] = None, paymentId: Optional[str] = None,
88 | successUrl: Optional[str] = None, failureUrl: Optional[str] = None,
89 | notificationUrl: Optional[str] = None) -> CreateOrder:
90 | """Create an order and receive a payment link.
91 |
92 | Docs: https://docs.freekassa.com/#operation/createOrder
93 |
94 | :param i: Required. Payment system ID. Example: i=6.
95 | :param email: Required. Buyer's email address. Example: email=user@site.ru.
96 | :param ip: Required. Buyer's IP address. Example: ip=0.0.0.0.
97 | :param amount: Required. Payment amount. Example: amount=100.23.
98 | :param currency: Required. Payment currency. Example: currency=RUB.
99 | :param tel: Optional. The payer's phone number is required in some payment methods. Example: tel=+79261231212.
100 | :param paymentId: Optional. Payment system ID. Example: paymentId=987654321.
101 | :param successUrl: Optional. Redefining the success url (to enable this parameter, contact support). Example: successUrl=https://site.ru/success.
102 | :param failureUrl: Optional. Redefining the error URL (to enable this parameter, contact support). Example: failureUrl=https://site.ru/error.
103 | :param notificationUrl: Optional. Redefining the notification url (to enable this option, contact support). Example: notificationUrl=https://site.ru/notify.
104 | """
105 | url = f"{self.__base_url}/orders/create"
106 | params = {
107 | "shopId": self.__shopId,
108 | "nonce": time.time_ns(),
109 | "i": i,
110 | "email": email,
111 | "ip": ip,
112 | "amount": amount,
113 | "currency": currency,
114 | "tel": tel,
115 | "paymentId": paymentId,
116 | "success_url": successUrl,
117 | "failure_url": failureUrl,
118 | "notification_url": notificationUrl,
119 | }
120 | self._delete_empty_fields(params)
121 | params['signature'] = self.__generate_sign(params)
122 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
123 | return CreateOrder(**response)
124 |
125 | async def get_list_of_currencies(self) -> List[Currency]:
126 | """Get list of all available currencies for payments.
127 |
128 | Docs: https://docs.freekassa.com/#operation/getCurrencies
129 | """
130 | url = f"{self.__base_url}/currencies"
131 | params = {
132 | "shopId": self.__shopId,
133 | "nonce": time.time_ns(),
134 | }
135 | params["signature"] = self.__generate_sign(params)
136 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
137 |
138 | return [Currency(**currency) for currency in response['currencies']]
139 |
140 | async def check_currency_status(self, paymentId: int) -> bool:
141 | """Check the availability of the payment system for payment.
142 |
143 | Docs: https://docs.freekassa.com/#operation/currencyStatus
144 |
145 | :return: True - Payment is available. False - Payment is not available.
146 | """
147 | url = f"{self.__base_url}/currencies/{paymentId}/status"
148 | params = {
149 | "shopId": self.__shopId,
150 | "nonce": time.time_ns(),
151 | }
152 | params["signature"] = self.__generate_sign(params)
153 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
154 |
155 | return response['type'] == "success"
156 |
157 | async def get_list_of_currencies_for_withdrawal(self) -> List[WithdrawalCurrency]:
158 | """Get list of all available currencies for withdrawal.
159 |
160 | Docs: https://docs.freekassa.com/#operation/getWithdrawalsCurrencies
161 | """
162 | url = f"{self.__base_url}/withdrawals/currencies"
163 | params = {
164 | "shopId": self.__shopId,
165 | "nonce": time.time_ns(),
166 | }
167 | params["signature"] = self.__generate_sign(params)
168 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
169 |
170 | return [WithdrawalCurrency(**currency) for currency in response['currencies']]
171 |
172 | async def get_list_of_your_stores(self) -> List[Store]:
173 | """Get list of your stores.
174 |
175 | Docs: https://docs.freekassa.com/#operation/getShops
176 | """
177 | url = f"{self.__base_url}/shops"
178 | params = {
179 | "shopId": self.__shopId,
180 | "nonce": time.time_ns(),
181 | }
182 | params["signature"] = self.__generate_sign(params)
183 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
184 |
185 | return [Store(**store) for store in response['shops']]
186 |
187 | async def get_withdrawals(self, orderId: Optional[int] = None, paymentId: Optional[str] = None,
188 | orderStatus: Optional[int] = None, dateFrom: Optional[str] = None,
189 | dateTo: Optional[str] = None, page: Optional[int] = None) -> Withdrawals:
190 | """Get list of withdrawals.
191 |
192 | Docs: https://docs.freekassa.com/#operation/getWithdrawals
193 |
194 | :param orderId: Optional. Freekassa Order Number. Example: orderId=123456789.
195 | :param paymentId: Optional. The order number in your store. Example: paymentId=987654321.
196 | :param orderStatus: Optional. Order status. Example: orderStatus=1.
197 | :param dateFrom: Optional. Date from. Example: dateFrom=2021-01-01 13:45:21.
198 | :param dateTo: Optional. Date by. Example: dateTo=2021-01-02 13:45:21.
199 | :param page: Optional. Page number.
200 | """
201 | url = f"{self.__base_url}/withdrawals"
202 | params = {
203 | "shopId": self.__shopId,
204 | "nonce": time.time_ns(),
205 | "orderId": orderId,
206 | "paymentId": paymentId,
207 | "orderStatus": orderStatus,
208 | "dateFrom": dateFrom,
209 | "dateTo": dateTo,
210 | "page": page,
211 | }
212 | self._delete_empty_fields(params)
213 | params['signature'] = self.__generate_sign(params)
214 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
215 |
216 | return Withdrawals(pages=int(response['pages']), withdrawals=[Withdrawal(**withdrawal) for withdrawal in response["orders"]])
217 |
218 | async def create_withdrawal(self, i: int, account: str, amount: Union[int, float], currency: str,
219 | paymentId: Optional[str] = None) -> CreateWithdrawal:
220 | """Create withdrawal.
221 |
222 | Docs: https://docs.freekassa.com/#operation/createWithdrawal
223 |
224 | :param i: Required. Payment system ID. Example: i=6.
225 | :param account: Required. A wallet for crediting funds (when paying to FKWallet, withdrawal is made only to your account). Example: account=5500000000000004.
226 | :param amount: Required. Payment amount. Example: amount=100.23.
227 | :param currency: Required. Payment currency. Example: currency=RUB.
228 | :param paymentId: Optional. Payment system ID. Example: paymentId=987654321.
229 | """
230 | url = f"{self.__base_url}/withdrawals/create"
231 | params = {
232 | "shopId": self.__shopId,
233 | "nonce": time.time_ns(),
234 | "i": i,
235 | "account": account,
236 | "amount": amount,
237 | "currency": currency,
238 | "paymentId": paymentId,
239 | }
240 | self._delete_empty_fields(params)
241 | params['signature'] = self.__generate_sign(params)
242 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, data=json.dumps(params))
243 | return CreateWithdrawal(**response['data'])
244 |
--------------------------------------------------------------------------------
/AsyncPayments/freeKassa/models.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel
2 | from typing import Optional, List, Union
3 |
4 |
5 | class Balance(BaseModel):
6 | currency: str
7 | value: Union[int, str, float]
8 |
9 |
10 | class Order(BaseModel):
11 | merchant_order_id: str
12 | fk_order_id: int
13 | amount: Union[int, float]
14 | currency: str
15 | email: str
16 | account: Optional[str] = None
17 | date: str
18 | status: int
19 | payer_account: Optional[str] = None
20 |
21 |
22 | class Orders(BaseModel):
23 | pages: int
24 | orders: List[Order]
25 |
26 |
27 | class CreateOrder(BaseModel):
28 | orderId: int
29 | orderHash: str
30 | location: str
31 |
32 |
33 | class Currency(BaseModel):
34 | id: int
35 | name: str
36 | currency: str
37 | is_enabled: int
38 | is_favorite: int
39 |
40 |
41 | class WithdrawalCurrency(BaseModel):
42 | id: int
43 | name: str
44 | min: int
45 | max: int
46 | currency: str
47 | can_exchange: int
48 |
49 |
50 | class Store(BaseModel):
51 | id: int
52 | name: str
53 | url: Optional[str] = None
54 | activated: Optional[int] = None
55 |
56 |
57 | class Withdrawal(BaseModel):
58 | id: int
59 | amount: Union[int, float]
60 | currency: str
61 | ext_currency_id: int
62 | account: str
63 | date: str
64 | status: int
65 |
66 |
67 | class Withdrawals(BaseModel):
68 | pages: int
69 | withdrawals: List[Withdrawal]
70 |
71 |
72 | class CreateWithdrawal(BaseModel):
73 | id: int
74 |
--------------------------------------------------------------------------------
/AsyncPayments/lolz/__init__.py:
--------------------------------------------------------------------------------
1 | from .api import AsyncLolzteamMarketPayment
--------------------------------------------------------------------------------
/AsyncPayments/lolz/api.py:
--------------------------------------------------------------------------------
1 | from ..requests import RequestsClient
2 | from typing import Optional, Union
3 | from .models import User, Payments, Invoice, Invoices
4 | from ..exceptions import MissingScopeError
5 |
6 | import json
7 | import random
8 | import math
9 | import time
10 | import secrets
11 | import base64
12 | from urllib.parse import urlencode
13 |
14 |
15 | class AsyncLolzteamMarketPayment(RequestsClient):
16 | API_HOST: str = "https://lzt.market"
17 |
18 | def __init__(self, token: str) -> None:
19 | """
20 | Initialize LolzteamMarket API client
21 | :param token: Your Lolzteam Token
22 | """
23 | super().__init__()
24 | self.__token = token
25 | jwt_payload = json.loads(
26 | base64.b64decode(token.split(".")[1] + "==").decode("utf-8")
27 | )
28 | self.__user_id = jwt_payload["sub"]
29 | if jwt_payload.get("scope"):
30 | if "market" not in jwt_payload["scope"]:
31 | raise MissingScopeError(
32 | '"Market" scope is not provided in your token. You need to recreate token with "Market" scope.'
33 | )
34 | self.__headers = {
35 | "Authorization": f"Bearer {self.__token}",
36 | "Accept": "application/json",
37 | }
38 | self.__base_url = "https://api.lzt.market"
39 | self.__get_method = "GET"
40 | self.__post_method = "POST"
41 | self.__payment_name = "lolz"
42 |
43 | async def get_me(self) -> User:
44 | """Get info about your account on Zelenka (Lolzteam).
45 |
46 | Docs: https://lzt-market.readme.io/reference/marketprofilesettingsgetinfo"""
47 |
48 | url = f"{self.__base_url}/me"
49 |
50 | response = await self._request(
51 | self.__payment_name, self.__get_method, url, headers=self.__headers
52 | )
53 |
54 | return User(**response["user"])
55 |
56 | def __get_random_string(self):
57 | return f"{time.time()}_{secrets.token_hex(random.randint(5, 10))}"
58 |
59 | async def create_invoice(
60 | self,
61 | amount: Union[int, float],
62 | payment_id: str,
63 | comment: str,
64 | url_success: str,
65 | merchant_id: str,
66 | currency: Optional[str] = "rub",
67 | url_callback: Optional[str] = None,
68 | lifetime: Optional[int] = 3600,
69 | additional_data: Optional[str] = None
70 | ) -> Invoice:
71 | """Create invoice.
72 |
73 | :param amount: Invoice amount.
74 | :param payment_id: Payment ID in your system (must be unique within the merchant / invoices).
75 | :param comment: Comment to the invoice.
76 | :param url_success: URL to redirect to after successful payment.
77 | :param merchant_id: Merchant ID.
78 | :param currency: Optional. Currency that will be used to create the invoice. Defaults to 'rub'.
79 | :param url_callback: Optional. Callback url.
80 | :param lifetime: Optional. Invoice lifetime.
81 | :param additional_data: Optional. Additional information for you.
82 |
83 | Docs: https://lzt-market.readme.io/reference/paymentsinvoicecreate
84 | """
85 | params = {
86 | "amount": amount,
87 | "payment_id": payment_id,
88 | "comment": comment,
89 | "url_success": url_success,
90 | "merchant_id": merchant_id,
91 | "currency": currency,
92 | "url_callback": url_callback,
93 | "lifetime": lifetime,
94 | "additional_data": additional_data,
95 | }
96 | self._delete_empty_fields(params)
97 | url = f"{self.__base_url}/invoice?{urlencode(params)}"
98 |
99 | response = await self._request(
100 | self.__payment_name,
101 | self.__post_method,
102 | url,
103 | headers=self.__headers,
104 | )
105 | return Invoice(**response['invoice'])
106 |
107 | async def get_invoice(
108 | self,
109 | invoice_id: Optional[str] = None,
110 | payment_id: Optional[str] = None
111 | ) -> Invoice:
112 | """Get invoice.
113 |
114 | :param invoice_id: Optional. Invoice ID.
115 | :param payment_id: Optional. Payment ID.
116 |
117 | Docs: https://lzt-market.readme.io/reference/paymentsinvoiceget
118 | """
119 |
120 | params = {
121 | "invoice_id": invoice_id,
122 | "payment_id": payment_id,
123 | }
124 |
125 | self._delete_empty_fields(params)
126 |
127 | url = f"{self.__base_url}/invoice?{urlencode(params)}"
128 |
129 | response = await self._request(
130 | self.__payment_name,
131 | self.__get_method,
132 | url,
133 | headers=self.__headers,
134 | )
135 | return Invoice(**response['data'])
136 |
137 | async def get_invoice_list(
138 | self,
139 | page: Optional[int] = 1,
140 | currency: Optional[str] = None,
141 | status: Optional[str] = None,
142 | amount: Optional[Union[float, int]] = None,
143 | merchant_id: Optional[int] = None,
144 | ) -> Invoices:
145 | """Get invoice list.
146 |
147 | :param page: Optional. The number of the page to display results from.
148 | :param currency: Optional. Currency of the created invoice.
149 | :param status: Optional. Status of the invoice.
150 | :param amount: Optional. Invoice amount.
151 | :param merchant_id: Optional. Merchant ID.
152 |
153 | Docs: https://lzt-market.readme.io/reference/paymentsinvoicelist
154 | """
155 |
156 | url = f"{self.__base_url}/invoice/list"
157 |
158 | params = {
159 | "page": page,
160 | "currency": currency,
161 | "status": status,
162 | "amount": amount,
163 | "merchant_id": merchant_id,
164 | }
165 |
166 | self._delete_empty_fields(params)
167 |
168 | response = await self._request(
169 | self.__payment_name,
170 | self.__get_method,
171 | url,
172 | headers=self.__headers,
173 | params=params,
174 | )
175 | return Invoices(**response)
176 |
177 | def get_payment_link(
178 | self,
179 | amount: Union[int, float],
180 | comment: Optional[str] = None,
181 | is_hold: Optional[bool] = False,
182 | is_amount_ceiling: Optional[bool] = False,
183 | ) -> str:
184 | """Get a link to transfer funds to the Lolzteam market. To accept payments, it is recommended to use the create_invoice() method.
185 |
186 | :param amount: Amount to transfer
187 | :param comment: Comment on the translation. If not specified: a random unique set of characters is generated.
188 | :param is_hold: If True: The page will have funds holding enabled by default. The user will be able to turn it off. *If you use this link for payment: ask your users not to enable hold!!! Defaults to False
189 | :param is_amount_ceiling: If True: The transfer amount will be rounded up. Defaults to False
190 |
191 | :return: Link to transfer (String)"""
192 |
193 | if is_amount_ceiling:
194 | amount = math.ceil(amount)
195 |
196 | if not comment:
197 | comment = self.__get_random_string()
198 |
199 | return f"https://lzt.market/balance/transfer?user_id={self.__user_id}&hold={int(is_hold)}&amount={amount}&comment={comment}"
200 |
201 | async def get_history_payments(
202 | self,
203 | operation_type: Optional[str] = None,
204 | pmin: Optional[int] = None,
205 | pmax: Optional[int] = None,
206 | page: Optional[int] = 1,
207 | operation_id_lt: Optional[int] = None,
208 | receiver: Optional[str] = None,
209 | sender: Optional[str] = None,
210 | startDate: Optional[str] = None,
211 | endDate: Optional[str] = None,
212 | wallet: Optional[str] = None,
213 | comment: Optional[str] = None,
214 | is_hold: Optional[bool] = None,
215 | show_payment_stats: Optional[bool] = None,
216 | ) -> Payments:
217 | """Displays list of your payments.
218 |
219 | Docs: https://lzt-market.readme.io/reference/paymentslisthistory
220 |
221 | :param operation_type: Optional. Type of operation. It can only be: "income", "cost", "refilled_balance", "withdrawal_balance", "paid_item", "sold_item", "money_transfer", "receiving_money", "internal_purchase", "claim_hold".
222 | :param pmin: Optional. Minimal price of account (Inclusive).
223 | :param pmax: Optional. Maximum price of account (Inclusive).
224 | :param page: Optional. The number of the page to display results from.
225 | :param operation_id_lt: Optional. ID of the operation from which the result begins.
226 | :param receiver: Optional. Username of user, which receive money from you.
227 | :param sender: Optional. Username of user, which sent money to you.
228 | :param startDate: Optional. Start date of operation (RFC 3339 date format).
229 | :param endDate: Optional. End date of operation (RFC 3339 date format).
230 | :param wallet: Optional. Wallet, which used for money payouts.
231 | :param comment: Optional. Comment for money transfers.
232 | :param is_hold: Optional. Display hold operations.
233 | :param show_payment_stats: Optional. Display payment stats for selected period (outgoing value, incoming value).
234 | """
235 |
236 | url = f"{self.__base_url}/user/{self.__user_id}/payments"
237 |
238 | if is_hold:
239 | is_hold = int(is_hold)
240 | if show_payment_stats:
241 | show_payment_stats = int(show_payment_stats)
242 |
243 | params = {
244 | "type": operation_type,
245 | "pmin": pmin,
246 | "pmax": pmax,
247 | "page": page,
248 | "operation_id_lt": operation_id_lt,
249 | "receiver": receiver,
250 | "sender": sender,
251 | "startDate": startDate,
252 | "endDate": endDate,
253 | "wallet": wallet,
254 | "comment": comment,
255 | "is_hold": is_hold,
256 | "show_payment_stats": show_payment_stats,
257 | }
258 |
259 | self._delete_empty_fields(params)
260 |
261 | response = await self._request(
262 | self.__payment_name,
263 | self.__get_method,
264 | url,
265 | headers=self.__headers,
266 | params=params,
267 | )
268 | if type(response.get("payments")) is list and len(response.get("payments")) == 0:
269 | response["payments"] = {}
270 | return Payments(**response)
271 |
272 | async def check_status_payment(self, pay_amount: int, comment: str) -> bool:
273 | """Displays whether the transfer is paid or not.
274 |
275 | :param pay_amount: The amount indicated in the transaction.
276 | :param comment: Comment indicated in the transaction.
277 |
278 | :return: True if payment has been received. Otherwise False"""
279 | payments = (
280 | await self.get_history_payments(
281 | operation_type="receiving_money",
282 | comment=comment,
283 | pmin=pay_amount,
284 | pmax=pay_amount,
285 | )
286 | ).payments
287 | if payments.values():
288 | return True
289 | return False
290 |
--------------------------------------------------------------------------------
/AsyncPayments/lolz/models.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel
2 | from typing import Optional, List, Union
3 |
4 |
5 | class User(BaseModel):
6 | user_id: int
7 | username: str
8 | balance: float
9 | hold: float
10 |
11 | class Payments(BaseModel):
12 | payments: dict
13 | page: int
14 | hasNextPage: bool
15 |
16 |
17 | class Invoice(BaseModel):
18 | amount: Union[float, int]
19 | currency: str
20 | payment_id: str
21 | merchant_id: int
22 | comment: str
23 | additional_data: str
24 | url_success: str
25 | url_callback: str
26 | expires_at: int
27 | user_id: int
28 | invoice_date: int
29 | status: str
30 | paid_date: int
31 | invoice_id: int
32 | url: str
33 |
34 |
35 | class Invoices(BaseModel):
36 | invoices: Optional[List[Invoice]] = []
37 | count: int
38 | page: int
39 | perPage: int
--------------------------------------------------------------------------------
/AsyncPayments/payok/__init__.py:
--------------------------------------------------------------------------------
1 | from .api import AsyncPayOK
--------------------------------------------------------------------------------
/AsyncPayments/payok/api.py:
--------------------------------------------------------------------------------
1 | from ..requests import RequestsClient
2 | from typing import Optional, Union, List
3 | from .models import Balance, Transaction, Payout, CreatePayout, PayoutOnCreate
4 | from urllib.parse import urlencode
5 | import hashlib
6 |
7 |
8 | class AsyncPayOK(RequestsClient):
9 | API_HOST: str = "https://payok.io/"
10 |
11 | def __init__(self, apiKey: str, secretKey: str, apiId: int, shopId: int) -> None:
12 | """
13 | Initialize PayOK API client
14 | :param apiKey: Your api key
15 | :param secretKey: Your secret key
16 | :param apiId: Your api id
17 | :param shopId: Your shop id
18 | """
19 | super().__init__()
20 | self.__apiKey = apiKey
21 | self.__secretKey = secretKey
22 | self.__apiId = apiId
23 | self.__shopId = shopId
24 | self.__base_url = "https://payok.io/api"
25 | self.__post_method = "POST"
26 | self.__payment_name = "payok"
27 | self.check_values()
28 |
29 | def check_values(self):
30 | if not self.__secretKey or not self.__apiKey or not self.__apiId or not self.__shopId:
31 | raise ValueError('No SecretKey, ApiKey, ShopID or ApiID specified')
32 |
33 | async def get_balance(self) -> Balance:
34 | """Get your balance.
35 |
36 | Docs: https://payok.io/cabinet/documentation/doc_api_balance
37 | """
38 | url = f"{self.__base_url}/balance"
39 |
40 | params = {
41 | "API_ID": self.__apiId,
42 | "API_KEY": self.__apiKey,
43 | }
44 | response = await self._request(self.__payment_name, self.__post_method, url, data=params)
45 |
46 | return Balance(**response)
47 |
48 | async def get_transactions(self, payment: Optional[int] = None,
49 | offset: Optional[int] = None) -> Union[Transaction, List[Transaction]]:
50 | """Get list of transactions.
51 |
52 | Docs: https://payok.io/cabinet/documentation/doc_api_transaction
53 |
54 | :param payment: Optional. Payment ID in your system.
55 | :param offset: Optional. Indentation, skipping the specified number of lines.
56 | """
57 | url = f"{self.__base_url}/transaction"
58 |
59 | params = {
60 | "API_ID": self.__apiId,
61 | "API_KEY": self.__apiKey,
62 | "shop": self.__shopId,
63 | "payment": payment,
64 | "offset": offset,
65 | }
66 | self._delete_empty_fields(params)
67 | response = await self._request(self.__payment_name, self.__post_method, url, data=params)
68 | if payment:
69 | return Transaction(**response['1'])
70 |
71 | return [Transaction(**transaction) for transaction in response.values()]
72 |
73 | async def get_payouts(self, payout_id: Optional[int] = None, offset: Optional[int] = None):
74 | """Get list of payouts.
75 |
76 | Docs: https://payok.io/cabinet/documentation/doc_api_payout
77 |
78 | :param payout_id: Payment ID in the Payok system.
79 | :param offset: Indentation, skipping the specified number of lines.
80 | """
81 | url = f"{self.__base_url}/payout"
82 | params = {
83 | "API_ID": self.__apiId,
84 | "API_KEY": self.__apiKey,
85 | "payout_id": payout_id,
86 | "offset": offset,
87 | }
88 | self._delete_empty_fields(params)
89 | response = await self._request(self.__payment_name, self.__post_method, url, data=params)
90 |
91 | if payout_id:
92 | return Payout(**response['1'])
93 |
94 | return [Payout(**payout) for payout in response.values()]
95 |
96 | async def create_payout(
97 | self,
98 | amount: float,
99 | method: str,
100 | reciever: str,
101 | commission_type: str,
102 | sbp_bank: Optional[str] = None,
103 | webhook_url: Optional[str] = None
104 | ) -> CreatePayout:
105 | """
106 | Create payout.
107 |
108 | Docs: https://payok.io/cabinet/documentation/doc_api_payout_create
109 |
110 | :param amount: Payment amount.
111 | :param method: Special value of the payment method, list of values.
112 | :param reciever: Details of the payee.
113 | :param commission_type: The bank for the payment of SBP.
114 | :param sbp_bank: Type of commission calculation: balance - Commission from the balance sheet, payment - Commission from the payment.
115 | :param webhook_url: URL for sending a Webhook when the payment status changes.
116 | """
117 | url = f"{self.__base_url}/payout_create"
118 | params = {
119 | "API_ID": self.__apiId,
120 | "API_KEY": self.__apiKey,
121 | "amount": amount,
122 | "method": method,
123 | "reciever": reciever,
124 | "commission_type": commission_type,
125 | "sbp_bank": sbp_bank,
126 | "webhook_url": webhook_url
127 | }
128 | self._delete_empty_fields(params)
129 | response = await self._request(self.__payment_name, self.__post_method, url, data=params)
130 |
131 | return CreatePayout(remain_balance=response['remain_balance'], payout=PayoutOnCreate(**response['data']))
132 |
133 |
134 | async def create_pay(
135 | self,
136 | amount: float,
137 | payment: Union[int, str],
138 | currency: Optional[str] = "RUB",
139 | desc: Optional[str] = 'Description',
140 | email: Optional[str] = None,
141 | success_url: Optional[str] = None,
142 | method: Optional[str] = None,
143 | lang: Optional[str] = None,
144 | custom: Optional[str] = None
145 | ) -> str:
146 | """Create payform url.
147 |
148 | Docs: https://payok.io/cabinet/documentation/doc_payform.php
149 |
150 | :param payment: Order number, unique in your system, up to 16 characters. (a-z0-9-_)
151 | :param amount : Order amount.
152 | :param currency : ISO 4217 currency. Default is "RUB".
153 | :param desc : Product name or description.
154 | :param email : Email Buyer mail. Defaults to None.
155 | :param success_url: Link to redirect after payment.
156 | :param method: Payment method
157 | :param lang: Interface language. RU or EN
158 | :param custom: Parameter that you want to pass in the notification.
159 | """
160 |
161 | params = {
162 | 'amount': amount,
163 | 'payment': payment,
164 | 'shop': self.__shopId,
165 | 'currency': currency,
166 | 'desc': desc,
167 | 'email': email,
168 | 'success_url': success_url,
169 | 'method': method,
170 | 'lang': lang,
171 | 'custom': custom
172 | }
173 |
174 | self._delete_empty_fields(params)
175 |
176 | sign_params = '|'.join(map(
177 | str,
178 | [amount, payment, self.__shopId, currency, desc, self.__secretKey]
179 | )).encode('utf-8')
180 | sign = hashlib.md5(sign_params).hexdigest()
181 | params['sign'] = sign
182 |
183 | url = f'{self.API_HOST}/pay?' + urlencode(params)
184 | return url
185 |
--------------------------------------------------------------------------------
/AsyncPayments/payok/models.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel
2 | from typing import Optional, Union
3 |
4 |
5 | class Balance(BaseModel):
6 | balance: int
7 | ref_balance: Union[str, float, int]
8 |
9 |
10 | class Transaction(BaseModel):
11 | transaction: Union[str, int]
12 | email: str
13 | amount: Union[str, int]
14 | currency: str
15 | currency_amount: Union[str, int]
16 | comission_percent: Union[str, int]
17 | comission_fixed: str
18 | amount_profit: Union[str, int]
19 | method: Optional[str] = None
20 | payment_id: Union[int, str]
21 | description: str
22 | date: str
23 | pay_date: str
24 | transaction_status: Union[str, int]
25 | custom_fields: Optional[Union[str, int, dict]] = None
26 | webhook_status: Union[str, int]
27 | webhook_amount: Union[str, int]
28 |
29 |
30 | class Payout(BaseModel):
31 | payout: int
32 | method: str
33 | reciever: str
34 | type: str
35 | amount: int
36 | comission_percent: int
37 | comission_fixed: str
38 | amount_profit: int
39 | date_create: str
40 | date_pay: str
41 | status: int
42 |
43 |
44 | class PayoutOnCreate(BaseModel):
45 | payout_id: int
46 | method: str
47 | reciever: str
48 | amount: int
49 | comission_percent: int
50 | comission_fixed: str
51 | amount_profit: int
52 | date: str
53 | payout_status_code: int
54 | payout_status_text: str
55 |
56 |
57 | class CreatePayout(BaseModel):
58 | remain_balance: Union[str, int, float]
59 | payout: PayoutOnCreate
60 |
--------------------------------------------------------------------------------
/AsyncPayments/requests.py:
--------------------------------------------------------------------------------
1 | import ssl
2 | import certifi
3 | from typing import Optional
4 | from aiohttp import ClientSession, TCPConnector
5 | from .exceptions.exceptions import BadRequest, RequestError
6 |
7 |
8 | class RequestsClient:
9 |
10 | def __init__(self) -> None:
11 | self._session: Optional[ClientSession] = None
12 |
13 | def _getsession(self) -> ClientSession:
14 |
15 | if isinstance(self._session, ClientSession) and not self._session.closed:
16 | return self._session
17 |
18 | ssl_context = ssl.create_default_context(cafile=certifi.where())
19 | connector = TCPConnector(ssl=ssl_context)
20 |
21 | self._session = ClientSession(connector=connector)
22 |
23 | return self._session
24 |
25 | def _delete_empty_fields(self, params: dict) -> None:
26 | for key, value in params.copy().items():
27 | if value is None:
28 | params.pop(key)
29 |
30 | async def _request(self, payment: str, method: str, url: str, **kwargs) -> dict:
31 | session = self._getsession()
32 |
33 | async with session.request(method, url, **kwargs) as response:
34 | await self._session.close()
35 | if response.status in [200, 201]:
36 | if payment in ["ruKassa"]:
37 | response = await response.json(content_type="text/html")
38 | elif payment in ['payok']:
39 | response = await response.json(content_type="text/plain")
40 | else:
41 | response = await response.json()
42 | else:
43 | try:
44 | return await self._checkexception(payment, await response.json())
45 | except:
46 | raise RequestError(
47 | f"{payment}. Response status: {response.status}. Text: {await response.text()}"
48 | )
49 | return response
50 |
51 | async def _checkexception(self, payment: str, response: dict) -> dict:
52 | if payment == "aaio":
53 | if response["type"] == "error":
54 | raise BadRequest("[AAIO] " + response["message"])
55 | elif payment == "crystalPay":
56 | if response["error"]:
57 | raise BadRequest("[CrystalPay] " + response["errors"][0])
58 | elif payment == "cryptoBot":
59 | if not response["ok"]:
60 | raise BadRequest("[CryptoBot] " + response["error"]["name"])
61 | elif payment == "lolz":
62 | if response.get("error"):
63 | raise BadRequest("[Lolzteam Market] " + response["error_description"])
64 | if response.get("errors"):
65 | raise BadRequest("[Lolzteam Market] " + response["errors"][0])
66 | elif payment == "ruKassa":
67 | if response.get("error"):
68 | raise BadRequest("[RuKassa] " + response["message"])
69 | elif payment == "freeKassa":
70 | if response["type"] == "error" and not response.get("description"):
71 | raise BadRequest("[FreeKassa] " + response["message"])
72 | elif payment == "cryptomus":
73 | if response.get('state') != 0:
74 | if response.get("errors"):
75 | raise BadRequest("[Cryptomus] " + str(response.get("errors")))
76 | else:
77 | raise BadRequest("[Cryptomus] " + str(response.get("message")))
78 | else:
79 | raise BadRequest("[Cryptomus] " + response.get("message"))
80 | elif payment == "xrocket":
81 | if not response.get("success"):
82 | text = f"[XRocket] {response.get('message')}"
83 | if response.get("errors"):
84 | text += ": \n"
85 | for error in response.get("errors"):
86 | text += f"Property: {error['property']} \nError: {error['error']}"
87 | raise BadRequest(text)
88 | else:
89 | raise BadRequest(f"[XRocket] Status code: {response.get('statusCode')}. Message: " + response.get("message"))
90 | else:
91 | # payok
92 | if response.get("status") and response.pop("status") == "error":
93 | raise BadRequest("[PayOK] " + response.get("text", response.get("error_text")) + ". Error code: " + response['error_code'])
94 |
95 | return response
96 |
--------------------------------------------------------------------------------
/AsyncPayments/ruKassa/__init__.py:
--------------------------------------------------------------------------------
1 | from .api import AsyncRuKassa
--------------------------------------------------------------------------------
/AsyncPayments/ruKassa/api.py:
--------------------------------------------------------------------------------
1 | from ..requests import RequestsClient
2 | from typing import Optional, Union
3 | from .models import Balance, CreatePayment, Payment, CreateWithdrawRequest, CancelWithdrawRequest, WithdrawRequest, RevokePayment
4 | import time
5 | import secrets
6 | import random
7 |
8 |
9 | class AsyncRuKassa(RequestsClient):
10 | API_HOST: str = "https://ruks.pro"
11 |
12 | def __init__(self, api_token: str, shop_id: int, email: str, password: str) -> None:
13 | """
14 | Initialize RuKassa API client
15 | :param api_token: Your RuKassa API-Token
16 | :param shop_id: Your RuKassa ShopID
17 | :param email: Your Email, which you pointed to RuKassa
18 | :param password: Your Password, which you pointed to RuKassa
19 | """
20 | super().__init__()
21 | self.__token = api_token
22 | self.__shop_id = shop_id
23 | self.__email = email
24 | self.__password = password
25 | self.__base_url = "https://lk.rukassa.pro/api/v1"
26 | self.__post_method = "POST"
27 | self.__payment_name = "ruKassa"
28 | self.check_values()
29 |
30 | def check_values(self):
31 | if not self.__token or not self.__shop_id or not self.__email or not self.__password:
32 | raise ValueError('No Api-Token, ShopID, Email or Password specified')
33 |
34 | async def get_balance(self) -> Balance:
35 | """Get User Balance
36 |
37 | :return: Balance Object"""
38 |
39 | url = f'{self.__base_url}/getBalance'
40 |
41 | params = {
42 | "email": self.__email,
43 | "password": self.__password,
44 | }
45 |
46 | response = await self._request(self.__payment_name, self.__post_method, url, data=params)
47 |
48 | return Balance(**response)
49 |
50 | def __get_random_string(self):
51 | return f'{time.time()}_{secrets.token_hex(random.randint(5, 10))}'
52 |
53 | async def create_payment(self, amount: Union[int, float], currency: Optional[str] = "RUB",
54 | method: Optional[str] = None, data: Optional[str] = None,
55 | orderId: Optional[int] = None, userCode: Optional[str] = None) -> CreatePayment:
56 | """Create a payment
57 |
58 | :param amount: Amount of payment.
59 | :param currency: Optional. In what currency are you specifying the amount parameter? Default RUB. Currencies: RUB, USD
60 | :param method: Optional. Payment method, if you want payment to be made through a specific method. Methods: card, card_byn, card_kzt, card_uah, card_uzs, qiwi, yandexmoney, payeer, crypta, sbp,
61 | :param data: Optional. String sent to the server along with a notification of a successful payment.
62 | :param orderId: Optional. A unique payment number in your system. If not specified, a random string will be generated.
63 | :param userCode: Optional. For H2H, Anti-Fraud is required. Client ID (you can use the user's IP address or Telegram ID).
64 |
65 | :return: CreatePayment object
66 | """
67 |
68 | url = f'{self.__base_url}/create'
69 |
70 | if not orderId:
71 | orderId = self.__get_random_string()
72 |
73 | params = {
74 | "shop_id": self.__shop_id,
75 | "order_id": orderId,
76 | "amount": amount,
77 | "token": self.__token,
78 | "data": data,
79 | "method": method,
80 | "currency": currency,
81 | "user_code": userCode,
82 | }
83 |
84 | for key, value in params.copy().items():
85 | if value is None:
86 | params.pop(key)
87 |
88 | response = await self._request(self.__payment_name, self.__post_method, url, data=params)
89 |
90 | return CreatePayment(**response)
91 |
92 | async def revoke_payment(self, payment_id: int) -> RevokePayment:
93 | """
94 | Revoke payment
95 |
96 | :param payment_id: Payment ID in our system.
97 | :return: RevokePayment object
98 | """
99 | url = f"{self.__base_url}/revoke"
100 | params = {
101 | "id": payment_id,
102 | "shop_id": self.__shop_id,
103 | "token": self.__token,
104 | }
105 | response = await self._request(self.__payment_name, self.__post_method, url, data=params)
106 | return RevokePayment(**response)
107 |
108 | async def get_info_payment(self, payment_id: int) -> Payment:
109 | """
110 | Get payment information
111 |
112 | :param payment_id: Transaction (entry) number in our system.
113 |
114 | :return: Payment object
115 | """
116 |
117 | url = f"{self.__base_url}/getPayInfo"
118 |
119 | params = {
120 | "id": payment_id,
121 | "shop_id": self.__shop_id,
122 | "token": self.__token,
123 | }
124 |
125 | response = await self._request(self.__payment_name, self.__post_method, url, data=params)
126 |
127 | return Payment(**response)
128 |
129 | async def create_withdraw(self, way: str, wallet: str, amount: Union[float, int], orderId: str = None,
130 | check_from: Optional[str] = "BASE_RUB", who_fee: Optional[int] = 0,
131 | bank: Optional[int] = None) -> CreateWithdrawRequest:
132 | """
133 | Create withdraw request
134 |
135 | :param way: Payment system for withdrawal. Systems: CARD, QIWI, YOOMONEY, USDT, SBP.
136 | :param wallet: The number of the wallet or card where the funds will be sent.
137 | :param amount: Amount to withdraw.
138 | :param orderId: ID in the merchant system.
139 | :param check_from: Account for debiting funds. Default: BASE_RUB. (BASE_RUB, BASE_USD).
140 | :param who_fee: Where to write off the commission. Default: 0. (0 - from account, 1 - from balance).
141 | :param bank: Only for SBP. Bank number.
142 |
143 | :return: CreateWithdrawRequest object
144 | """
145 |
146 | url = f"{self.__base_url}/createWithdraw"
147 |
148 | params = {
149 | "email": self.__email,
150 | "password": self.__password,
151 | "way": way,
152 | "wallet": wallet,
153 | "amount": amount,
154 | "order_id": orderId,
155 | "from": check_from,
156 | "who_fee": who_fee,
157 | "bank": bank,
158 | }
159 |
160 | response = await self._request(self.__payment_name, self.__post_method, url, data=params)
161 |
162 | return CreateWithdrawRequest(**response)
163 |
164 | async def cancel_withdraw(self, payment_id: int) -> CancelWithdrawRequest:
165 | """
166 | Cancel withdraw request
167 |
168 | :param payment_id: Payment ID in our system.
169 |
170 | :return: CancelWithdrawRequest object
171 | """
172 |
173 | url = f"{self.__base_url}/cancelWithdraw"
174 |
175 | params = {
176 | "email": self.__email,
177 | "password": self.__password,
178 | "id": payment_id,
179 | }
180 |
181 | response = await self._request(self.__payment_name, self.__post_method, url, data=params)
182 |
183 | return CancelWithdrawRequest(**response)
184 |
185 | async def get_info_withdraw(self, payment_id: int) -> WithdrawRequest:
186 | """
187 | Get info about withdraw request
188 |
189 | :param payment_id: The number of the operation (withdrawal) in our system.
190 |
191 | :return: WithdrawRequest object
192 | """
193 |
194 | url = f"{self.__base_url}/getWithdrawInfo"
195 |
196 | params = {
197 | "token": self.__token,
198 | "shop_id": self.__shop_id,
199 | "id": payment_id,
200 | }
201 |
202 | response = await self._request(self.__payment_name, self.__post_method, url, data=params)
203 |
204 | return WithdrawRequest(**response)
205 |
--------------------------------------------------------------------------------
/AsyncPayments/ruKassa/models.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel
2 | from typing import Union, Optional
3 |
4 |
5 | class Balance(BaseModel):
6 | balance_rub: float
7 | balance_usd: float
8 |
9 |
10 | class CreatePayment(BaseModel):
11 | id: int
12 | hash: str
13 | url: str
14 |
15 |
16 | class Payment(BaseModel):
17 | id: int
18 | order_id: Union[int, str]
19 | in_amount: Optional[float] = None
20 | amount: float
21 | currency: str
22 | status: str
23 | data: str
24 |
25 |
26 | class RevokePayment(BaseModel):
27 | id: int
28 |
29 |
30 | class CreateWithdrawRequest(BaseModel):
31 | id: int
32 | status: str
33 |
34 |
35 | class CancelWithdrawRequest(BaseModel):
36 | id: int
37 | status: str
38 |
39 |
40 | class WithdrawRequest(BaseModel):
41 | id: int
42 | order_id: Union[int, str]
43 | amount: float
44 | fee: Optional[float] = None
45 | way: str
46 | who_fee: str
47 | status: str
48 |
--------------------------------------------------------------------------------
/AsyncPayments/xrocket/__init__.py:
--------------------------------------------------------------------------------
1 | from .api import AsyncXRocket
--------------------------------------------------------------------------------
/AsyncPayments/xrocket/api.py:
--------------------------------------------------------------------------------
1 | from ..requests import RequestsClient
2 | from typing import Optional, List
3 | from .models import AppInfo, Transfer, Withdrawal, WithdrawalFees, MultiCheque, MultiChequesList, Invoice, InvoicesList, Currency, \
4 | Subscription, SubscriptionsList, SubscriptionCheck, Subscriptions
5 | from urllib.parse import urlencode
6 |
7 |
8 | class AsyncXRocket(RequestsClient):
9 | API_HOST: str = "https://t.me/tonRocketBot"
10 |
11 | def __init__(self, apiKey: str) -> None:
12 | """
13 | Initialize XRocket API client
14 | :param apiKey: Your API key
15 | """
16 | super().__init__()
17 | self.__api_key = apiKey
18 | self.__headers = {
19 | "Content-Type": "application/json",
20 | "Rocket-Pay-Key": self.__api_key,
21 | }
22 | self.__base_url = "https://pay.xrocket.tg"
23 | self.__post_method = "POST"
24 | self.__get_method = "GET"
25 | self.__put_method = "PUT"
26 | self.__delete_method = "DELETE"
27 | self.__payment_name = "xrocket"
28 | self.check_values()
29 |
30 | def check_values(self):
31 | if not self.__api_key:
32 | raise ValueError('No API key specified')
33 |
34 | async def get_app_info(self) -> AppInfo:
35 | """Returns information about your application.
36 |
37 | Docs: https://pay.xrocket.tg/api/#/app/AppsController_getAppInfo"""
38 | url = f"{self.__base_url}/app/info"
39 | response = await self._request(self.__payment_name, self.__get_method, url, headers=self.__headers)
40 | return AppInfo(**response['data'])
41 |
42 | async def transfer(self, tgUserId: int, currency: str, amount: float, transferId: str, description: Optional[str] = "") -> Transfer:
43 | """Make transfer of funds to another user.
44 |
45 | :param tgUserId: Telegram user ID. If we dont have this user in DB, we will fail transaction with error: 400 - User not found.
46 | :param currency: Currency of transfer, info with function get_available_currencies().
47 | :param amount: Transfer amount. 9 decimal places, others cut off.
48 | :param transferId: Unique transfer ID in your system to prevent double spends.
49 | :description: Transfer description.
50 |
51 | Docs: https://pay.xrocket.tg/api/#/app/AppsController_transfer"""
52 | url = f"{self.__base_url}/app/transfer"
53 | params = {
54 | "tgUserId": tgUserId,
55 | "currency": currency,
56 | "amount": amount,
57 | "transferId": transferId,
58 | "description": description,
59 | }
60 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, json=params)
61 | return Transfer(**response['data'])
62 |
63 | async def withdrawal(self, network: str, address: str, currency: str, amount: float, withdrawalId: str, comment: Optional[str] = "") -> Withdrawal:
64 | """Make withdrawal of funds to external wallet.
65 |
66 | :param network: Network code.
67 | :param address: Withdrawal address.
68 | :param currency: Currency code.
69 | :param amount: Withdrawal amount. 9 decimal places, others cut off.
70 | :param withdrawalId: Unique withdrawal ID in your system to prevent double spends.
71 | :param comment: Withdrawal comment.
72 |
73 | Docs: https://pay.xrocket.tg/api/#/app/AppsController_withdrawal"""
74 | url = f"{self.__base_url}/app/withdrawal"
75 | params = {
76 | "network": network,
77 | "address": address,
78 | "currency": currency,
79 | "amount": amount,
80 | "withdrawalId": withdrawalId,
81 | "comment": comment,
82 | }
83 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, json=params)
84 | return Withdrawal(**response['data'])
85 |
86 | async def withdrawal_status(self, withdrawalId: str) -> Withdrawal:
87 | """Returns withdrawal status.
88 |
89 | Docs: https://pay.xrocket.tg/api/#/app/AppsController_getWithdrawalStatus"""
90 | url = f"{self.__base_url}/app/withdrawal/status/{withdrawalId}"
91 | response = await self._request(self.__payment_name, self.__get_method, url, headers=self.__headers)
92 | return Withdrawal(**response['data'])
93 |
94 | async def withdrawal_fees(self, currency: Optional[str] = None) -> List[WithdrawalFees]:
95 | """Returns withdrawal fees.
96 |
97 | Docs: https://pay.xrocket.tg/api/#/app/AppsController_getWithdrawalFees"""
98 | url = f"{self.__base_url}/app/withdrawal/fees"
99 | params = {
100 | "currency": currency,
101 | }
102 | self._delete_empty_fields(params)
103 | response = await self._request(self.__payment_name, self.__get_method, url, headers=self.__headers, json=params)
104 | return [WithdrawalFees(**withdrawalFee) for withdrawalFee in response['data']]
105 |
106 | async def create_multi_cheque(self, currency: str, chequePerUser: float, usersNumber: int, refProgram: int, password: Optional[str] = None,
107 | description: Optional[str] = None, sendNotifications: Optional[bool] = True, enableCaptcha: Optional[bool] = True,
108 | telegramResourcesIds: Optional[List[str]] = [], forPremium: Optional[bool] = False, linkedWallet: Optional[bool] = False,
109 | disabledLanguages: Optional[List[str]] = [], enabledCountries: Optional[List[str]] = []) -> MultiCheque:
110 | """Create multi-cheque.
111 |
112 | :param currency: Currency of transfer, info with function get_available_currencies().
113 | :param chequePerUser: Cheque amount for one user. 9 decimal places, others cut off.
114 | :param usersNumber: Number of users to save multicheque. 0 decimal places.
115 | :param refProgram: Referral program percentage (%). 0 decimal places.
116 | :param password: Password for cheque.
117 | :param description: Description for cheque.
118 | :param sendNotifications: Send notifications about activations.
119 | :param enableCaptcha: Enable captcha.
120 | :param telegramResourcesIds: IDs of telegram resources (groups, channels, private groups).
121 | :param forPremium: Only users with Telegram Premium can activate this cheque.
122 | :param linkedWallet: Only users with linked wallet can activate this cheque.
123 | :param disabledLanguages: Disable languages.
124 | :param enabledCountries: Enabled countries (AsyncPayments.xrocket.models.CountriesName).
125 |
126 | Docs: https://pay.xrocket.tg/api/#/multi-cheque/ChequesController_createCheque"""
127 | url = f"{self.__base_url}/multi-cheque"
128 | params = {
129 | "currency": currency,
130 | "chequePerUser": chequePerUser,
131 | "usersNumber": usersNumber,
132 | "refProgram": refProgram,
133 | "password": password,
134 | "description": description,
135 | "sendNotifications": sendNotifications,
136 | "enableCaptcha": enableCaptcha,
137 | "telegramResourcesIds": telegramResourcesIds,
138 | "forPremium": forPremium,
139 | "linkedWallet": linkedWallet,
140 | "disabledLanguages": disabledLanguages,
141 | "enabledCountries": enabledCountries,
142 | }
143 | self._delete_empty_fields(params)
144 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, json=params)
145 | return MultiCheque(**response['data'])
146 |
147 | async def multi_cheques_list(self, limit: Optional[int] = 100, offset: Optional[int] = 0) -> MultiChequesList:
148 | """Get list of multi-cheques.
149 |
150 | :param limit: Limit of cheques.
151 | :param offset: Offset.
152 |
153 | Docs: https://pay.xrocket.tg/api/#/multi-cheque/ChequesController_getCheques"""
154 | params = {
155 | "limit": limit,
156 | "offset": offset,
157 | }
158 | url = f"{self.__base_url}/multi-cheque?{urlencode(params)}"
159 | response = await self._request(self.__payment_name, self.__get_method, url, headers=self.__headers)
160 | return MultiChequesList(**response['data'])
161 |
162 | async def get_multi_cheque_info(self, cheque_id: int) -> MultiCheque:
163 | """Get multi-cheque info.
164 |
165 | :param cheque_id: ID of cheque.
166 |
167 | Docs: https://pay.xrocket.tg/api/#/multi-cheque/ChequesController_getCheque"""
168 | url = f"{self.__base_url}/multi-cheque/{cheque_id}"
169 | response = await self._request(self.__payment_name, self.__get_method, url, headers=self.__headers)
170 | return MultiCheque(**response['data'])
171 |
172 | async def edit_multi_cheque(self, cheque_id: int, password: Optional[str] = None, description: Optional[str] = None,
173 | sendNotifications: Optional[bool] = None, enableCaptcha: Optional[bool] = None,
174 | telegramResourcesIds: Optional[List[str]] = None, forPremium: Optional[bool] = None,
175 | linkedWallet: Optional[bool] = None, disabledLanguages: Optional[List[str]] = None,
176 | enabledCountries: Optional[List[str]] = None) -> MultiCheque:
177 | """Edit multi-cheque.
178 |
179 | :param cheque_id: ID of cheque.
180 | :param password: Password for cheque.
181 | :param description: Description for cheque.
182 | :param sendNotifications: Send notifications about activations.
183 | :param enableCaptcha: Enable captcha.
184 | :param telegramResourcesIds: IDs of telegram resources (groups, channels, private groups).
185 | :param forPremium: Only users with Telegram Premium can activate this cheque.
186 | :param linkedWallet: Only users with linked wallet can activate this cheque.
187 | :param disabledLanguages: Disable languages.
188 | :param enabledCountries: Enabled countries (AsyncPayments.xrocket.models.CountriesName).
189 |
190 |
191 | Docs: https://pay.xrocket.tg/api/#/multi-cheque/ChequesController_editCheque"""
192 | params = {
193 | "password": password,
194 | "description": description,
195 | "sendNotifications": sendNotifications,
196 | "enableCaptcha": enableCaptcha,
197 | "telegramResourcesIds": telegramResourcesIds,
198 | "forPremium": forPremium,
199 | "linkedWallet": linkedWallet,
200 | "disabledLanguages": disabledLanguages,
201 | "enabledCountries": enabledCountries,
202 | }
203 | self._delete_empty_fields(params)
204 | url = f"{self.__base_url}/multi-cheque/{cheque_id}"
205 | response = await self._request(self.__payment_name, self.__put_method, url, headers=self.__headers, json=params)
206 | return MultiCheque(**response['data'])
207 |
208 | async def delete_multi_cheque(self, cheque_id: int) -> bool:
209 | """Delete multi-cheque.
210 |
211 | :param cheque_id: ID of cheque.
212 |
213 | Docs: https://pay.xrocket.tg/api/#/multi-cheque/ChequesController_deleteCheque"""
214 | url = f"{self.__base_url}/multi-cheque/{cheque_id}"
215 | response = await self._request(self.__payment_name, self.__delete_method, url, headers=self.__headers)
216 | return True if response['success'] else False
217 |
218 | async def create_invoice(self, numPayments: int, currency: str, amount: Optional[float] = None, minPayment: Optional[int] = None,
219 | description: Optional[str] = None, hiddenMessage: Optional[str] = None, commentsEnabled: Optional[bool] = None,
220 | callbackUrl: Optional[str] = None, payload: Optional[str] = None, expiredIn: Optional[int] = None) -> Invoice:
221 | """Create invoice.
222 |
223 | :param numPayments: Num payments for invoice.
224 | :param currency: Currency of transfer, info with function get_available_currencies().
225 | :param amount: Invoice amount. 9 decimal places, others cut off.
226 | :param minPayment: Min payment only for multi invoice if invoice amount is None.
227 | :param description: Description for invoice.
228 | :param hiddenMessage: Hidden message after invoice is paid.
229 | :param commentsEnabled: Allow comments.
230 | :param callbackUrl: Url for Return button after invoice is paid.
231 | :param payload: Any data. Invisible to user, will be returned in callback.
232 | :param expiredIn: Invoice expire time in seconds, max 1 day, 0 - None expired.
233 |
234 | Docs: https://pay.xrocket.tg/api/#/tg-invoices/InvoicesController_createInvoice"""
235 | params = {
236 | "numPayments": numPayments,
237 | "currency": currency,
238 | "amount": amount,
239 | "minPayment": minPayment,
240 | "description": description,
241 | "hiddenMessage": hiddenMessage,
242 | "commentsEnabled": commentsEnabled,
243 | "callbackUrl": callbackUrl,
244 | "payload": payload,
245 | "expiredIn": expiredIn,
246 | }
247 | self._delete_empty_fields(params)
248 | url = f"{self.__base_url}/tg-invoices"
249 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, json=params)
250 | return Invoice(**response['data'])
251 |
252 | async def get_list_invoices(self, limit: Optional[int] = 100, offset: Optional[int] = 0) -> InvoicesList:
253 | """Get list of invoices.
254 |
255 | :param limit: Limit of invoices.
256 | :param offset: Offset.
257 |
258 | Docs: https://pay.xrocket.tg/api/#/tg-invoices/InvoicesController_getInvoices"""
259 | params = {
260 | "limit": limit,
261 | "offset": offset,
262 | }
263 | url = f"{self.__base_url}/tg-invoices?{urlencode(params)}"
264 | response = await self._request(self.__payment_name, self.__get_method, url, headers=self.__headers)
265 | return InvoicesList(**response['data'])
266 |
267 | async def get_invoice_info(self, invoice_id: str) -> Invoice:
268 | """Get invoice info.
269 |
270 | :param invoice_id: ID of invoice.
271 |
272 | Docs: https://pay.xrocket.tg/api/#/tg-invoices/InvoicesController_getInvoice"""
273 | url = f"{self.__base_url}/tg-invoices/{invoice_id}"
274 | response = await self._request(self.__payment_name, self.__get_method, url, headers=self.__headers)
275 | return Invoice(**response['data'])
276 |
277 | async def delete_invoice(self, invoice_id: str) -> bool:
278 | """Delete invoice.
279 |
280 | :param invoice_id: ID of invoice.
281 |
282 | Docs: https://pay.xrocket.tg/api/#/tg-invoices/InvoicesController_deleteInvoice"""
283 | url = f"{self.__base_url}/tg-invoices/{invoice_id}"
284 | response = await self._request(self.__payment_name, self.__delete_method, url, headers=self.__headers)
285 | return True if response['success'] else False
286 |
287 | async def get_challenge(self, challenge_id: str, user_id: str) -> str:
288 | """Get challenge amount by user id.
289 |
290 | :param challenge_id: ID of the challenge.
291 | :param user_id: Telegram ID of the user.
292 |
293 | Docs: https://pay.xrocket.tg/api/#/challenges/ChallengesController_getTradeAmount
294 |
295 | :return: Amount in USD."""
296 | url = f"{self.__base_url}/challenges/{challenge_id}/users/{user_id}"
297 | response = await self._request(self.__payment_name, self.__get_method, url, headers=self.__headers)
298 | return response['data']['amountUsd']
299 |
300 | async def get_available_currencies(self) -> List[Currency]:
301 | """Returns available currencies.
302 |
303 | Docs: https://pay.xrocket.tg/api/#/currencies/CurrenciesController_getCoins"""
304 | url = f"{self.__base_url}/currencies/available"
305 | response = await self._request(self.__payment_name, self.__get_method, url, headers=self.__headers)
306 | return [Currency(**currency) for currency in response['data']['results']]
307 |
308 | async def create_subscription(self, interval: str, amount: float, status: str, referralPercent: int, currency: str, name: Optional[str] = None,
309 | description: Optional[str] = None, tgResource: Optional[str] = None, returnUrl: Optional[str] = None) -> Subscription:
310 | """Create subscription.
311 |
312 | :param interval: Interval for subscription (AsyncPayments.xrocket.models.SubscriptionsIntervals).
313 | :param amount: Cost subscription for current interval in currency.
314 | :param status: Status for subscription (AsyncPayments.xrocket.models.SubscriptionsStatuses).
315 | :param referralPercent: Subscription referral percent.
316 | :param currency: Subscription currency.
317 | :param name: Subscription name, view in bot.
318 | :param description: Subscription description, view in bot.
319 | :param tgResource: Subscription TG resource.
320 | :param returlUrl: Return link after payment.
321 |
322 | Docs: https://pay.xrocket.tg/api/#/subscriptions/SubscriptionsController_createSubscription"""
323 | params = {
324 | "name": name,
325 | "description": description,
326 | "currency": currency,
327 | "interval": [
328 | {
329 | "interval": interval,
330 | "amount": amount,
331 | "status": status
332 | }
333 | ],
334 | "tgResource": tgResource,
335 | "referralPercent": referralPercent,
336 | "returnUrl": returnUrl
337 | }
338 | self._delete_empty_fields(params)
339 | url = f"{self.__base_url}/subscriptions"
340 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers)
341 | return Subscription(**response['data'])
342 |
343 | async def get_list_subscriptions(self, limit: Optional[int] = 100, offset: Optional[int] = 0) -> SubscriptionsList:
344 | """Get list of subscription.
345 |
346 | :param limit: Limit of subscriptions.
347 | :param offset: Offset.
348 |
349 | Docs: https://pay.xrocket.tg/api/#/subscriptions/SubscriptionsController_getSubscriptions"""
350 | params = {
351 | "limit": limit,
352 | "offset": offset,
353 | }
354 | url = f"{self.__base_url}/subscriptions?{urlencode(params)}"
355 | response = await self._request(self.__payment_name, self.__get_method, url, headers=self.__headers)
356 | return SubscriptionsList(**response['data'])
357 |
358 | async def get_subscription_info(self, subscription_id: int) -> Subscription:
359 | """Get subscription info.
360 |
361 | :param subscription_id: ID of the subscription.
362 |
363 | Docs: https://pay.xrocket.tg/api/#/subscriptions/SubscriptionsController_getSubscription"""
364 | url = f"{self.__base_url}/subscriptions/{subscription_id}"
365 | response = await self._request(self.__payment_name, self.__get_method, url, headers=self.__headers)
366 | return Subscription(**response['data'])
367 |
368 | async def delete_subscription(self, subscription_id: int) -> bool:
369 | """Delete subscription.
370 |
371 | :param subscription_id: ID of the subscription.
372 |
373 | Docs: https://pay.xrocket.tg/api/#/subscriptions/SubscriptionsController_deleteSubscription"""
374 | url = f"{self.__base_url}/subscriptions/{subscription_id}"
375 | response = await self._request(self.__payment_name, self.__delete_method, url, headers=self.__headers)
376 | return True if response['success'] else False
377 |
378 | async def check_subscription(self, subscription_id: int, user_id: int) -> SubscriptionCheck:
379 | """Delete subscription.
380 |
381 | :param subscription_id: ID of the subscription.
382 | :param user_id: ID of the user.
383 |
384 | Docs: https://pay.xrocket.tg/api/#/subscriptions/SubscriptionsController_checkSubscription"""
385 | params = {
386 | "userId": user_id,
387 | }
388 | url = f"{self.__base_url}/subscriptions/check/{subscription_id}"
389 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers, json=params)
390 | return SubscriptionCheck(**response['data'])
391 |
392 | async def get_subscription_interval_info(self, subscription_id: int, interval_code: str) -> Subscriptions.Interval:
393 | """Get subscription interval info.
394 |
395 | :param subscription_id: ID of the subscription.
396 | :param interval_code: Code of the interval.
397 |
398 | Docs: https://pay.xrocket.tg/api/#/subscriptions/SubscriptionsController_getSubscriptionInterval"""
399 | url = f"{self.__base_url}/subscriptions/{subscription_id}/interval/{interval_code}"
400 | response = await self._request(self.__payment_name, self.__get_method, url, headers=self.__headers)
401 | return Subscriptions.Interval(**response['data'])
402 |
403 | async def edit_subscription_interval(self, subscription_id: int, interval_code: str, status: str) -> Subscriptions.Interval:
404 | """Edit subscription interval.
405 |
406 | :param subscription_id: ID of the subscription.
407 | :param interval_code: Code of the interval.
408 | :param status: Status for subscription (AsyncPayments.xrocket.models.SubscriptionsStatuses).
409 |
410 | Docs: https://pay.xrocket.tg/api/#/subscriptions/SubscriptionsController_editSubscriptionInterval"""
411 | params = {
412 | "status": status
413 | }
414 | url = f"{self.__base_url}/subscriptions/{subscription_id}/interval/{interval_code}"
415 | response = await self._request(self.__payment_name, self.__put_method, url, headers=self.__headers, json=params)
416 | return Subscriptions.Interval(**response['data'])
417 |
418 | async def delete_subscription_interval(self, subscription_id: int, interval_code: str) -> Subscriptions.Interval:
419 | """Delete subscription interval.
420 |
421 | :param subscription_id: ID of the subscription.
422 | :param interval_code: Code of the interval.
423 |
424 | Docs: https://pay.xrocket.tg/api/#/subscriptions/SubscriptionsController_deleteSubscriptionInterval"""
425 | url = f"{self.__base_url}/subscriptions/{subscription_id}/interval/{interval_code}"
426 | response = await self._request(self.__payment_name, self.__delete_method, url, headers=self.__headers)
427 | return Subscriptions.Interval(**response['data'])
428 |
429 | async def create_subscription_interval(self, subscription_id: int, interval: str, amount: float, status: str) -> Subscriptions.Interval:
430 | """Create subscription interval.
431 |
432 | :param subscription_id: ID of the subscription.
433 | :param interval: Interval for subscription (AsyncPayments.xrocket.models.SubscriptionsIntervals).
434 | :param amount: Cost subscription for current interval in currency.
435 | :param status: Status for subscription (AsyncPayments.xrocket.models.SubscriptionsStatuses).
436 |
437 | Docs: https://pay.xrocket.tg/api/#/subscriptions/SubscriptionsController_creteSubscriptionInterval"""
438 | params = {
439 | "interval": interval,
440 | "amount": amount,
441 | "status": status,
442 | }
443 | url = f"{self.__base_url}/subscriptions/{subscription_id}"
444 | response = await self._request(self.__payment_name, self.__post_method, url, headers=self.__headers)
445 | return Subscriptions.Interval(**response['data'])
--------------------------------------------------------------------------------
/AsyncPayments/xrocket/models.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel, Field
2 | from typing import Optional, Union, List
3 |
4 |
5 | class Balance(BaseModel):
6 | currency: str
7 | balance: Union[int, float]
8 |
9 |
10 | class AppInfo(BaseModel):
11 | name: str
12 | feePercents: Union[int, float]
13 | balances: List[Balance]
14 |
15 |
16 | class Transfer(BaseModel):
17 | id: int
18 | tgUserId: int
19 | currency: str
20 | amount: Union[int, float]
21 | description: str
22 |
23 |
24 | class Withdrawal(BaseModel):
25 | network: str
26 | address: str
27 | currency: str
28 | amount: Union[int, float]
29 | withdrawalId: str
30 | status: str
31 | comment: str
32 | txHash: str
33 | txLink: str
34 |
35 |
36 | class FeeWithdraw(BaseModel):
37 | fee: Optional[float] = None
38 | currency: str
39 |
40 |
41 | class Fee(BaseModel):
42 | networkCode: str
43 | feeWithdraw: FeeWithdraw
44 |
45 |
46 | class WithdrawalFees(BaseModel):
47 | code: str
48 | minWithdraw: float
49 | fees: List[Fee]
50 |
51 |
52 | class MultiCheque(BaseModel):
53 | id: int
54 | currency: str
55 | total: int
56 | perUser: int
57 | users: int
58 | password: str
59 | description: str
60 | sendNotifications: bool
61 | captchaEnabled: bool
62 | refProgramPercents: int
63 | refRewardPerUser: float
64 | state: str
65 | link: str
66 | disabledLanguages: list
67 | enabledCountries: list
68 | forPremium: int
69 | forNewUsersOnly: int
70 | linkedWallet: int
71 | tgResources: Optional[list] = None
72 | activations: Optional[int] = None
73 | refRewards: Optional[int] = None
74 |
75 |
76 | class MultiChequesList(BaseModel):
77 | total: int
78 | limit: int
79 | offset: int
80 | results: List[MultiCheque]
81 |
82 |
83 | class InvoicePayment(BaseModel):
84 | userId: int
85 | paymentNum: int
86 | paymentAmount: int
87 | comment: str
88 | paid: str
89 |
90 |
91 | class Invoice(BaseModel):
92 | id: str
93 | amount: Union[float, int]
94 | minPayment: Optional[Union[float, int]] = None
95 | totalActivations: int
96 | activationsLeft: int
97 | description: Optional[str] = None
98 | hiddenMessage: Optional[str] = None
99 | payload: Optional[str] = None
100 | callbackUrl: Optional[str] = None
101 | commentsEnabled: Union[bool, int]
102 | currency: str
103 | created: Optional[str] = None
104 | paid: Optional[str] = None
105 | status: str
106 | expiredIn: int
107 | link: str
108 | payments: Optional[List[InvoicePayment]] = []
109 |
110 |
111 | class InvoicesList(BaseModel):
112 | total: int
113 | limit: int
114 | offset: int
115 | results: List[Invoice]
116 |
117 |
118 | class Currency(BaseModel):
119 | currency: str
120 | name: str
121 | minTransfer: Union[float, int]
122 | minCheque: Union[float, int]
123 | minInvoice: Union[float, int]
124 | minWithdraw: Union[float, int]
125 | feeWithdraw: dict
126 |
127 |
128 | class Subscriptions:
129 | class Interval(BaseModel):
130 | interval: str
131 | amount: Union[float, int]
132 | status: str
133 | code: str
134 |
135 | class tgResource(BaseModel):
136 | id: int
137 | type_: str = Field(alias="type")
138 | resourceId: str
139 | name: str
140 | linkedChat: str
141 |
142 |
143 | class Subscription(BaseModel):
144 | id: int
145 | name: str
146 | description: str
147 | currency: str
148 | link: str
149 | interval: Subscriptions.Interval
150 | referralPercent: int
151 | returnUrl: str
152 | tgResource: Subscriptions.tgResource
153 |
154 |
155 | class SubscriptionsList(BaseModel):
156 | total: int
157 | limit: int
158 | offset: int
159 | results: List[Subscription]
160 |
161 |
162 | class SubscriptionCheck(BaseModel):
163 | subscriptionId: int
164 | subscriptionCode: str
165 | userId: int
166 | amount: Union[float, int]
167 | currency: str
168 | interval: str
169 | refFee: Union[float, int]
170 | isRefPay: bool
171 | totalAmount: Union[float, int]
172 | paymentStart: str
173 | paymentEnd: str
174 | autoRenewal: bool
175 | transactions: list
176 |
177 |
178 | class SubscriptionsStatutes:
179 | ACTIVE = "ACTIVE"
180 | ARCHIVE = "ARCHIVE"
181 | DELETED = "DELETED"
182 |
183 |
184 | class SubscriptionsIntervals:
185 | DAY = "DAY"
186 | WEEK = "WEEK"
187 | MONTH = "MONTH"
188 | YEAR = "YEAR"
189 | FOREVER = "FOREVER"
190 |
191 |
192 | class InvoiceStatutes:
193 | ACTIVE = "active"
194 | PAID = "paid"
195 | EXPIRED = "expired"
196 |
197 |
198 | class CountriesName:
199 | DZ: str = "DZ"
200 | AO: str = "AO"
201 | BJ: str = "BJ"
202 | BW: str = "BW"
203 | BF: str = "BF"
204 | BI: str = "BI"
205 | CV: str = "CV"
206 | CM: str = "CM"
207 | CF: str = "CF"
208 | TD: str = "TD"
209 | KM: str = "KM"
210 | CG: str = "CG"
211 | CD: str = "CD"
212 | DJ: str = "DJ"
213 | EG: str = "EG"
214 | GQ: str = "GQ"
215 | ER: str = "ER"
216 | SZ: str = "SZ"
217 | ET: str = "ET"
218 | GA: str = "GA"
219 | GM: str = "GM"
220 | GH: str = "GH"
221 | GN: str = "GN"
222 | GW: str = "GW"
223 | CI: str = "CI"
224 | KE: str = "KE"
225 | LS: str = "LS"
226 | LR: str = "LR"
227 | LY: str = "LY"
228 | MG: str = "MG"
229 | MW: str = "MW"
230 | ML: str = "ML"
231 | MR: str = "MR"
232 | MU: str = "MU"
233 | MA: str = "MA"
234 | MZ: str = "MZ"
235 | NA: str = "NA"
236 | NE: str = "NE"
237 | NG: str = "NG"
238 | RW: str = "RW"
239 | ST: str = "ST"
240 | SN: str = "SN"
241 | SC: str = "SC"
242 | SL: str = "SL"
243 | SO: str = "SO"
244 | ZA: str = "ZA"
245 | SS: str = "SS"
246 | SD: str = "SD"
247 | TZ: str = "TZ"
248 | TG: str = "TG"
249 | TN: str = "TN"
250 | UG: str = "UG"
251 | ZM: str = "ZM"
252 | ZW: str = "ZW"
253 | AF: str = "AF"
254 | AM: str = "AM"
255 | AZ: str = "AZ"
256 | BH: str = "BH"
257 | BD: str = "BD"
258 | BT: str = "BT"
259 | BN: str = "BN"
260 | MM: str = "MM"
261 | KH: str = "KH"
262 | CN: str = "CN"
263 | CY: str = "CY"
264 | GE: str = "GE"
265 | IN: str = "IN"
266 | ID: str = "ID"
267 | IR: str = "IR"
268 | IQ: str = "IQ"
269 | IL: str = "IL"
270 | JP: str = "JP"
271 | JO: str = "JO"
272 | KZ: str = "KZ"
273 | KW: str = "KW"
274 | KG: str = "KG"
275 | LA: str = "LA"
276 | LB: str = "LB"
277 | MY: str = "MY"
278 | MV: str = "MV"
279 | MN: str = "MN"
280 | NP: str = "NP"
281 | KP: str = "KP"
282 | KR: str = "KR"
283 | OM: str = "OM"
284 | PK: str = "PK"
285 | PS: str = "PS"
286 | PH: str = "PH"
287 | QA: str = "QA"
288 | SA: str = "SA"
289 | SG: str = "SG"
290 | LK: str = "LK"
291 | SY: str = "SY"
292 | TW: str = "TW"
293 | TJ: str = "TJ"
294 | TH: str = "TH"
295 | TR: str = "TR"
296 | TM: str = "TM"
297 | AE: str = "AE"
298 | UZ: str = "UZ"
299 | VN: str = "VN"
300 | YE: str = "YE"
301 | AL: str = "AL"
302 | AD: str = "AD"
303 | AT: str = "AT"
304 | BY: str = "BY"
305 | BE: str = "BE"
306 | BA: str = "BA"
307 | BG: str = "BG"
308 | HR: str = "HR"
309 | CZ: str = "CZ"
310 | DK: str = "DK"
311 | EE: str = "EE"
312 | FI: str = "FI"
313 | FR: str = "FR"
314 | DE: str = "DE"
315 | GR: str = "GR"
316 | HU: str = "HU"
317 | IS: str = "IS"
318 | IE: str = "IE"
319 | IT: str = "IT"
320 | XK: str = "XK"
321 | LV: str = "LV"
322 | LI: str = "LI"
323 | LT: str = "LT"
324 | LU: str = "LU"
325 | MT: str = "MT"
326 | MD: str = "MD"
327 | MC: str = "MC"
328 | ME: str = "ME"
329 | NL: str = "NL"
330 | MK: str = "MK"
331 | NO: str = "NO"
332 | PL: str = "PL"
333 | PT: str = "PT"
334 | RO: str = "RO"
335 | RU: str = "RU"
336 | SM: str = "SM"
337 | RS: str = "RS"
338 | SK: str = "SK"
339 | SI: str = "SI"
340 | ES: str = "ES"
341 | SE: str = "SE"
342 | CH: str = "CH"
343 | UA: str = "UA"
344 | GB: str = "GB"
345 | VA: str = "VA"
346 | AG: str = "AG"
347 | BS: str = "BS"
348 | BB: str = "BB"
349 | BZ: str = "BZ"
350 | CA: str = "CA"
351 | CR: str = "CR"
352 | CU: str = "CU"
353 | DM: str = "DM"
354 | DO: str = "DO"
355 | SV: str = "SV"
356 | GD: str = "GD"
357 | GT: str = "GT"
358 | HT: str = "HT"
359 | HN: str = "HN"
360 | JM: str = "JM"
361 | MX: str = "MX"
362 | NI: str = "NI"
363 | PA: str = "PA"
364 | KN: str = "KN"
365 | LC: str = "LC"
366 | VC: str = "VC"
367 | TT: str = "TT"
368 | US: str = "US"
369 | AR: str = "AR"
370 | BO: str = "BO"
371 | BR: str = "BR"
372 | CL: str = "CL"
373 | CO: str = "CO"
374 | EC: str = "EC"
375 | GY: str = "GY"
376 | PY: str = "PY"
377 | PE: str = "PE"
378 | SR: str = "SR"
379 | UY: str = "UY"
380 | VE: str = "VE"
381 | AU: str = "AU"
382 | FJ: str = "FJ"
383 | KI: str = "KI"
384 | MH: str = "MH"
385 | FM: str = "FM"
386 | NR: str = "NR"
387 | NZ: str = "NZ"
388 | PW: str = "PW"
389 | PG: str = "PG"
390 | WS: str = "WS"
391 | SB: str = "SB"
392 | TO: str = "TO"
393 | TV: str = "TV"
394 | VU: str = "VU"
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 ToSa
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AsyncPayments
2 | 
3 | 
4 | 
5 |
6 | > Add payment acceptance to your projects.
7 | ## Installing
8 | pip install AsyncPayments
9 | ## Version
10 | v1.4.7
11 | ## Code example
12 |
13 | ```python
14 | import asyncio
15 |
16 | from AsyncPaymentsTest.ruKassa import AsyncRuKassa
17 | from AsyncPaymentsTest.lolz import AsyncLolzteamMarketPayment
18 | from AsyncPaymentsTest.aaio import AsyncAaio
19 | from AsyncPaymentsTest.cryptoBot import AsyncCryptoBot
20 | from AsyncPaymentsTest.crystalPay import AsyncCrystalPay
21 | from AsyncPaymentsTest.freeKassa import AsyncFreeKassa
22 | from AsyncPaymentsTest.payok import AsyncPayOK
23 | from AsyncPaymentsTest.cryptomus import AsyncCryptomus
24 | from AsyncPaymentsTest.xrocket import AsyncXRocket
25 |
26 | ruKassa = AsyncRuKassa(api_token="ApiToken", shop_id=1, email="Email", password="Password")
27 | lolz = AsyncLolzteamMarketPayment(token="Token")
28 | aaio = AsyncAaio(apikey="ApiKey", shopid="ShopID", secretkey="SecretKey")
29 | cryptoBot = AsyncCryptoBot(token="CryptoPayToken", is_testnet=False)
30 | crystalPay = AsyncCrystalPay(login="Login", secret="Secret", salt="Salt")
31 | freeKassa = AsyncFreeKassa(apiKey="ApiKey", shopId=1)
32 | payok = AsyncPayOK(apiKey="ApiKey", secretKey="SecretKey", apiId=1, shopId=1)
33 | cryptomus = AsyncCryptomus(payment_api_key="PaymentApiKey", merchant_id="MerchantID", payout_api_key="PayoutApiKey")
34 | xrocket = AsyncXRocket(apiKey="ApiKey")
35 |
36 |
37 | async def main():
38 | balance_payok = await payok.get_balance()
39 | balance_freekassa = await freeKassa.get_balance()
40 | balance_rukassa = await ruKassa.get_balance()
41 | balance_lolz = await lolz.get_me()
42 | balance_aaio = await aaio.get_balance()
43 | balance_crypto_bot = await cryptoBot.get_balance()
44 | balance_crystal_pay = await crystalPay.get_balance_list()
45 | balance_cryptomus = await cryptomus.get_balance()
46 | balance_xrocket = await xrocket.get_app_info()
47 |
48 | print("PayOK:")
49 | print("Balance: ", balance_payok.balance)
50 | print("Referral balance: ", balance_payok.ref_balance)
51 | print('--------------')
52 | print("FreeKassa:")
53 | for balance in balance_freekassa:
54 | print(f"{balance.currency}: ", balance.value)
55 | print('--------------')
56 | print("RuKassa:")
57 | print("RUB: ", balance_rukassa.balance_rub)
58 | print("USD: ", balance_rukassa.balance_usd)
59 | print('--------------')
60 | print("Lolz:")
61 | print('ID: ', balance_lolz.user_id)
62 | print('Nickname: ', balance_lolz.username)
63 | print('Available: ', balance_lolz.balance)
64 | print('In hold: ', balance_lolz.hold)
65 | print('--------------')
66 | print("Aaio:")
67 | print('Available: ', balance_aaio.balance)
68 | print('In hold: ', balance_aaio.hold)
69 | print('Referral balance: ', balance_aaio.referral)
70 | print('--------------')
71 | print("CryptoBot:")
72 | for balance in balance_crypto_bot:
73 | print(f"Available {balance.currency_code}: ", balance.available, f" (In hold: {balance.onhold})")
74 | print('--------------')
75 | print("CrystalPay:")
76 | for currency, balance in balance_crystal_pay:
77 | print(f"Available {currency}: {balance.amount} {balance.currency}")
78 | print('--------------')
79 | print("Cryptomus:")
80 | print("Merchant:\n")
81 | for balance in balance_cryptomus.merchant:
82 | print(
83 | f"Available {balance.currency_code}: {balance.balance} {balance.currency_code} ({balance.balance_usd} USD)")
84 | print("\nUser:\n")
85 | for balance in balance_cryptomus.user:
86 | print(
87 | f"Available {balance.currency_code}: {balance.balance} {balance.currency_code} ({balance.balance_usd} USD)")
88 | print('--------------')
89 | print('XRocket:')
90 | for bal in balance.balances:
91 | print(f"Available {bal.currency}: {bal.balance} {bal.currency}")
92 | print('------------------------------------------')
93 |
94 | order_payok = await payok.create_pay(15, "orderId")
95 | order_freeKassa = await freeKassa.create_order(1, "example@gmail.com", "0.0.0.0", 150, "RUB")
96 | order_ruKassa = await ruKassa.create_payment(15)
97 | order_lolz = await lolz.create_invoice(15, "paymentId", "comment", "https://example.com", 1)
98 | order_aaio = await aaio.create_payment_url(15, "orderId")
99 | order_crypto_bot = await cryptoBot.create_invoice(15, currency_type="crypto", asset="USDT")
100 | order_crystal_pay = await crystalPay.create_payment(15)
101 | order_cryptomus = await cryptomus.create_payment("15", "RUB", "orderId")
102 | order_xrocket = await xrocket.create_invoice(1, "TONCOIN", 1)
103 |
104 | print("PayOK", order_payok)
105 | print("FreeKassa", order_freeKassa.location)
106 | print("RuKassa: ", order_ruKassa.url)
107 | print("Lolz: ":, order_lolz.url)
108 | print("Aaio: ", order_aaio)
109 | print("CryptoBot: ", order_crypto_bot.pay_url)
110 | print("CrystalPay: ", order_crystal_pay.url)
111 | print("Cryptomus: ", order_cryptomus.url)
112 | print("XRocket: ", order_xrocket.link)
113 |
114 | print('------------------------------------------')
115 |
116 | info_payok = await payok.get_transactions("orderId")
117 | info_freeKassa = await freeKassa.get_orders("orderId")
118 | info_ruKassa = await ruKassa.get_info_payment("orderId")
119 | info_lolz = await lolz.get_invoice(payment_id="paymentId")
120 | info_aaio = await aaio.get_order_info("orderId")
121 | info_crypto_bot = await cryptoBot.get_invoices(
122 | invoice_ids=["orderId"], count=1
123 | )
124 | info_crystal_pay = await crystalPay.get_payment_info("orderId")
125 | info_cryptomus = await cryptomus.payment_info(order_id="orderId")
126 | info_xrocket = await xrocket.get_invoice_info('orderId')
127 |
128 | print("PayOK:")
129 | print("Amount: ", info_payok.amount)
130 | print("Status: ", info_payok.transaction_status)
131 | print('--------------')
132 | print("FreeKassa:")
133 | print("Amount: ", info_freeKassa.orders[0].amount)
134 | print("Status: ", info_freeKassa.orders[0].status)
135 | print('--------------')
136 | print('RuKassa:')
137 | print("Amount: ", info_ruKassa.amount)
138 | print("Status: ", info_ruKassa.status)
139 | print('--------------')
140 | print("Lolz:")
141 | print("Amount: ", info_lolz.amount)
142 | print("Status: ", info_lolz.status)
143 | print('--------------')
144 | print("Aaio:")
145 | print("Amount: ", info_aaio.amount)
146 | print("Status: ", info_aaio.status)
147 | print('--------------')
148 | print("CryptoBot:")
149 | print("Amount: ", info_crypto_bot.amount)
150 | print("Status: ", info_crypto_bot.status)
151 | print('--------------')
152 | print("CrystalPay:")
153 | print("Amount: ", info_crystal_pay.rub_amount)
154 | print("Status:", info_crystal_pay.state)
155 | print('--------------')
156 | print("Cryptomus:")
157 | print("Amount: ", info_cryptomus.amount)
158 | print("Status: ", info_cryptomus.payment_status)
159 | print('--------------')
160 | print("XRocket:")
161 | print("Amount": info_xrocket.amount)
162 | print("Status": info_xrocket.status)
163 |
164 | asyncio.run(main())
165 | ```
166 | ## Output
167 | ```Python
168 | PayOK:
169 | Balance: 0
170 | Referral balance: 0.00
171 | --------------
172 | FreeKassa:
173 | RUB: 0.00
174 | USD: 0.00
175 | EUR: 0.00
176 | KZT: 0.00
177 | UAH: 0.00
178 | --------------
179 | RuKassa:
180 | RUB: 34.0
181 | USD: 234.1
182 | --------------
183 | Lolz:
184 | ID: 4810752
185 | Nickname: ToSa
186 | Available: 5233.0
187 | In hold: 234.0
188 | --------------
189 | Aaio:
190 | Available: 1235.0
191 | In hold: 0.0
192 | Referral balance: 0.0
193 | --------------
194 | CryptoBot:
195 | Available USDT: 15.0 (In hold: 0.0)
196 | Available TON: 0.0 (In hold: 0.0)
197 | Available BTC: 0.00000023 (In hold: 0.0)
198 | Available LTC: 0.0 (In hold: 0.0)
199 | Available ETH: 0.0 (In hold: 0.0)
200 | Available BNB: 0.0 (In hold: 0.0)
201 | Available TRX: 0.0 (In hold: 0.0)
202 | Available USDC: 0.0 (In hold: 0.0)
203 | --------------
204 | CrystalPay:
205 | Available BITCOIN: 0 BTC
206 | Available BITCOINCASH: 0 BCH
207 | Available BNBCRYPTOBOT: 0 BNB
208 | Available BNBSMARTCHAIN: 0 BNB
209 | Available BTCCRYPTOBOT: 0 BTC
210 | Available CARDRUBP2P: 0 RUB
211 | Available DASH: 0 DASH
212 | Available DOGECOIN: 0 DOGE
213 | Available ETHCRYPTOBOT: 0 ETH
214 | Available ETHEREUM: 0 ETH
215 | Available LITECOIN: 0 LTC
216 | Available LTCCRYPTOBOT: 0 LTC
217 | Available LZTMARKET: 0 RUB
218 | Available POLYGON: 0 MATIC
219 | Available SBERPAYP2P: 0 RUB
220 | Available SBPP2P: 0 RUB
221 | Available TONCOIN: 0 TON
222 | Available TONCRYPTOBOT: 0 TON
223 | Available TRON: 0 TRX
224 | Available USDCTRC: 0 USDC
225 | Available USDTCRYPTOBOT: 0 USDT
226 | Available USDTTRC: 0 USDT
227 | --------------
228 | Cryptomus:
229 | Merchant:
230 |
231 | Available VERSE: 0.00000000 VERSE (0.00000000 USD)
232 | Available DAI: 0.00000000 DAI (0.00000000 USD)
233 | Available ETH: 0.00000000 ETH (0.00000000 USD)
234 | Available BCH: 0.00000000 BCH (0.00000000 USD)
235 | Available DASH: 0.00000000 DASH (0.00000000 USD)
236 | Available BNB: 0.00000000 BNB (0.00000000 USD)
237 | Available XMR: 0.00000000 XMR (0.00000000 USD)
238 | Available SOL: 0.00000000 SOL (0.00000000 USD)
239 | Available DOGE: 0.00000000 DOGE (0.00000000 USD)
240 | Available USDC: 0.00980000 USDC (0.00980031 USD)
241 | Available CGPT: 0.00000000 CGPT (0.00000000 USD)
242 | Available USDT: 0.00315576 USDT (0.00315333 USD)
243 | Available TON: 0.00000000 TON (0.00000000 USD)
244 | Available BUSD: 0.00000000 BUSD (0.00000000 USD)
245 | Available TRX: 0.01116951 TRX (0.00269201 USD)
246 | Available POL: 0.13433365 POL (0.06417564 USD)
247 | Available AVAX: 0.00000000 AVAX (0.00000000 USD)
248 | Available BTC: 0.00000000 BTC (0.00000000 USD)
249 | Available LTC: 0.00000136 LTC (0.00017045 USD)
250 | Available SHIB: 0.00000000 SHIB (0.00000000 USD)
251 | Available HMSTR: 0.00000000 HMSTR (0.00000000 USD)
252 |
253 | User:
254 |
255 | Available DASH: 0.00000000 DASH (0.00000000 USD)
256 | Available ETH: 0.00000000 ETH (0.00000000 USD)
257 | Available VERSE: 0.00000000 VERSE (0.00000000 USD)
258 | Available CRMS: 0.12041311 CRMS (0.12041311 USD)
259 | Available DAI: 0.00000000 DAI (0.00000000 USD)
260 | Available BUSD: 0.00000000 BUSD (0.00000000 USD)
261 | Available SOL: 0.00000000 SOL (0.00000000 USD)
262 | Available USDT: 0.00975846 USDT (0.00975097 USD)
263 | Available CGPT: 0.00000000 CGPT (0.00000000 USD)
264 | Available BNB: 0.00000000 BNB (0.00000000 USD)
265 | Available BTC: 0.00000000 BTC (0.00000000 USD)
266 | Available USDC: 0.00000000 USDC (0.00000000 USD)
267 | Available DOGE: 0.00000000 DOGE (0.00000000 USD)
268 | Available AVAX: 0.00000000 AVAX (0.00000000 USD)
269 | Available LTC: 0.00000000 LTC (0.00000000 USD)
270 | Available XMR: 0.00000000 XMR (0.00000000 USD)
271 | Available BCH: 0.00000000 BCH (0.00000000 USD)
272 | Available POL: 0.00000000 POL (0.00000000 USD)
273 | Available TON: 0.00000000 TON (0.00000000 USD)
274 | Available TRX: 0.00000000 TRX (0.00000000 USD)
275 | Available SHIB: 0.00000000 SHIB (0.00000000 USD)
276 | Available HMSTR: 0.00000000 HMSTR (0.00000000 USD)
277 | --------------
278 | XRocket:
279 | Available TONCOIN: 0 TONCOIN
280 | Available XROCK: 0 XROCK
281 | Available SCALE: 0 SCALE
282 | Available BOLT: 0 BOLT
283 | Available TAKE: 0 TAKE
284 | Available HEDGE: 0 HEDGE
285 | Available KOTE: 0 KOTE
286 | Available TNX: 0 TNX
287 | Available GRBS: 0 GRBS
288 | Available AMBR: 0 AMBR
289 | Available JBCT: 0 JBCT
290 | Available IVS: 0 IVS
291 | Available LAVE: 0 LAVE
292 | Available DHD: 0 DHD
293 | Available KINGY: 0 KINGY
294 | Available REDX: 0 REDX
295 | Available GGT: 0 GGT
296 | Available PET: 0 PET
297 | Available JETTON: 0 JETTON
298 | Available BNB: 0 BNB
299 | Available USDT: 0 USDT
300 | Available LIFEYT: 0 LIFEYT
301 | Available GEMSTON: 0 GEMSTON
302 | Available BTC: 0 BTC
303 | Available NANO: 0 NANO
304 | Available ANON: 0 ANON
305 | Available ATL: 0 ATL
306 | Available NUDES: 0 NUDES
307 | Available WIF: 0 WIF
308 | Available MARGA: 0 MARGA
309 | Available DUREV: 0 DUREV
310 | Available SOX: 0 SOX
311 | Available UNIC: 0 UNIC
312 | Available VIRUS1: 0 VIRUS1
313 | Available ICTN: 0 ICTN
314 | Available JMT: 0 JMT
315 | Available FID: 0 FID
316 | Available CATS: 0 CATS
317 | Available WALL: 0 WALL
318 | Available NOT: 0 NOT
319 | Available OPEN: 0 OPEN
320 | Available MORFEY: 0 MORFEY
321 | Available MMM: 0 MMM
322 | Available CAVI: 0 CAVI
323 | Available ALENKA: 0 ALENKA
324 | Available TIME: 0 TIME
325 | Available CES: 0 CES
326 | Available KKX: 0 KKX
327 | Available HYDRA: 0 HYDRA
328 | Available GRC: 0 GRC
329 | Available tsTON: 0 tsTON
330 | Available STON: 0 STON
331 | Available DOGS: 0 DOGS
332 | Available TRX: 0 TRX
333 | Available PUNK: 0 PUNK
334 | Available TONNEL: 0 TONNEL
335 | Available DFC: 0 DFC
336 | Available ETH: 0 ETH
337 | Available ARBUZ: 0 ARBUZ
338 | Available UP: 0 UP
339 | Available RAFF: 0 RAFF
340 | Available DRIFT: 0 DRIFT
341 | Available FISH: 0 FISH
342 | Available MEOW: 0 MEOW
343 | Available TINU: 0 TINU
344 | Available BLKC: 0 BLKC
345 | Available PROTON: 0 PROTON
346 | Available GRAM: 0 GRAM
347 | Available WEB3: 0 WEB3
348 | Available MRDN: 0 MRDN
349 | Available LKY: 0 LKY
350 | Available STBL: 0 STBL
351 | Available 1RUSD: 0 1RUSD
352 | Available JVT: 0 JVT
353 | Available DRA: 0 DRA
354 | Available STATHAM: 0 STATHAM
355 | Available SHEEP: 0 SHEEP
356 | Available PLANKTON: 0 PLANKTON
357 | Available MUMBA: 0 MUMBA
358 | Available VWS: 0 VWS
359 | Available LAIKA: 0 LAIKA
360 | Available SAU: 0 SAU
361 | Available GOY: 0 GOY
362 | Available BUFFY: 0 BUFFY
363 | Available PIZZA: 0 PIZZA
364 | Available SOL: 0 SOL
365 | Available SLOW: 0 SLOW
366 | Available THNG: 0 THNG
367 | Available SP: 0 SP
368 | Available AQUAXP: 0 AQUAXP
369 | Available CATI: 0 CATI
370 | Available HMSTR: 0 HMSTR
371 | Available STORM: 0 STORM
372 | Available SPN: 0 SPN
373 | Available JETTY: 0 JETTY
374 | Available MAJOR: 0 MAJOR
375 | Available FTON: 0 FTON
376 | Available CATSTG: 0 CATSTG
377 | Available BUILD: 0 BUILD
378 | Available TRUMP: 0 TRUMP
379 | ------------------------------------------
380 | PayOK: https://payok.io//pay?amount=15&payment=4364575733&shop=12452¤cy=RUB&desc=Description&sign=af2fdc6796750e3c6910230095ec0ed8
381 | FreeKassa: https://pay.freekassa.com/form/161328352/576046439bd01de60a6e418bad9354a2
382 | RuKassa: https://pay.ruks.pro/?hash=435fc3cee737f9dac2b34c9ba9311eae
383 | Lolz: https://lzt.market/invoice/369/
384 | Aaio: https://aaio.io/merchant/pay?merchant_id=f398c75d-b775-412c-9674-87939692c083&amount=15&order_id=orderId¤cy=RUB&sign=6ad5dc2164059a255921ad216c7e5ffd0d2abcaec9af7415636fc12df938582f
385 | CryptoBot: https://t.me/CryptoBot?start=IVYOJWPOZh15
386 | CrystalPay: https://pay.crystalpay.io/?i=715308958_rPwTzvsvCmabwl
387 | Cryptomus: https://pay.cryptomus.com/pay/6c0j685d-2bc1-41a1-954b-b11def3641a4
388 | XRocket: https://t.me/xrocket?start=inv_NX9RajMus37wbn3
389 | ------------------------------------------
390 | PayOK:
391 | Amount: 15
392 | Status: 0
393 | --------------
394 | FreeKassa:
395 | Amount: 150
396 | Status: 0
397 | --------------
398 | RuKassa:
399 | Amount: 50
400 | Status: WAIT
401 | --------------
402 | Lolz:
403 | Amount: 15
404 | Status: not_paid
405 | --------------
406 | Aaio:
407 | Amount: 299.0
408 | Status: in_process
409 | --------------
410 | CryptoBot:
411 | Amount: 15
412 | Status: active
413 | --------------
414 | CrystalPay:
415 | Amount: 15
416 | Status: notpayed
417 | --------------
418 | Cryptomus:
419 | Amount: 15.00
420 | Status: check
421 | --------------
422 | XRocket:
423 | Amount: 1.0
424 | Status: active
425 |
426 | ```
427 |
428 | ## Docs
429 | > Lolzteam Market: https://lzt-market.readme.io/reference/
430 | > Aaio: https://wiki.aaio.io
431 | > CryptoBot: https://help.crypt.bot/crypto-pay-api
432 | > CrystalPay: https://docs.crystalpay.io/
433 | > RuKassa: https://lk.rukassa.pro/api/v1
434 | > FreeKassa: https://docs.freekassa.com/
435 | > PayOK: https://payok.io/cabinet/documentation/doc_main.php
436 | > Cryptomus: https://doc.cryptomus.com/business
437 | > XRocket: https://pay.xrocket.tg/api/#/
438 |
439 | ## Developer Links
440 | > Zelenka (Lolzteam): https://lzt.market/tosa
441 | > GitHub: https://github.com/I-ToSa-I
442 | > Telegram: https://t.me/ToSa_LZT
443 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = ["setuptools", "setuptools-scm"]
3 | build-backend = "setuptools.build_meta"
4 | [project]
5 | name = "AsyncPayments"
6 | version = "1.4.7"
7 | dependencies = [
8 | "aiohttp"
9 | ]
10 | requires-python = ">= 3.9"
11 | authors = [
12 | { name = "ToSa" },
13 | ]
14 | maintainers = [
15 | { name = "ToSa" }
16 | ]
17 | description = "Add payment acceptance to your projects."
18 | readme = "README.md"
19 | license = {text = "MIT License"}
20 | keywords = [
21 | "async",
22 | "payments",
23 | "aaio",
24 | "crypto bot",
25 | "crystal pay",
26 | "async payments",
27 | "free kassa",
28 | "ru kassa",
29 | "cryptomus",
30 | "xrocket",
31 | "payok"
32 | ]
33 | classifiers = [
34 | "Development Status :: 5 - Production/Stable",
35 | "Natural Language :: Russian",
36 | "Natural Language :: English",
37 | "Programming Language :: Python",
38 | "Programming Language :: Python :: 3 :: Only",
39 | "Programming Language :: Python :: 3.9",
40 | "Programming Language :: Python :: 3.10",
41 | "Programming Language :: Python :: 3.11",
42 | "Topic :: Utilities"
43 | ]
44 | [project.urls]
45 | Homepage = "https://github.com/I-ToSa-I/AsyncPayments"
46 | Repository = "https://github.com/I-ToSa-I/AsyncPayments"
47 | Issues = "https://github.com/I-ToSa-I/AsyncPayments/issues"
48 |
--------------------------------------------------------------------------------