paymentsgate 1.4.9__tar.gz → 1.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of paymentsgate might be problematic. Click here for more details.
- {paymentsgate-1.4.9 → paymentsgate-1.5.0}/PKG-INFO +1 -1
- {paymentsgate-1.4.9 → paymentsgate-1.5.0}/paymentsgate/client.py +117 -54
- {paymentsgate-1.4.9 → paymentsgate-1.5.0}/paymentsgate/enums.py +57 -22
- {paymentsgate-1.4.9 → paymentsgate-1.5.0}/paymentsgate/exceptions.py +2 -2
- paymentsgate-1.5.0/paymentsgate/mappers.py +4 -0
- paymentsgate-1.5.0/paymentsgate/models.py +264 -0
- {paymentsgate-1.4.9 → paymentsgate-1.5.0}/paymentsgate/transport.py +5 -8
- paymentsgate-1.5.0/paymentsgate/types.py +9 -0
- {paymentsgate-1.4.9 → paymentsgate-1.5.0}/pyproject.toml +1 -1
- {paymentsgate-1.4.9 → paymentsgate-1.5.0}/setup.py +1 -1
- paymentsgate-1.4.9/paymentsgate/models.py +0 -233
- {paymentsgate-1.4.9 → paymentsgate-1.5.0}/LICENSE +0 -0
- {paymentsgate-1.4.9 → paymentsgate-1.5.0}/README.md +0 -0
- {paymentsgate-1.4.9 → paymentsgate-1.5.0}/paymentsgate/__init__.py +0 -0
- {paymentsgate-1.4.9 → paymentsgate-1.5.0}/paymentsgate/cache.py +0 -0
- {paymentsgate-1.4.9 → paymentsgate-1.5.0}/paymentsgate/logger.py +0 -0
- {paymentsgate-1.4.9 → paymentsgate-1.5.0}/paymentsgate/tokens.py +0 -0
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
import logging
|
|
3
|
-
from dataclasses import dataclass, is_dataclass, field, asdict
|
|
3
|
+
# from dataclasses import dataclass, is_dataclass, field, asdict
|
|
4
4
|
import json
|
|
5
5
|
from urllib.parse import urlencode
|
|
6
|
+
from pydantic import Field, BaseModel
|
|
6
7
|
|
|
7
|
-
from
|
|
8
|
+
from .types import TokenResponse
|
|
9
|
+
from .tokens import (
|
|
8
10
|
AccessToken,
|
|
9
11
|
RefreshToken
|
|
10
12
|
)
|
|
11
|
-
from
|
|
13
|
+
from .exceptions import (
|
|
12
14
|
APIResponseError,
|
|
13
15
|
APIAuthenticationError
|
|
14
16
|
)
|
|
15
|
-
from
|
|
17
|
+
from .models import (
|
|
16
18
|
Credentials,
|
|
17
19
|
GetQuoteModel,
|
|
18
20
|
GetQuoteResponseModel,
|
|
@@ -20,36 +22,35 @@ from paymentsgate.models import (
|
|
|
20
22
|
PayInResponseModel,
|
|
21
23
|
PayOutModel,
|
|
22
24
|
PayOutResponseModel,
|
|
23
|
-
InvoiceModel
|
|
25
|
+
InvoiceModel,
|
|
26
|
+
GetQuoteTlv,
|
|
27
|
+
PayOutTlvRequest,
|
|
28
|
+
QuoteTlvResponse,
|
|
24
29
|
)
|
|
25
|
-
from
|
|
26
|
-
from
|
|
30
|
+
from .enums import ApiPaths
|
|
31
|
+
from .transport import (
|
|
27
32
|
Request,
|
|
28
33
|
Response
|
|
29
34
|
)
|
|
30
|
-
from
|
|
31
|
-
from
|
|
35
|
+
from .logger import Logger
|
|
36
|
+
from .cache import (
|
|
32
37
|
AbstractCache,
|
|
33
38
|
DefaultCache
|
|
34
39
|
)
|
|
35
40
|
|
|
36
41
|
import requests
|
|
37
42
|
|
|
38
|
-
@dataclass
|
|
39
|
-
class ApiClient:
|
|
40
|
-
baseUrl: str = field(default="", init=False)
|
|
41
|
-
timeout: int = field(default=180, init=True)
|
|
42
|
-
logger: Logger = Logger
|
|
43
|
-
cache: AbstractCache = field(default_factory=DefaultCache)
|
|
44
|
-
config: Credentials = field(default_factory=dict, init=False)
|
|
45
|
-
|
|
46
|
-
REQUEST_DEBUG: bool = False
|
|
47
|
-
RESPONSE_DEBUG: bool = False
|
|
48
43
|
|
|
44
|
+
class ApiClient:
|
|
49
45
|
def __init__(self, config: Credentials, baseUrl: str, debug: bool=False):
|
|
50
46
|
self.config = config
|
|
51
47
|
self.cache = DefaultCache()
|
|
52
48
|
self.baseUrl = baseUrl
|
|
49
|
+
|
|
50
|
+
self.REQUEST_DEBUG = False
|
|
51
|
+
self.RESPONSE_DEBUG = False
|
|
52
|
+
self.timeout = 180
|
|
53
|
+
|
|
53
54
|
if debug:
|
|
54
55
|
logging.basicConfig(level=logging.DEBUG)
|
|
55
56
|
|
|
@@ -65,7 +66,7 @@ class ApiClient:
|
|
|
65
66
|
|
|
66
67
|
# Handle response
|
|
67
68
|
response = self._send_request(request)
|
|
68
|
-
self.
|
|
69
|
+
self.log(request, response)
|
|
69
70
|
if (response.success):
|
|
70
71
|
return response.cast(PayInResponseModel, APIResponseError)
|
|
71
72
|
else:
|
|
@@ -84,16 +85,34 @@ class ApiClient:
|
|
|
84
85
|
|
|
85
86
|
# Handle response
|
|
86
87
|
response = self._send_request(request)
|
|
87
|
-
self.
|
|
88
|
+
self.log(request, response)
|
|
88
89
|
if (response.success):
|
|
89
90
|
return response.cast(PayOutResponseModel, APIResponseError)
|
|
90
91
|
else:
|
|
91
92
|
raise APIResponseError(response)
|
|
92
93
|
|
|
94
|
+
def PayOutTlv(self, request: PayOutTlvRequest) -> PayOutResponseModel:
|
|
95
|
+
request = Request(
|
|
96
|
+
method="post",
|
|
97
|
+
path=ApiPaths.invoices_payout_tlv,
|
|
98
|
+
content_type='application/json',
|
|
99
|
+
noAuth=False,
|
|
100
|
+
signature=False,
|
|
101
|
+
body=request
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
# Handle response
|
|
105
|
+
response = self._send_request(request)
|
|
106
|
+
self.log(request, response)
|
|
107
|
+
if not response.success:
|
|
108
|
+
raise APIResponseError(response)
|
|
109
|
+
|
|
110
|
+
return response.cast(PayOutResponseModel, APIResponseError)
|
|
111
|
+
|
|
93
112
|
def Quote(self, params: GetQuoteModel) -> GetQuoteResponseModel:
|
|
94
113
|
# Prepare request
|
|
95
114
|
request = Request(
|
|
96
|
-
method="
|
|
115
|
+
method="post",
|
|
97
116
|
path=ApiPaths.fx_quote,
|
|
98
117
|
content_type='application/json',
|
|
99
118
|
noAuth=False,
|
|
@@ -103,12 +122,30 @@ class ApiClient:
|
|
|
103
122
|
|
|
104
123
|
# Handle response
|
|
105
124
|
response = self._send_request(request)
|
|
106
|
-
self.
|
|
125
|
+
self.log(request, response)
|
|
107
126
|
if not response.success:
|
|
108
127
|
raise APIResponseError(response)
|
|
109
128
|
|
|
110
129
|
return response.cast(GetQuoteResponseModel, APIResponseError)
|
|
111
130
|
|
|
131
|
+
def QuoteQr(self, params: GetQuoteTlv) -> QuoteTlvResponse:
|
|
132
|
+
request = Request(
|
|
133
|
+
method="post",
|
|
134
|
+
path=ApiPaths.fx_quote_tlv,
|
|
135
|
+
content_type='application/json',
|
|
136
|
+
noAuth=False,
|
|
137
|
+
signature=False,
|
|
138
|
+
body=params
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
# Handle response
|
|
142
|
+
response = self._send_request(request)
|
|
143
|
+
self.log(request, response)
|
|
144
|
+
if not response.success:
|
|
145
|
+
raise APIResponseError(response)
|
|
146
|
+
|
|
147
|
+
return response.cast(QuoteTlvResponse, APIResponseError)
|
|
148
|
+
|
|
112
149
|
def Status(self, id: str) -> InvoiceModel:
|
|
113
150
|
# Prepare request
|
|
114
151
|
request = Request(
|
|
@@ -121,7 +158,7 @@ class ApiClient:
|
|
|
121
158
|
|
|
122
159
|
# Handle response
|
|
123
160
|
response = self._send_request(request)
|
|
124
|
-
self.
|
|
161
|
+
self.log(request, response)
|
|
125
162
|
if not response.success:
|
|
126
163
|
raise APIResponseError(response)
|
|
127
164
|
|
|
@@ -130,23 +167,25 @@ class ApiClient:
|
|
|
130
167
|
@property
|
|
131
168
|
def token(self) -> AccessToken | None:
|
|
132
169
|
# First check if valid token is cached
|
|
133
|
-
token = self.cache.get_token('
|
|
134
|
-
refresh = self.cache.get_token('
|
|
170
|
+
token = self.cache.get_token('AccessToken')
|
|
171
|
+
refresh = self.cache.get_token('RefreshToken')
|
|
172
|
+
|
|
135
173
|
if token is not None and not token.is_expired:
|
|
136
174
|
return token
|
|
137
175
|
else:
|
|
138
176
|
# try to refresh token
|
|
139
177
|
if refresh is not None and not refresh.is_expired:
|
|
140
|
-
refreshed = self._refresh_token()
|
|
178
|
+
refreshed = self._refresh_token(token, refresh)
|
|
141
179
|
|
|
142
180
|
if (refreshed.success):
|
|
143
181
|
access = AccessToken(
|
|
144
|
-
|
|
182
|
+
refreshed.json_body["access_token"]
|
|
145
183
|
)
|
|
146
184
|
refresh = RefreshToken(
|
|
147
|
-
|
|
148
|
-
int(
|
|
185
|
+
refreshed.json_body["refresh_token"],
|
|
186
|
+
int(refreshed.json_body["expires_in"]),
|
|
149
187
|
)
|
|
188
|
+
|
|
150
189
|
self.cache.set_token(access)
|
|
151
190
|
self.cache.set_token(refresh)
|
|
152
191
|
|
|
@@ -157,12 +196,13 @@ class ApiClient:
|
|
|
157
196
|
if response.success:
|
|
158
197
|
|
|
159
198
|
access = AccessToken(
|
|
160
|
-
response.
|
|
199
|
+
response.json_body["access_token"]
|
|
161
200
|
)
|
|
162
201
|
refresh = RefreshToken(
|
|
163
|
-
response.
|
|
164
|
-
int(response.
|
|
202
|
+
response.json_body["refresh_token"],
|
|
203
|
+
int(response.json_body["expires_in"]),
|
|
165
204
|
)
|
|
205
|
+
|
|
166
206
|
self.cache.set_token(access)
|
|
167
207
|
self.cache.set_token(refresh)
|
|
168
208
|
|
|
@@ -174,7 +214,8 @@ class ApiClient:
|
|
|
174
214
|
"""
|
|
175
215
|
Send a specified Request to the GoPay REST API and process the response
|
|
176
216
|
"""
|
|
177
|
-
body = asdict(request.body) if is_dataclass(request.body) else request.body
|
|
217
|
+
# body = asdict(request.body) if is_dataclass(request.body) else request.body
|
|
218
|
+
body = request.body
|
|
178
219
|
# Add Bearer authentication to headers if needed
|
|
179
220
|
headers = request.headers or {}
|
|
180
221
|
if not request.noAuth:
|
|
@@ -184,35 +225,48 @@ class ApiClient:
|
|
|
184
225
|
|
|
185
226
|
if (request.method == 'get'):
|
|
186
227
|
params = urlencode(body)
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
228
|
+
try:
|
|
229
|
+
r = requests.request(
|
|
230
|
+
method=request.method,
|
|
231
|
+
url=f"{self.baseUrl}{request.path}?{params}",
|
|
232
|
+
headers=headers,
|
|
233
|
+
timeout=self.timeout
|
|
234
|
+
)
|
|
235
|
+
except:
|
|
236
|
+
print('Error')
|
|
237
|
+
pass
|
|
193
238
|
else:
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
239
|
+
try:
|
|
240
|
+
r = requests.request(
|
|
241
|
+
method=request.method,
|
|
242
|
+
url=f"{self.baseUrl}{request.path}",
|
|
243
|
+
headers=headers,
|
|
244
|
+
json=body,
|
|
245
|
+
timeout=self.timeout
|
|
246
|
+
)
|
|
247
|
+
except KeyError:
|
|
248
|
+
print('Error')
|
|
249
|
+
pass
|
|
250
|
+
|
|
251
|
+
# if r == None:
|
|
201
252
|
|
|
202
253
|
# Build Response instance, try to decode body as JSON
|
|
203
|
-
response = Response(raw_body=r.content,
|
|
254
|
+
response = Response(raw_body=r.content, json_body={}, status_code=r.status_code)
|
|
204
255
|
|
|
205
256
|
if (self.REQUEST_DEBUG):
|
|
206
257
|
print(f"{request.method} => {self.baseUrl}{request.path} => {response.status_code}")
|
|
207
258
|
|
|
208
259
|
try:
|
|
209
|
-
response.
|
|
260
|
+
response.json_body = r.json()
|
|
210
261
|
except json.JSONDecodeError:
|
|
211
262
|
pass
|
|
212
263
|
|
|
213
|
-
self.
|
|
264
|
+
self.log(request, response)
|
|
214
265
|
return response
|
|
215
266
|
|
|
267
|
+
def log(self, request: Request, response: Response):
|
|
268
|
+
Logger(self, request, response)
|
|
269
|
+
|
|
216
270
|
def _get_token(self) -> Response:
|
|
217
271
|
# Prepare request
|
|
218
272
|
request = Request(
|
|
@@ -224,18 +278,27 @@ class ApiClient:
|
|
|
224
278
|
)
|
|
225
279
|
# Handle response
|
|
226
280
|
response = self._send_request(request)
|
|
227
|
-
self.
|
|
281
|
+
self.log(request, response)
|
|
228
282
|
return response
|
|
229
283
|
|
|
230
|
-
def _refresh_token(self) -> Response:
|
|
284
|
+
def _refresh_token(self, access: AccessToken, refresh: RefreshToken) -> Response:
|
|
231
285
|
# Prepare request
|
|
232
286
|
request = Request(
|
|
233
287
|
method="post",
|
|
234
288
|
path=ApiPaths.token_refresh,
|
|
235
289
|
content_type='application/json',
|
|
236
|
-
|
|
290
|
+
noAuth=True,
|
|
291
|
+
headers={"Authorization": f"Bearer {access.token}" },
|
|
292
|
+
body={"refresh_token": refresh.token},
|
|
237
293
|
)
|
|
238
294
|
# Handle response
|
|
239
295
|
response = self._send_request(request)
|
|
240
|
-
self.
|
|
296
|
+
self.log(request, response)
|
|
241
297
|
return response
|
|
298
|
+
|
|
299
|
+
def loadToken(self, params: TokenResponse):
|
|
300
|
+
access = AccessToken(params.access_token)
|
|
301
|
+
refresh = RefreshToken(params.refresh_token, int(params.expires_in))
|
|
302
|
+
self.cache.set_token(access)
|
|
303
|
+
self.cache.set_token(refresh)
|
|
304
|
+
|
|
@@ -16,6 +16,7 @@ class ApiPaths(StrEnum):
|
|
|
16
16
|
token_validate = "/auth/token/validate"
|
|
17
17
|
invoices_payin = "/deals/payin"
|
|
18
18
|
invoices_payout = "/deals/payout"
|
|
19
|
+
invoices_payout_tlv = "/deals/tlv"
|
|
19
20
|
invoices_info = "/deals/:id"
|
|
20
21
|
invoices_credentials = "/deals/:id/credentials"
|
|
21
22
|
assets_list = "/wallet"
|
|
@@ -25,6 +26,7 @@ class ApiPaths(StrEnum):
|
|
|
25
26
|
appel_list = "/support/list"
|
|
26
27
|
appel_stat = "/support/statistic"
|
|
27
28
|
fx_quote = "/fx/calculatenew"
|
|
29
|
+
fx_quote_tlv = "/fx/tlv"
|
|
28
30
|
|
|
29
31
|
class Currencies(StrEnum):
|
|
30
32
|
USDT = "USDT"
|
|
@@ -57,14 +59,16 @@ class Currencies(StrEnum):
|
|
|
57
59
|
AMD = "AMD"
|
|
58
60
|
|
|
59
61
|
class Languages(StrEnum):
|
|
60
|
-
EN = "EN"
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
62
|
+
EN = "EN",
|
|
63
|
+
AZ = "AZ",
|
|
64
|
+
UZ = "UZ",
|
|
65
|
+
GE = "GE",
|
|
66
|
+
TR = "TR",
|
|
67
|
+
AE = "AE",
|
|
68
|
+
RU = "RU",
|
|
69
|
+
IN = "IN",
|
|
70
|
+
AR = "AR",
|
|
71
|
+
KG = "KG"
|
|
68
72
|
|
|
69
73
|
|
|
70
74
|
class Statuses(StrEnum):
|
|
@@ -118,14 +122,42 @@ class InvoiceTypes(StrEnum):
|
|
|
118
122
|
vodafonecash = "vodafonecash"
|
|
119
123
|
razn = "razn"
|
|
120
124
|
rtjs = "rtjs"
|
|
121
|
-
|
|
125
|
+
sberpay = "sberpay",
|
|
126
|
+
tpay = "tpay",
|
|
127
|
+
opay = "opay",
|
|
128
|
+
moniepoint = "moniepoint",
|
|
129
|
+
palmpay = "palmpay",
|
|
130
|
+
wave = "wave",
|
|
131
|
+
orangemoney = "orangemoney",
|
|
132
|
+
moovmoney = "moovmoney",
|
|
133
|
+
rtjscard = "rtjscard",
|
|
134
|
+
ruzs = "ruzs",
|
|
135
|
+
amobile = "amobile",
|
|
136
|
+
payid = "payid",
|
|
137
|
+
baridi = "baridi",
|
|
138
|
+
multiwidget = "multiwidget",
|
|
139
|
+
attijari = "attijari",
|
|
140
|
+
cih = "cih",
|
|
141
|
+
cashplus = "cashplus",
|
|
142
|
+
elqr = "elqr",
|
|
143
|
+
odengi = "odengi"
|
|
144
|
+
|
|
145
|
+
class EELQRBankALias(StrEnum):
|
|
146
|
+
bakai = 'bakai',
|
|
147
|
+
mbank = 'mbank',
|
|
148
|
+
optima = 'optima',
|
|
149
|
+
kicb = 'kicb',
|
|
150
|
+
odengi = 'odengi',
|
|
151
|
+
demir = 'demir',
|
|
152
|
+
megapay = 'megapay',
|
|
122
153
|
|
|
123
154
|
class CredentialsTypes(StrEnum):
|
|
124
|
-
iban = "iban"
|
|
125
|
-
phone = "phone"
|
|
126
|
-
card = "card"
|
|
127
|
-
fps = "fps"
|
|
128
|
-
|
|
155
|
+
iban = "iban",
|
|
156
|
+
phone = "phone",
|
|
157
|
+
card = "card",
|
|
158
|
+
fps = "fps",
|
|
159
|
+
qr = "qr",
|
|
160
|
+
account = "account",
|
|
129
161
|
custom = "custom"
|
|
130
162
|
|
|
131
163
|
|
|
@@ -137,12 +169,13 @@ class RiskScoreLevels(StrEnum):
|
|
|
137
169
|
|
|
138
170
|
|
|
139
171
|
class CancellationReason(StrEnum):
|
|
140
|
-
NO_MONEY = "NO_MONEY"
|
|
141
|
-
CREDENTIALS_INVALID = "CREDENTIALS_INVALID"
|
|
142
|
-
EXPIRED = "EXPIRED"
|
|
143
|
-
PRECHARGE_GAP_UPPER_LIMIT = "PRECHARGE_GAP_UPPER_LIMIT"
|
|
144
|
-
CROSS_BANK_TFF_LESS_THAN_3K = "CROSS_BANK_TFF_LESS_THAN_3K"
|
|
145
|
-
CROSS_BANK_UNSUPPORTED = "CROSS_BANK_UNSUPPORTED"
|
|
172
|
+
NO_MONEY = "NO_MONEY",
|
|
173
|
+
CREDENTIALS_INVALID = "CREDENTIALS_INVALID",
|
|
174
|
+
EXPIRED = "EXPIRED",
|
|
175
|
+
PRECHARGE_GAP_UPPER_LIMIT = "PRECHARGE_GAP_UPPER_LIMIT",
|
|
176
|
+
CROSS_BANK_TFF_LESS_THAN_3K = "CROSS_BANK_TFF_LESS_THAN_3K",
|
|
177
|
+
CROSS_BANK_UNSUPPORTED = "CROSS_BANK_UNSUPPORTED",
|
|
178
|
+
ACCOUNT_NUMBER_BLACKLISTED = "ACCOUNT_NUMBER_BLACKLISTED"
|
|
146
179
|
|
|
147
180
|
|
|
148
181
|
class FeesStrategy(StrEnum):
|
|
@@ -151,8 +184,10 @@ class FeesStrategy(StrEnum):
|
|
|
151
184
|
|
|
152
185
|
|
|
153
186
|
class InvoiceDirection(StrEnum):
|
|
154
|
-
F2C = "F2C"
|
|
155
|
-
C2F = "C2F"
|
|
187
|
+
F2C = "F2C",
|
|
188
|
+
C2F = "C2F",
|
|
189
|
+
FIAT_IN = "FIAT_IN",
|
|
190
|
+
FIAT_OUT = "FIAT_OUT"
|
|
156
191
|
|
|
157
192
|
|
|
158
193
|
class TTLUnits(StrEnum):
|
|
@@ -31,8 +31,8 @@ class APIError(PaymentsgateError):
|
|
|
31
31
|
|
|
32
32
|
class APIResponseError(APIError):
|
|
33
33
|
def __init__(self, response: Response) -> None:
|
|
34
|
-
super().__init__(response.
|
|
34
|
+
super().__init__(response.json_body.get('error'), response.json_body.get('message'), response.json_body.get('data'), response.json_body.get('details'), response.status_code)
|
|
35
35
|
|
|
36
36
|
class APIAuthenticationError(APIError):
|
|
37
37
|
def __init__(self, response: Response) -> None:
|
|
38
|
-
super().__init__(response.
|
|
38
|
+
super().__init__(response.json_body.get('error'), response.json_body.get('message'), response.json_body.get('data'), response.json_body.get('details'), response.status_code)
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
import datetime
|
|
3
|
+
import json
|
|
4
|
+
from typing import Optional, List
|
|
5
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
from paymentsgate.enums import (
|
|
9
|
+
Currencies,
|
|
10
|
+
InvoiceTypes,
|
|
11
|
+
Languages,
|
|
12
|
+
Statuses,
|
|
13
|
+
TTLUnits,
|
|
14
|
+
CurrencyTypes,
|
|
15
|
+
FeesStrategy,
|
|
16
|
+
InvoiceDirection,
|
|
17
|
+
CredentialsTypes
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
class BaseRequestModel(BaseModel):
|
|
21
|
+
model_config = ConfigDict(extra='forbid')
|
|
22
|
+
|
|
23
|
+
class BaseResponseModel(BaseModel):
|
|
24
|
+
model_config = ConfigDict(extra='ignore')
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class Credentials(BaseModel):
|
|
28
|
+
account_id: str
|
|
29
|
+
public_key: str
|
|
30
|
+
private_key: Optional[str] = Field(default=None)
|
|
31
|
+
merchant_id: Optional[str] = Field(default=None)
|
|
32
|
+
project_id: Optional[str] = Field(default=None)
|
|
33
|
+
|
|
34
|
+
@classmethod
|
|
35
|
+
def fromFile(cls, filename):
|
|
36
|
+
data = json.load(open(filename))
|
|
37
|
+
return cls(**data)
|
|
38
|
+
|
|
39
|
+
model_config = ConfigDict(extra='ignore')
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class PayInFingerprintBrowserModel(BaseRequestModel):
|
|
43
|
+
acceptHeader: str
|
|
44
|
+
colorDepth: int
|
|
45
|
+
language: str
|
|
46
|
+
screenHeight: int
|
|
47
|
+
screenWidth: int
|
|
48
|
+
timezone: str
|
|
49
|
+
userAgent: str
|
|
50
|
+
javaEnabled: bool
|
|
51
|
+
windowHeight: int
|
|
52
|
+
windowWidth: int
|
|
53
|
+
|
|
54
|
+
class PayInFingerprintModel(BaseRequestModel):
|
|
55
|
+
fingerprint: str
|
|
56
|
+
ip: str
|
|
57
|
+
country: str
|
|
58
|
+
city: str
|
|
59
|
+
state: str
|
|
60
|
+
zip: str
|
|
61
|
+
browser: Optional[PayInFingerprintBrowserModel]
|
|
62
|
+
|
|
63
|
+
class PayInModel(BaseRequestModel):
|
|
64
|
+
amount: float # decimals: 2
|
|
65
|
+
currency: Currencies
|
|
66
|
+
country: Optional[str] # Country iso code
|
|
67
|
+
invoiceId: Optional[str] # idempotent key
|
|
68
|
+
clientId: Optional[str] # uniq client ref
|
|
69
|
+
type: InvoiceTypes # Invoice subtype, see documentation
|
|
70
|
+
bankId: Optional[str] # ID from bank list or NSPK id
|
|
71
|
+
trusted: Optional[bool]
|
|
72
|
+
successUrl: Optional[str]
|
|
73
|
+
failUrl: Optional[str]
|
|
74
|
+
backUrl: Optional[str]
|
|
75
|
+
clientCard: Optional[str]
|
|
76
|
+
clientName: Optional[str]
|
|
77
|
+
fingerprint: Optional[PayInFingerprintModel]
|
|
78
|
+
lang: Optional[Languages]
|
|
79
|
+
sync: Optional[bool] # sync h2h scheme, see documentation
|
|
80
|
+
multiWidgetOptions: Optional[PayInMultiWidgetOptions]
|
|
81
|
+
theme: Optional[str] # personalized widget theme
|
|
82
|
+
|
|
83
|
+
class PayInResponseModel(BaseResponseModel):
|
|
84
|
+
id: str
|
|
85
|
+
status: Statuses
|
|
86
|
+
type: InvoiceTypes
|
|
87
|
+
url: Optional[str]
|
|
88
|
+
deeplink: Optional[str]
|
|
89
|
+
m10: Optional[str]
|
|
90
|
+
cardholder: Optional[str]
|
|
91
|
+
account: Optional[str]
|
|
92
|
+
bankId: Optional[str]
|
|
93
|
+
accountSubType: Optional[str]
|
|
94
|
+
|
|
95
|
+
class PayOutRecipientModel(BaseRequestModel):
|
|
96
|
+
account_number: str # IBAN, Phone, Card, local bank account number, wallet number, etc'
|
|
97
|
+
account_owner: Optional[str] # FirstName LastName or FirstName MiddleName LastName
|
|
98
|
+
account_iban: Optional[str] # use only cases where iban is't primary account id
|
|
99
|
+
account_swift: Optional[str] # for swift transfers only
|
|
100
|
+
account_phone: Optional[str] # additional recipient phone number, use only cases where phone is't primary account id
|
|
101
|
+
account_bic: Optional[str] # recipient bank id
|
|
102
|
+
account_ewallet_name: Optional[str] # additional recipient wallet provider info
|
|
103
|
+
account_email: Optional[str] # additional recipient email, use only cases where email is't primary account id
|
|
104
|
+
account_bank_id: Optional[str] # recipient bankId (from API banks or RU NSPK id)
|
|
105
|
+
account_internal_client_number: Optional[str] # Bank internal identifier used for method banktransferphp (Philippines)
|
|
106
|
+
type: Optional[CredentialsTypes] # primary credential type
|
|
107
|
+
|
|
108
|
+
class PayOutModel(BaseRequestModel):
|
|
109
|
+
currency: Optional[Currencies] # currency from, by default = usdt
|
|
110
|
+
currencyTo: Optional[Currencies] # currency to, fiat only, if use quoteId - not required
|
|
111
|
+
amount: Optional[float] # decimals: 2, if use quoteId - not required
|
|
112
|
+
invoiceId: Optional[str] # idempotent key
|
|
113
|
+
clientId: Optional[str] # uniq client ref
|
|
114
|
+
ttl: Optional[int]
|
|
115
|
+
ttl_unit: Optional[TTLUnits]
|
|
116
|
+
finalAmount: Optional[float] # Optional, for pre-charge rate lock
|
|
117
|
+
sender_name: Optional[str] # sender personal short data
|
|
118
|
+
sender_personal: Optional[PayOutSenderModel]
|
|
119
|
+
baseCurrency: Optional[CurrencyTypes]
|
|
120
|
+
feesStrategy: Optional[FeesStrategy]
|
|
121
|
+
recipient: PayOutRecipientModel
|
|
122
|
+
quoteId: Optional[str]
|
|
123
|
+
src_amount: Optional[str] # Optional, source amount in local currency for 2phase payout
|
|
124
|
+
type: Optional[InvoiceTypes] # payout transaction scheme hint
|
|
125
|
+
|
|
126
|
+
class PayOutResponseModel(BaseResponseModel):
|
|
127
|
+
id: str
|
|
128
|
+
status: Statuses
|
|
129
|
+
|
|
130
|
+
class GetQuoteModel(BaseRequestModel):
|
|
131
|
+
currency_from: Currencies
|
|
132
|
+
currency_to: Currencies
|
|
133
|
+
amount: float
|
|
134
|
+
subtype: Optional[InvoiceTypes]
|
|
135
|
+
currency_original: Optional[Currencies]
|
|
136
|
+
|
|
137
|
+
class QuoteEntity(BaseResponseModel):
|
|
138
|
+
currencyFrom: Currencies
|
|
139
|
+
currencyTo: Currencies
|
|
140
|
+
pair: str
|
|
141
|
+
rate: float
|
|
142
|
+
|
|
143
|
+
class GetQuoteResponseModel(BaseResponseModel):
|
|
144
|
+
id: str
|
|
145
|
+
finalAmount: float
|
|
146
|
+
direction: InvoiceDirection
|
|
147
|
+
fullRate: float
|
|
148
|
+
fullRateReverse: float
|
|
149
|
+
fees: float
|
|
150
|
+
fees_percent: float
|
|
151
|
+
quotes: List[QuoteEntity]
|
|
152
|
+
expiredAt: Optional[datetime.datetime] = Field(default=None)
|
|
153
|
+
|
|
154
|
+
#deprecated
|
|
155
|
+
currency_from: Optional[CurrencyModel] = Field(default=None)
|
|
156
|
+
currency_to: Optional[CurrencyModel] = Field(default=None)
|
|
157
|
+
currency_middle: Optional[CurrencyModel] = Field(default=None)
|
|
158
|
+
rate1: Optional[float] = Field(default=None)
|
|
159
|
+
rate2: Optional[float] = Field(default=None)
|
|
160
|
+
rate3: Optional[float] = Field(default=None)
|
|
161
|
+
net_amount: Optional[float] = Field(default=None)
|
|
162
|
+
metadata: Optional[object] = Field(default=None)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class DepositAddressResponseModel(BaseResponseModel):
|
|
166
|
+
currency: Currencies
|
|
167
|
+
address: str
|
|
168
|
+
expiredAt: datetime.datetime
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
class CurrencyModel(BaseResponseModel):
|
|
172
|
+
_id: str
|
|
173
|
+
type: CurrencyTypes
|
|
174
|
+
code: Currencies
|
|
175
|
+
symbol: str
|
|
176
|
+
label: Optional[str] = Field(default=None)
|
|
177
|
+
decimal: int
|
|
178
|
+
countryCode: Optional[str] = Field(default=None)
|
|
179
|
+
countryName: Optional[str] = Field(default=None)
|
|
180
|
+
|
|
181
|
+
class BankModel(BaseResponseModel):
|
|
182
|
+
name: str
|
|
183
|
+
title: str
|
|
184
|
+
currency: Currencies
|
|
185
|
+
fpsId: str
|
|
186
|
+
|
|
187
|
+
class InvoiceStatusModel(BaseResponseModel):
|
|
188
|
+
name: Statuses
|
|
189
|
+
createdAt: datetime.datetime
|
|
190
|
+
updatedAt: datetime.datetime
|
|
191
|
+
|
|
192
|
+
class InvoiceAmountModel(BaseResponseModel):
|
|
193
|
+
crypto: float
|
|
194
|
+
fiat: float
|
|
195
|
+
fiat_net: float
|
|
196
|
+
|
|
197
|
+
class InvoiceMetadataModel(BaseResponseModel):
|
|
198
|
+
invoiceId: Optional[str]
|
|
199
|
+
clientId: Optional[str]
|
|
200
|
+
fiatAmount: Optional[float]
|
|
201
|
+
|
|
202
|
+
class InvoiceModel(BaseResponseModel):
|
|
203
|
+
_id: str
|
|
204
|
+
orderId: str
|
|
205
|
+
projectId: str
|
|
206
|
+
currencyFrom: CurrencyModel
|
|
207
|
+
currencyTo: CurrencyModel
|
|
208
|
+
direction: InvoiceDirection
|
|
209
|
+
amount: float
|
|
210
|
+
status: InvoiceStatusModel
|
|
211
|
+
amounts: InvoiceAmountModel
|
|
212
|
+
metadata: InvoiceMetadataModel
|
|
213
|
+
receiptUrls: List[str]
|
|
214
|
+
isExpired: bool
|
|
215
|
+
createdAt: datetime.datetime
|
|
216
|
+
updatedAt: datetime.datetime
|
|
217
|
+
expiredAt: datetime.datetime
|
|
218
|
+
|
|
219
|
+
class AssetsAccountModel(BaseResponseModel):
|
|
220
|
+
currency: CurrencyModel;
|
|
221
|
+
total: float
|
|
222
|
+
pending: float
|
|
223
|
+
available: float
|
|
224
|
+
|
|
225
|
+
class AssetsResponseModel(BaseResponseModel):
|
|
226
|
+
assets: List[AssetsAccountModel]
|
|
227
|
+
|
|
228
|
+
class PayInMultiWidgetOptions(BaseRequestModel):
|
|
229
|
+
offerAmount: Optional[bool] # show amount select from best offers
|
|
230
|
+
elqrBanks: Optional[str] # elqr bank list
|
|
231
|
+
|
|
232
|
+
class PayOutSenderModel(BaseRequestModel):
|
|
233
|
+
name: Optional[str]
|
|
234
|
+
birthday: Optional[str]
|
|
235
|
+
phone: Optional[str]
|
|
236
|
+
passport: Optional[str]
|
|
237
|
+
|
|
238
|
+
class PayOutTlvRequestModel(BaseRequestModel):
|
|
239
|
+
quoteId: str # ID from /fx/tlv response
|
|
240
|
+
invoiceId: Optional[str]
|
|
241
|
+
clientId: Optional[str]
|
|
242
|
+
sender_personal: Optional[PayOutSenderModel]
|
|
243
|
+
|
|
244
|
+
class GetQuoteTlv(BaseRequestModel):
|
|
245
|
+
data: str
|
|
246
|
+
|
|
247
|
+
class QuoteTlvResponse(BaseResponseModel):
|
|
248
|
+
id: str
|
|
249
|
+
amount: float # fiat local amount
|
|
250
|
+
amountCrypto: float # total crypto amount inc. fees
|
|
251
|
+
currencyCode: Currencies # local currency
|
|
252
|
+
feeInCrypto: float # total fee in crypto
|
|
253
|
+
feePercent: float # fee percent
|
|
254
|
+
qrVersion: int # qr code version, 1 - nspk, 2 - tlv encoded, 3 - tlv plain
|
|
255
|
+
rate: float # exchange rate
|
|
256
|
+
merchant: Optional[str] = Field(default=None) # merchant title
|
|
257
|
+
logo: Optional[str] = Field(default=None) # merchant logo
|
|
258
|
+
|
|
259
|
+
class PayOutTlvRequest(BaseRequestModel):
|
|
260
|
+
quoteId: str # quote.id ref
|
|
261
|
+
invoiceId: Optional[str] = Field(default=None)
|
|
262
|
+
clientId: Optional[str] = Field(default=None)
|
|
263
|
+
src_amount: Optional[float] = Field(default=None)
|
|
264
|
+
sender_personal: Optional[PayOutSenderModel] = Field(default=None)
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
from pydantic import BaseModel
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
class Request:
|
|
4
|
+
class Request(BaseModel):
|
|
6
5
|
method: str
|
|
7
6
|
path: str
|
|
8
7
|
content_type: str = 'application/json'
|
|
@@ -11,11 +10,9 @@ class Request:
|
|
|
11
10
|
noAuth: bool | None = False
|
|
12
11
|
signature: bool | None = False
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
@dataclass
|
|
16
|
-
class Response:
|
|
13
|
+
class Response(BaseModel):
|
|
17
14
|
raw_body: bytes
|
|
18
|
-
|
|
15
|
+
json_body: dict
|
|
19
16
|
status_code: int
|
|
20
17
|
|
|
21
18
|
@property
|
|
@@ -24,8 +21,8 @@ class Response:
|
|
|
24
21
|
|
|
25
22
|
def cast(self, model: BaseModel, error: dict):
|
|
26
23
|
if self.success:
|
|
27
|
-
return model(**self.
|
|
28
|
-
return error(self.
|
|
24
|
+
return model(**self.json_body)
|
|
25
|
+
return error(self.json_body.get('error'), self.json_body.get('message'), self.json_body.get('data'), self.json_body.get('status'));
|
|
29
26
|
|
|
30
27
|
def __str__(self) -> str:
|
|
31
28
|
return self.raw_body.decode("utf-8")
|
|
@@ -15,7 +15,7 @@ install_requires = \
|
|
|
15
15
|
|
|
16
16
|
setup_kwargs = {
|
|
17
17
|
'name': 'paymentsgate',
|
|
18
|
-
'version': '1.
|
|
18
|
+
'version': '1.5.0',
|
|
19
19
|
'description': "PaymentsGate's Python SDK for REST API",
|
|
20
20
|
'long_description': '\n# Paymentsgate Python SDK for Payments REST API\n\n\n## Requirements\n\n- Python >= 3.8.1\n- dependencies:\n - [`requests`](https://github.com/kennethreitz/requests)\n - [`pydantic`](https://docs.pydantic.dev/latest/)\n - [`jwt`](https://pyjwt.readthedocs.io/en/stable/)\n \n## Installation\n\nThe simplest way to install SDK is to use [PIP](https://docs.python.org/3/installing/):\n\n```bash\npip install paymentsgate\n```\n\n## Basic usage\n\n```python\nfrom paymentsgate import ApiClient, Credentials, Currencies\n\n\n# minimal configuration\nconfig = Credentials().fromFile(\'/path/to/credentials.json\');\n\n# create ApiClient\nclient = ApiClient(config, baseUrl=\'https://api.example.com\');\n\n# request quote\nres = cli.Quote(\n {\n "amount": 10.10,\n "currency_from": Currencies.EUR,\n "currency_to": Currencies.AZN,\n }\n)\nprint(res);\n```\n\nThe `credentials.json` file is used to connect to the client and contains all necessary data to use the API. This file can be obtained in your personal cabinet, in the service accounts section. Follow the instructions in the documentation to issue new keys. If you already have keys, but you don\'t feel comfortable storing them in a file, you can use client initialization via variables. In this case, the key data can be stored in external storage instead of on the file system:\n\n```python\nfrom paymentsgate import ApiClient, Credentials\n\nconfig = Credentials(\n account_id="00000000-4000-4000-0000-00000000000a" \n public_key="LS0tLS1CRUdJTiBSU0EgUFJJVkFUNSUlFb3dJQk..."\n)\n\nclient = ApiClient(config, baseUrl=\'https://api.example.com\');\n\n...\n```\n*It is important to note that the data format for key transfer is base46.\n\n## Examples\n\n### create PayIn\n\n```python\nres = cli.PayIn(\n {\n "amount": 10.10,\n "currency": Currencies.AZN,\n "invoiceId": "INVOICE-112123124",\n "clientId": "",\n "successUrl": "https://example.com/success",\n "failUrl": "https://example.com/fail",\n "type": InvoiceTypes.m10\n }\n)\nprint(res);\n```\n\n### create PayOut\n\n```python\nres = cli.PayOut(\n {\n "amount": 5.12,\n "currencyTo": Currencies.EUR,\n "invoiceId": "INVOICE-112123124",\n "clientId": "CLIENT-003010023004",\n "baseCurrency": CurrencyTypes.fiat,\n "feesStrategy": FeesStrategy.add,\n "recipient": {\n "account_number": "4000000000000012",\n "account_owner": "CARD HOLDER",\n "type": CredentialsTypes.card\n }\n }\n)\nprint(res);\n```\n\n### Error handling\n\n```python\ntry:\n res = cli.PayOut(\n {\n "amount": 5.12,\n "currencyTo": Currencies.EUR,\n "invoiceId": "INVOICE-112123124",\n "clientId": "CLIENT-003010023004",\n "baseCurrency": CurrencyTypes.fiat,\n "feesStrategy": FeesStrategy.add,\n "recipient": {\n "account_number": "4000000000000012",\n "account_owner": "CARD HOLDER",\n "type": CredentialsTypes.card\n }\n }\n )\n print(res);\nexcept APIAuthenticationError as err:\n print(f"Authentication fail: {err.message}")\nexcept APIResponseError as err:\n print(f"Exception: {err.error}; Message: {err.message}")\n```',
|
|
21
21
|
'author': 'PaymentsGate',
|
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
from dataclasses import dataclass
|
|
3
|
-
import datetime
|
|
4
|
-
import json
|
|
5
|
-
from typing import Optional, List
|
|
6
|
-
|
|
7
|
-
from paymentsgate.enums import (
|
|
8
|
-
Currencies,
|
|
9
|
-
InvoiceTypes,
|
|
10
|
-
Languages,
|
|
11
|
-
Statuses,
|
|
12
|
-
TTLUnits,
|
|
13
|
-
CurrencyTypes,
|
|
14
|
-
FeesStrategy,
|
|
15
|
-
InvoiceDirection,
|
|
16
|
-
CredentialsTypes
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
from pydantic import BaseModel, ConfigDict
|
|
20
|
-
|
|
21
|
-
@dataclass
|
|
22
|
-
class Credentials:
|
|
23
|
-
def __init__(
|
|
24
|
-
self,
|
|
25
|
-
account_id: str,
|
|
26
|
-
merchant_id: str,
|
|
27
|
-
project_id: str,
|
|
28
|
-
private_key: str,
|
|
29
|
-
public_key: str
|
|
30
|
-
):
|
|
31
|
-
self.account_id = account_id
|
|
32
|
-
self.merchant_id = merchant_id
|
|
33
|
-
self.project_id = project_id
|
|
34
|
-
self.private_key = private_key
|
|
35
|
-
self.public_key = public_key
|
|
36
|
-
|
|
37
|
-
@classmethod
|
|
38
|
-
def fromFile(cls, filename):
|
|
39
|
-
data = json.load(open(filename))
|
|
40
|
-
return cls(data.get('account_id'),
|
|
41
|
-
data.get('merchant_id'),
|
|
42
|
-
data.get('project_id'),
|
|
43
|
-
data.get('private_key'),
|
|
44
|
-
data.get('public_key'))
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
@dataclass
|
|
48
|
-
class PayInFingerprintBrowserModel:
|
|
49
|
-
acceptHeader: str
|
|
50
|
-
colorDepth: int
|
|
51
|
-
language: str
|
|
52
|
-
screenHeight: int
|
|
53
|
-
screenWidth: int
|
|
54
|
-
timezone: str
|
|
55
|
-
userAgent: str
|
|
56
|
-
javaEnabled: bool
|
|
57
|
-
windowHeight: int
|
|
58
|
-
windowWidth: int
|
|
59
|
-
|
|
60
|
-
@dataclass
|
|
61
|
-
class PayInFingerprintModel:
|
|
62
|
-
fingerprint: str
|
|
63
|
-
ip: str
|
|
64
|
-
country: str
|
|
65
|
-
city: str
|
|
66
|
-
state: str
|
|
67
|
-
zip: str
|
|
68
|
-
browser: Optional[PayInFingerprintBrowserModel]
|
|
69
|
-
|
|
70
|
-
@dataclass
|
|
71
|
-
class PayInModel:
|
|
72
|
-
amount: float
|
|
73
|
-
currency: Currencies
|
|
74
|
-
invoiceId: Optional[str] # idempotent key
|
|
75
|
-
clientId: Optional[str]
|
|
76
|
-
type: InvoiceTypes
|
|
77
|
-
bankId: Optional[str]
|
|
78
|
-
trusted: Optional[bool]
|
|
79
|
-
successUrl: Optional[str]
|
|
80
|
-
failUrl: Optional[str]
|
|
81
|
-
backUrl: Optional[str]
|
|
82
|
-
clientCard: Optional[str]
|
|
83
|
-
fingerprint: Optional[PayInFingerprintModel]
|
|
84
|
-
lang: Optional[Languages]
|
|
85
|
-
|
|
86
|
-
@dataclass
|
|
87
|
-
class PayInResponseModel:
|
|
88
|
-
id: str
|
|
89
|
-
status: Statuses
|
|
90
|
-
type: InvoiceTypes
|
|
91
|
-
url: str
|
|
92
|
-
|
|
93
|
-
@dataclass
|
|
94
|
-
class PayOutRecipientModel:
|
|
95
|
-
account_number: str
|
|
96
|
-
account_owner: Optional[str]
|
|
97
|
-
account_iban: Optional[str]
|
|
98
|
-
account_swift: Optional[str]
|
|
99
|
-
account_phone: Optional[str]
|
|
100
|
-
account_bic: Optional[str]
|
|
101
|
-
account_ewallet_name: Optional[str]
|
|
102
|
-
account_email: Optional[str]
|
|
103
|
-
account_bank_id: Optional[str]
|
|
104
|
-
type: Optional[CredentialsTypes]
|
|
105
|
-
|
|
106
|
-
@dataclass
|
|
107
|
-
class PayOutModel:
|
|
108
|
-
currency: Optional[Currencies] # currency from, by default = usdt
|
|
109
|
-
currencyTo:Currencies
|
|
110
|
-
amount: float
|
|
111
|
-
invoiceId: Optional[str] # idempotent key
|
|
112
|
-
clientId: Optional[str]
|
|
113
|
-
ttl: Optional[int]
|
|
114
|
-
ttl_unit: Optional[TTLUnits]
|
|
115
|
-
finalAmount: Optional[float]
|
|
116
|
-
sender_name: Optional[str]
|
|
117
|
-
baseCurrency: Optional[CurrencyTypes]
|
|
118
|
-
feesStrategy: Optional[FeesStrategy]
|
|
119
|
-
recipient: PayOutRecipientModel
|
|
120
|
-
quoteId: Optional[str]
|
|
121
|
-
|
|
122
|
-
@dataclass
|
|
123
|
-
class PayOutResponseModel:
|
|
124
|
-
id: str
|
|
125
|
-
status: Statuses
|
|
126
|
-
|
|
127
|
-
@dataclass
|
|
128
|
-
class GetQuoteModel:
|
|
129
|
-
currency_from: Currencies
|
|
130
|
-
currency_to: Currencies
|
|
131
|
-
amount: float
|
|
132
|
-
subtype: InvoiceTypes
|
|
133
|
-
|
|
134
|
-
@dataclass
|
|
135
|
-
class QuoteEntity:
|
|
136
|
-
currency_from: CurrencyModel
|
|
137
|
-
currency_to: CurrencyModel
|
|
138
|
-
pair: str
|
|
139
|
-
rate: float
|
|
140
|
-
|
|
141
|
-
@dataclass
|
|
142
|
-
class GetQuoteResponseModel:
|
|
143
|
-
id: Optional[str] = None
|
|
144
|
-
finalAmount: Optional[float] = None
|
|
145
|
-
direction: Optional[InvoiceDirection] = None
|
|
146
|
-
fullRate: Optional[float] = None
|
|
147
|
-
fullRateReverse: Optional[float] = None
|
|
148
|
-
fees: Optional[float] = None
|
|
149
|
-
fees_percent: Optional[float] = None
|
|
150
|
-
quotes: Optional[List[QuoteEntity]] = None
|
|
151
|
-
expiredAt: Optional[datetime.datetime] = None
|
|
152
|
-
|
|
153
|
-
#deprecated
|
|
154
|
-
currency_from: Optional[CurrencyModel] = None
|
|
155
|
-
currency_to: Optional[CurrencyModel] = None
|
|
156
|
-
currency_middle: Optional[CurrencyModel] = None
|
|
157
|
-
rate1: Optional[float] = None
|
|
158
|
-
rate2: Optional[float] = None
|
|
159
|
-
rate3: Optional[float] = None
|
|
160
|
-
net_amount: Optional[float] = None
|
|
161
|
-
metadata: Optional[object] = None
|
|
162
|
-
|
|
163
|
-
@dataclass
|
|
164
|
-
class DepositAddressResponseModel:
|
|
165
|
-
currency: Currencies
|
|
166
|
-
address: str
|
|
167
|
-
expiredAt: datetime
|
|
168
|
-
|
|
169
|
-
@dataclass
|
|
170
|
-
class CurrencyModel:
|
|
171
|
-
_id: str
|
|
172
|
-
type: CurrencyTypes
|
|
173
|
-
code: Currencies
|
|
174
|
-
symbol: str
|
|
175
|
-
label: Optional[str]
|
|
176
|
-
decimal: int
|
|
177
|
-
countryCode: Optional[str]
|
|
178
|
-
countryName: Optional[str]
|
|
179
|
-
|
|
180
|
-
@dataclass
|
|
181
|
-
class BankModel:
|
|
182
|
-
name: str
|
|
183
|
-
title: str
|
|
184
|
-
currency: Currencies
|
|
185
|
-
fpsId: str
|
|
186
|
-
|
|
187
|
-
@dataclass
|
|
188
|
-
class InvoiceStatusModel:
|
|
189
|
-
name: Statuses
|
|
190
|
-
createdAt: datetime
|
|
191
|
-
updatedAt: datetime
|
|
192
|
-
|
|
193
|
-
@dataclass
|
|
194
|
-
class InvoiceAmountModel:
|
|
195
|
-
crypto: float
|
|
196
|
-
fiat: float
|
|
197
|
-
fiat_net: float
|
|
198
|
-
|
|
199
|
-
@dataclass
|
|
200
|
-
class InvoiceMetadataModel:
|
|
201
|
-
invoiceId: Optional[str]
|
|
202
|
-
clientId: Optional[str]
|
|
203
|
-
fiatAmount: Optional[float]
|
|
204
|
-
|
|
205
|
-
@dataclass
|
|
206
|
-
class InvoiceModel:
|
|
207
|
-
_id: str
|
|
208
|
-
orderId: str
|
|
209
|
-
projectId: str
|
|
210
|
-
currencyFrom: CurrencyModel
|
|
211
|
-
currencyTo: CurrencyModel
|
|
212
|
-
direction: InvoiceDirection
|
|
213
|
-
amount: float
|
|
214
|
-
status: InvoiceStatusModel
|
|
215
|
-
amounts: InvoiceAmountModel
|
|
216
|
-
metadata: InvoiceMetadataModel
|
|
217
|
-
receiptUrls: List[str]
|
|
218
|
-
isExpired: bool
|
|
219
|
-
createdAt: datetime
|
|
220
|
-
updatedAt: datetime
|
|
221
|
-
expiredAt: datetime
|
|
222
|
-
|
|
223
|
-
@dataclass
|
|
224
|
-
class AssetsAccountModel:
|
|
225
|
-
currency: CurrencyModel;
|
|
226
|
-
total: float
|
|
227
|
-
pending: float
|
|
228
|
-
available: float
|
|
229
|
-
|
|
230
|
-
@dataclass
|
|
231
|
-
class AssetsResponseModel:
|
|
232
|
-
assets: List[AssetsAccountModel]
|
|
233
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|