paymentsgate 1.4.8__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.8 → paymentsgate-1.5.0}/PKG-INFO +1 -1
- {paymentsgate-1.4.8 → paymentsgate-1.5.0}/paymentsgate/client.py +121 -59
- {paymentsgate-1.4.8 → paymentsgate-1.5.0}/paymentsgate/enums.py +57 -22
- {paymentsgate-1.4.8 → 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.8 → paymentsgate-1.5.0}/paymentsgate/transport.py +5 -8
- paymentsgate-1.5.0/paymentsgate/types.py +9 -0
- {paymentsgate-1.4.8 → paymentsgate-1.5.0}/pyproject.toml +1 -1
- {paymentsgate-1.4.8 → paymentsgate-1.5.0}/setup.py +1 -1
- paymentsgate-1.4.8/paymentsgate/models.py +0 -233
- {paymentsgate-1.4.8 → paymentsgate-1.5.0}/LICENSE +0 -0
- {paymentsgate-1.4.8 → paymentsgate-1.5.0}/README.md +0 -0
- {paymentsgate-1.4.8 → paymentsgate-1.5.0}/paymentsgate/__init__.py +0 -0
- {paymentsgate-1.4.8 → paymentsgate-1.5.0}/paymentsgate/cache.py +0 -0
- {paymentsgate-1.4.8 → paymentsgate-1.5.0}/paymentsgate/logger.py +0 -0
- {paymentsgate-1.4.8 → 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,45 +85,80 @@ 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
|
|
|
93
|
-
def
|
|
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
|
+
|
|
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,
|
|
100
119
|
signature=False,
|
|
101
|
-
body=
|
|
120
|
+
body=params
|
|
102
121
|
)
|
|
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
|
|
|
112
|
-
def
|
|
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
|
+
|
|
149
|
+
def Status(self, id: str) -> InvoiceModel:
|
|
113
150
|
# Prepare request
|
|
114
151
|
request = Request(
|
|
115
152
|
method="get",
|
|
116
|
-
path=ApiPaths.invoices_info,
|
|
153
|
+
path=ApiPaths.invoices_info.replace(':id', id),
|
|
117
154
|
content_type='application/json',
|
|
118
155
|
noAuth=False,
|
|
119
156
|
signature=False,
|
|
120
|
-
body=request
|
|
121
157
|
)
|
|
122
158
|
|
|
123
159
|
# Handle response
|
|
124
160
|
response = self._send_request(request)
|
|
125
|
-
self.
|
|
161
|
+
self.log(request, response)
|
|
126
162
|
if not response.success:
|
|
127
163
|
raise APIResponseError(response)
|
|
128
164
|
|
|
@@ -131,23 +167,25 @@ class ApiClient:
|
|
|
131
167
|
@property
|
|
132
168
|
def token(self) -> AccessToken | None:
|
|
133
169
|
# First check if valid token is cached
|
|
134
|
-
token = self.cache.get_token('
|
|
135
|
-
refresh = self.cache.get_token('
|
|
170
|
+
token = self.cache.get_token('AccessToken')
|
|
171
|
+
refresh = self.cache.get_token('RefreshToken')
|
|
172
|
+
|
|
136
173
|
if token is not None and not token.is_expired:
|
|
137
174
|
return token
|
|
138
175
|
else:
|
|
139
176
|
# try to refresh token
|
|
140
177
|
if refresh is not None and not refresh.is_expired:
|
|
141
|
-
refreshed = self._refresh_token()
|
|
178
|
+
refreshed = self._refresh_token(token, refresh)
|
|
142
179
|
|
|
143
180
|
if (refreshed.success):
|
|
144
181
|
access = AccessToken(
|
|
145
|
-
|
|
182
|
+
refreshed.json_body["access_token"]
|
|
146
183
|
)
|
|
147
184
|
refresh = RefreshToken(
|
|
148
|
-
|
|
149
|
-
int(
|
|
185
|
+
refreshed.json_body["refresh_token"],
|
|
186
|
+
int(refreshed.json_body["expires_in"]),
|
|
150
187
|
)
|
|
188
|
+
|
|
151
189
|
self.cache.set_token(access)
|
|
152
190
|
self.cache.set_token(refresh)
|
|
153
191
|
|
|
@@ -158,12 +196,13 @@ class ApiClient:
|
|
|
158
196
|
if response.success:
|
|
159
197
|
|
|
160
198
|
access = AccessToken(
|
|
161
|
-
response.
|
|
199
|
+
response.json_body["access_token"]
|
|
162
200
|
)
|
|
163
201
|
refresh = RefreshToken(
|
|
164
|
-
response.
|
|
165
|
-
int(response.
|
|
202
|
+
response.json_body["refresh_token"],
|
|
203
|
+
int(response.json_body["expires_in"]),
|
|
166
204
|
)
|
|
205
|
+
|
|
167
206
|
self.cache.set_token(access)
|
|
168
207
|
self.cache.set_token(refresh)
|
|
169
208
|
|
|
@@ -175,7 +214,8 @@ class ApiClient:
|
|
|
175
214
|
"""
|
|
176
215
|
Send a specified Request to the GoPay REST API and process the response
|
|
177
216
|
"""
|
|
178
|
-
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
|
|
179
219
|
# Add Bearer authentication to headers if needed
|
|
180
220
|
headers = request.headers or {}
|
|
181
221
|
if not request.noAuth:
|
|
@@ -185,35 +225,48 @@ class ApiClient:
|
|
|
185
225
|
|
|
186
226
|
if (request.method == 'get'):
|
|
187
227
|
params = urlencode(body)
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
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
|
|
194
238
|
else:
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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:
|
|
202
252
|
|
|
203
253
|
# Build Response instance, try to decode body as JSON
|
|
204
|
-
response = Response(raw_body=r.content,
|
|
254
|
+
response = Response(raw_body=r.content, json_body={}, status_code=r.status_code)
|
|
205
255
|
|
|
206
256
|
if (self.REQUEST_DEBUG):
|
|
207
257
|
print(f"{request.method} => {self.baseUrl}{request.path} => {response.status_code}")
|
|
208
258
|
|
|
209
259
|
try:
|
|
210
|
-
response.
|
|
260
|
+
response.json_body = r.json()
|
|
211
261
|
except json.JSONDecodeError:
|
|
212
262
|
pass
|
|
213
263
|
|
|
214
|
-
self.
|
|
264
|
+
self.log(request, response)
|
|
215
265
|
return response
|
|
216
266
|
|
|
267
|
+
def log(self, request: Request, response: Response):
|
|
268
|
+
Logger(self, request, response)
|
|
269
|
+
|
|
217
270
|
def _get_token(self) -> Response:
|
|
218
271
|
# Prepare request
|
|
219
272
|
request = Request(
|
|
@@ -225,18 +278,27 @@ class ApiClient:
|
|
|
225
278
|
)
|
|
226
279
|
# Handle response
|
|
227
280
|
response = self._send_request(request)
|
|
228
|
-
self.
|
|
281
|
+
self.log(request, response)
|
|
229
282
|
return response
|
|
230
283
|
|
|
231
|
-
def _refresh_token(self) -> Response:
|
|
284
|
+
def _refresh_token(self, access: AccessToken, refresh: RefreshToken) -> Response:
|
|
232
285
|
# Prepare request
|
|
233
286
|
request = Request(
|
|
234
287
|
method="post",
|
|
235
288
|
path=ApiPaths.token_refresh,
|
|
236
289
|
content_type='application/json',
|
|
237
|
-
|
|
290
|
+
noAuth=True,
|
|
291
|
+
headers={"Authorization": f"Bearer {access.token}" },
|
|
292
|
+
body={"refresh_token": refresh.token},
|
|
238
293
|
)
|
|
239
294
|
# Handle response
|
|
240
295
|
response = self._send_request(request)
|
|
241
|
-
self.
|
|
296
|
+
self.log(request, response)
|
|
242
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
|