pyXRocketAPI 0.1.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.
- pyxrocketapi-0.1.0/LICENSE +21 -0
- pyxrocketapi-0.1.0/PKG-INFO +52 -0
- pyxrocketapi-0.1.0/README.md +33 -0
- pyxrocketapi-0.1.0/pyXRocketAPI/__init__.py +3 -0
- pyxrocketapi-0.1.0/pyXRocketAPI/api.py +506 -0
- pyxrocketapi-0.1.0/pyXRocketAPI/exceptions.py +22 -0
- pyxrocketapi-0.1.0/pyXRocketAPI/models.py +692 -0
- pyxrocketapi-0.1.0/pyXRocketAPI/version.py +3 -0
- pyxrocketapi-0.1.0/pyXRocketAPI.egg-info/PKG-INFO +52 -0
- pyxrocketapi-0.1.0/pyXRocketAPI.egg-info/SOURCES.txt +14 -0
- pyxrocketapi-0.1.0/pyXRocketAPI.egg-info/dependency_links.txt +1 -0
- pyxrocketapi-0.1.0/pyXRocketAPI.egg-info/requires.txt +1 -0
- pyxrocketapi-0.1.0/pyXRocketAPI.egg-info/top_level.txt +1 -0
- pyxrocketapi-0.1.0/pyproject.toml +30 -0
- pyxrocketapi-0.1.0/setup.cfg +4 -0
- pyxrocketapi-0.1.0/tests/test_api.py +113 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Badiboy
|
|
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.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyXRocketAPI
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python client for the xRocket Pay API
|
|
5
|
+
Author: Badiboy
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Badiboy/pyXRocketAPI
|
|
8
|
+
Project-URL: Documentation, https://docs.xrocket.exchange/api/pay/pay-api-overview
|
|
9
|
+
Project-URL: Repository, https://github.com/Badiboy/pyXRocketAPI
|
|
10
|
+
Keywords: xrocket,pay,crypto,payments,api
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
License-File: LICENSE
|
|
17
|
+
Requires-Dist: requests>=2.28
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
|
|
20
|
+
# pyXRocketAPI
|
|
21
|
+
|
|
22
|
+
**pyXRocketAPI** is a Python client for the [xRocket Pay API](https://docs.xrocket.exchange/api/pay/pay-api-overview). It supports application information, balances, invoices, cheques, payouts, withdrawals, currency rates, and health checks.
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
```shell
|
|
27
|
+
pip install pyXRocketAPI
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Quick start
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
from pyXRocketAPI import xRocketPayAPI
|
|
34
|
+
|
|
35
|
+
client = xRocketPayAPI(token="your-pay-api-token")
|
|
36
|
+
invoice = client.create_invoice(price_currency="USDT", price_amount="10.00")
|
|
37
|
+
print(invoice.id, invoice.links.web_link)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
For integration testing, use the xRocket testnet instead of production:
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
client = xRocketPayAPI(token="testnet-token", testnet=True)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Safety
|
|
47
|
+
|
|
48
|
+
The token grants access to the application and must not be committed to source control. Financial POST operations are not retried automatically. Supply and retain the relevant client identifier (`client_invoice_id`, `client_payout_id`, `client_cheque_id`, or `client_withdrawal_id`) so that a timed-out operation can be reconciled safely.
|
|
49
|
+
|
|
50
|
+
Errors from the API raise `xRocketAPIException`; its `problem_type`, `kind`, `status`, and `instance` attributes expose the RFC 9457 error response.
|
|
51
|
+
|
|
52
|
+
_AI-supported creation._
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# pyXRocketAPI
|
|
2
|
+
|
|
3
|
+
**pyXRocketAPI** is a Python client for the [xRocket Pay API](https://docs.xrocket.exchange/api/pay/pay-api-overview). It supports application information, balances, invoices, cheques, payouts, withdrawals, currency rates, and health checks.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```shell
|
|
8
|
+
pip install pyXRocketAPI
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick start
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from pyXRocketAPI import xRocketPayAPI
|
|
15
|
+
|
|
16
|
+
client = xRocketPayAPI(token="your-pay-api-token")
|
|
17
|
+
invoice = client.create_invoice(price_currency="USDT", price_amount="10.00")
|
|
18
|
+
print(invoice.id, invoice.links.web_link)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
For integration testing, use the xRocket testnet instead of production:
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
client = xRocketPayAPI(token="testnet-token", testnet=True)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Safety
|
|
28
|
+
|
|
29
|
+
The token grants access to the application and must not be committed to source control. Financial POST operations are not retried automatically. Supply and retain the relevant client identifier (`client_invoice_id`, `client_payout_id`, `client_cheque_id`, or `client_withdrawal_id`) so that a timed-out operation can be reconciled safely.
|
|
30
|
+
|
|
31
|
+
Errors from the API raise `xRocketAPIException`; its `problem_type`, `kind`, `status`, and `instance` attributes expose the RFC 9457 error response.
|
|
32
|
+
|
|
33
|
+
_AI-supported creation._
|
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
from collections.abc import Iterable, Mapping
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
import requests
|
|
5
|
+
|
|
6
|
+
from .exceptions import xRocketAPIException
|
|
7
|
+
from .models import App, Balance, Cheque, ChequesList, Currency, Invoice, InvoicePaymentAddress, InvoicePaymentsList, InvoicesList, MassPayouts, xPage, Payout, PayoutsList, Rate, Withdrawal, WithdrawalLink, WithdrawalQuotas, WithdrawalsList, xRocketObject
|
|
8
|
+
|
|
9
|
+
PRODUCTION_API_URL = "https://pay.api.xrocket.exchange"
|
|
10
|
+
TESTNET_API_URL = "https://pay.api.testnet.xrocket.exchange"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _without_none(**values: Any) -> dict[str, Any]:
|
|
14
|
+
"""Keep valid falsey API values while omitting arguments not supplied."""
|
|
15
|
+
return {key: value for key, value in values.items() if value is not None}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _identifier(first_name: str, first_value: str | None, second_name: str, second_value: str | None) -> dict[str, str]:
|
|
19
|
+
if first_value is None and second_value is None:
|
|
20
|
+
raise ValueError(f"Specify {first_name} or {second_name}.")
|
|
21
|
+
return _without_none(**{first_name: first_value, second_name: second_value})
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class xRocketPayAPI:
|
|
25
|
+
"""Client for the current xRocket Pay API.
|
|
26
|
+
|
|
27
|
+
Parameters
|
|
28
|
+
----------
|
|
29
|
+
token:
|
|
30
|
+
App-specific Pay API Bearer token. Public calls such as
|
|
31
|
+
``health_check()`` and ``get_available_currencies()`` do not require
|
|
32
|
+
one.
|
|
33
|
+
testnet:
|
|
34
|
+
Select the xRocket Pay testnet URL. A testnet token is required.
|
|
35
|
+
timeout:
|
|
36
|
+
Timeout passed to every request, in seconds. ``None`` uses requests'
|
|
37
|
+
default behaviour.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
def __init__(
|
|
41
|
+
self,
|
|
42
|
+
token: str | None = None,
|
|
43
|
+
testnet: bool = False,
|
|
44
|
+
timeout: float | tuple[float, float] | None = 10,
|
|
45
|
+
) -> None:
|
|
46
|
+
self.token = token
|
|
47
|
+
self.timeout = timeout
|
|
48
|
+
self.base_url = TESTNET_API_URL if testnet else PRODUCTION_API_URL
|
|
49
|
+
|
|
50
|
+
def _request(
|
|
51
|
+
self,
|
|
52
|
+
method: str,
|
|
53
|
+
path: str,
|
|
54
|
+
params: Mapping[str, Any] | None = None,
|
|
55
|
+
body: Mapping[str, Any] | None = None,
|
|
56
|
+
auth_required: bool = True,
|
|
57
|
+
) -> Any:
|
|
58
|
+
"""Send one request to the xRocket Pay REST API.
|
|
59
|
+
|
|
60
|
+
The method builds the standard ``Accept`` header, optionally adds the
|
|
61
|
+
application's Bearer token, sends a JSON request, and converts a
|
|
62
|
+
non-success response from the API's RFC 9457 Problem Details format
|
|
63
|
+
into :class:`xRocketAPIException`.
|
|
64
|
+
|
|
65
|
+
:param method: HTTP method, for example ``"GET"`` or ``"POST"``.
|
|
66
|
+
:param path: API path beginning with ``/``, appended to the selected
|
|
67
|
+
production or testnet base URL.
|
|
68
|
+
:param params: Optional query-string parameters.
|
|
69
|
+
:param body: Optional JSON request body.
|
|
70
|
+
:param auth_required: Require an API token and send it in the Bearer
|
|
71
|
+
header. Public endpoints pass ``False`` explicitly; rates may opt
|
|
72
|
+
into authorization.
|
|
73
|
+
:return: Parsed JSON response, or ``None`` for an empty ``204``
|
|
74
|
+
response.
|
|
75
|
+
:raises xRocketAPIException: If a required token is absent, a network
|
|
76
|
+
request fails, the response is not a 2xx success, or a successful
|
|
77
|
+
response does not contain valid JSON.
|
|
78
|
+
"""
|
|
79
|
+
headers = {"Accept": "application/json"}
|
|
80
|
+
if auth_required:
|
|
81
|
+
if not self.token:
|
|
82
|
+
raise xRocketAPIException("This endpoint requires an xRocket Pay API token.")
|
|
83
|
+
headers["Authorization"] = f"Bearer {self.token}"
|
|
84
|
+
|
|
85
|
+
try:
|
|
86
|
+
response = requests.request(
|
|
87
|
+
method, f"{self.base_url}{path}", params=params, json=body, headers=headers, timeout=self.timeout
|
|
88
|
+
)
|
|
89
|
+
except requests.RequestException as error:
|
|
90
|
+
raise xRocketAPIException(f"Request to xRocket Pay failed: {error}") from error
|
|
91
|
+
|
|
92
|
+
if response.status_code < 200 or response.status_code >= 300:
|
|
93
|
+
try:
|
|
94
|
+
problem = response.json()
|
|
95
|
+
except ValueError:
|
|
96
|
+
problem = {}
|
|
97
|
+
detail = problem.get("detail") or problem.get("title") or response.text or "xRocket Pay request failed"
|
|
98
|
+
raise xRocketAPIException(
|
|
99
|
+
detail,
|
|
100
|
+
status=response.status_code,
|
|
101
|
+
problem_type=problem.get("type"),
|
|
102
|
+
title=problem.get("title"),
|
|
103
|
+
detail=problem.get("detail"),
|
|
104
|
+
instance=problem.get("instance"),
|
|
105
|
+
kind=problem.get("kind"),
|
|
106
|
+
info=problem.get("info"),
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
if response.status_code == 204 or not response.content:
|
|
110
|
+
return None
|
|
111
|
+
try:
|
|
112
|
+
return response.json()
|
|
113
|
+
except ValueError as error:
|
|
114
|
+
raise xRocketAPIException("xRocket Pay returned invalid JSON.", status=response.status_code) from error
|
|
115
|
+
|
|
116
|
+
def health_check(self) -> xRocketObject:
|
|
117
|
+
"""Run the public health check.
|
|
118
|
+
|
|
119
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/health-controller-health
|
|
120
|
+
|
|
121
|
+
:return: ``xRocketObject``.
|
|
122
|
+
"""
|
|
123
|
+
return xRocketObject.de_json(self._request("GET", "/health", auth_required=False), process_mode=2)
|
|
124
|
+
|
|
125
|
+
def get_app_info(self) -> App:
|
|
126
|
+
"""Get information about your application.
|
|
127
|
+
|
|
128
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/app-controller-get-app
|
|
129
|
+
|
|
130
|
+
:return: ``App``.
|
|
131
|
+
"""
|
|
132
|
+
return App.de_json(self._request("GET", "/api/v1/app-info"))
|
|
133
|
+
|
|
134
|
+
def get_balances(self) -> list[Balance]:
|
|
135
|
+
"""Get balances of your application.
|
|
136
|
+
|
|
137
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/app-controller-get-app-balances
|
|
138
|
+
|
|
139
|
+
:return: ``list[Balance]``.
|
|
140
|
+
"""
|
|
141
|
+
data = self._request("GET", "/api/v1/balances")
|
|
142
|
+
return [Balance.de_json(item) for item in data.get("balances", [])]
|
|
143
|
+
|
|
144
|
+
def get_currencies(self, kind: str | None = None) -> list[Currency]:
|
|
145
|
+
"""Get available currencies.
|
|
146
|
+
|
|
147
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/currencies-controller-get-currencies
|
|
148
|
+
|
|
149
|
+
:param kind: No description is provided.
|
|
150
|
+
:return: ``list[Currency]``.
|
|
151
|
+
"""
|
|
152
|
+
data = self._request(
|
|
153
|
+
"GET", "/api/v1/currencies", params=_without_none(kind=kind), auth_required=False
|
|
154
|
+
)
|
|
155
|
+
return [Currency.de_json(item) for item in data]
|
|
156
|
+
|
|
157
|
+
def get_rates(self, base: str, assets: Iterable[str], authorize: bool = False) -> list[Rate]:
|
|
158
|
+
"""Get currencies rates (optional auth).
|
|
159
|
+
|
|
160
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/rate-controller-get-rates
|
|
161
|
+
|
|
162
|
+
:param base: Fiat currency.
|
|
163
|
+
:param assets: Asset codes.
|
|
164
|
+
:param authorize: Send the optional Bearer authorization header.
|
|
165
|
+
:return: ``list[Rate]``.
|
|
166
|
+
"""
|
|
167
|
+
data = self._request(
|
|
168
|
+
"GET", "/api/v1/rates", params={"base": base, "assets": list(assets)},
|
|
169
|
+
auth_required=authorize,
|
|
170
|
+
)
|
|
171
|
+
return [Rate.de_json(item) for item in data]
|
|
172
|
+
|
|
173
|
+
def create_invoice(
|
|
174
|
+
self,
|
|
175
|
+
price_currency: str,
|
|
176
|
+
price_amount: str | None = None,
|
|
177
|
+
min_payment: str | None = None,
|
|
178
|
+
num_payments: int | None = None,
|
|
179
|
+
payout_currency: str | None = None,
|
|
180
|
+
pay_currencies: Iterable[str] | None = None,
|
|
181
|
+
client_invoice_id: str | None = None,
|
|
182
|
+
description: str | None = None,
|
|
183
|
+
expires_in: int | None = None,
|
|
184
|
+
callback: Mapping[str, Any] | None = None,
|
|
185
|
+
url: Mapping[str, Any] | None = None,
|
|
186
|
+
customer: Mapping[str, Any] | None = None,
|
|
187
|
+
is_fee_paid_by_user: bool | None = None,
|
|
188
|
+
data: Mapping[str, Any] | None = None,
|
|
189
|
+
platform_id: str | None = None,
|
|
190
|
+
) -> Invoice:
|
|
191
|
+
"""Create invoice.
|
|
192
|
+
|
|
193
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/invoice-controller-create-invoice
|
|
194
|
+
|
|
195
|
+
:param price_currency: Invoice price currency (crypto or fiat).
|
|
196
|
+
:param price_amount: Invoice price amount.
|
|
197
|
+
:param min_payment: Minimum payment amount (for open-amount invoices).
|
|
198
|
+
:param num_payments: Num payments for invoice.
|
|
199
|
+
:param payout_currency: Invoice payout crypto currency.
|
|
200
|
+
:param pay_currencies: Crypto currencies which can be used to pay the invoice.
|
|
201
|
+
:param client_invoice_id: Client Invoice ID as assigned by the client.
|
|
202
|
+
:param description: Description for invoice.
|
|
203
|
+
:param expires_in: Payment expires in milliseconds.
|
|
204
|
+
:param callback: Callback data.
|
|
205
|
+
:param url: User redirect urls.
|
|
206
|
+
:param customer: Customer info.
|
|
207
|
+
:param is_fee_paid_by_user: If true, the user pays a commission.
|
|
208
|
+
:param data: Custom user data passed through and returned in callbacks/webhooks (max size 4KB).
|
|
209
|
+
:param platform_id: Platform identifier.
|
|
210
|
+
:return: ``Invoice``.
|
|
211
|
+
"""
|
|
212
|
+
body = _without_none(
|
|
213
|
+
priceCurrency=price_currency, priceAmount=price_amount, minPayment=min_payment, numPayments=num_payments,
|
|
214
|
+
payoutCurrency=payout_currency, payCurrencies=list(pay_currencies) if pay_currencies is not None else None,
|
|
215
|
+
clientInvoiceId=client_invoice_id, description=description, expiresIn=expires_in, callback=callback, url=url,
|
|
216
|
+
customer=customer, isFeePaidByUser=is_fee_paid_by_user, data=data, platformId=platform_id,
|
|
217
|
+
)
|
|
218
|
+
return Invoice.de_json(self._request("POST", "/api/v1/invoices", body=body))
|
|
219
|
+
|
|
220
|
+
def get_invoices_list(self, asset: str | None = None, fiat: str | None = None, ids: Iterable[str] | None = None,
|
|
221
|
+
status: str | None = None, cursor: str | None = None, limit: int | None = None) -> InvoicesList:
|
|
222
|
+
"""Get list of invoices.
|
|
223
|
+
|
|
224
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/invoice-controller-get-invoices
|
|
225
|
+
|
|
226
|
+
:param asset: Filtering invoices by asset.
|
|
227
|
+
:param fiat: Filtering invoices by fiat.
|
|
228
|
+
:param ids: Filtering invoices by ids.
|
|
229
|
+
:param status: Filtering invoices by status.
|
|
230
|
+
:param cursor: Cursor for pagination.
|
|
231
|
+
:param limit: No description is provided.
|
|
232
|
+
:return: ``InvoicesList``.
|
|
233
|
+
"""
|
|
234
|
+
params = _without_none(asset=asset, fiat=fiat, ids=list(ids) if ids is not None else None, status=status, cursor=cursor, limit=limit)
|
|
235
|
+
return InvoicesList.de_json(self._request("GET", "/api/v1/invoices", params=params))
|
|
236
|
+
|
|
237
|
+
def get_invoice_info(self, invoice_id: str | None = None, client_invoice_id: str | None = None) -> Invoice:
|
|
238
|
+
"""Get invoice info.
|
|
239
|
+
|
|
240
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/invoice-controller-get-invoice
|
|
241
|
+
Either invoiceId (xRocket) or clientInvoiceId (client-assigned) is required. If both are passed, invoiceId will be used.
|
|
242
|
+
|
|
243
|
+
:param invoice_id: xRocket Invoice ID. Either invoiceId or clientInvoiceId is required. If both are passed, invoiceId will be used.
|
|
244
|
+
:param client_invoice_id: Client Invoice ID assigned by the client. Either invoiceId or clientInvoiceId is required.
|
|
245
|
+
:return: ``Invoice``.
|
|
246
|
+
"""
|
|
247
|
+
return Invoice.de_json(self._request("GET", "/api/v1/invoice", params=_identifier("invoiceId", invoice_id, "clientInvoiceId", client_invoice_id)))
|
|
248
|
+
|
|
249
|
+
def delete_invoice(self, invoice_id: str | None = None, client_invoice_id: str | None = None) -> None:
|
|
250
|
+
"""Delete invoice.
|
|
251
|
+
|
|
252
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/invoice-controller-delete-invoice
|
|
253
|
+
Either invoiceId (xRocket) or clientInvoiceId (client-assigned) is required. If both are passed, invoiceId will be used.
|
|
254
|
+
|
|
255
|
+
:param invoice_id: xRocket Invoice ID. Either invoiceId or clientInvoiceId is required. If both are passed, invoiceId will be used.
|
|
256
|
+
:param client_invoice_id: Client Invoice ID assigned by the client. Either invoiceId or clientInvoiceId is required.
|
|
257
|
+
:return: ``None``.
|
|
258
|
+
"""
|
|
259
|
+
self._request("DELETE", "/api/v1/invoice", params=_identifier("invoiceId", invoice_id, "clientInvoiceId", client_invoice_id))
|
|
260
|
+
|
|
261
|
+
def get_invoice_payments(self, invoice_id: str | None = None, client_invoice_id: str | None = None,
|
|
262
|
+
cursor: str | None = None, limit: int | None = None) -> InvoicePaymentsList:
|
|
263
|
+
"""Get invoice payments.
|
|
264
|
+
|
|
265
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/invoice-controller-get-invoice-payments
|
|
266
|
+
Returns payments of an invoice in the same format as the payment_status_changed webhook. Either invoiceId (xRocket) or clientInvoiceId (client-assigned) is required. If both are passed, invoiceId will be used.
|
|
267
|
+
|
|
268
|
+
:param invoice_id: xRocket Invoice ID. Either invoiceId or clientInvoiceId is required. If both are passed, invoiceId will be used.
|
|
269
|
+
:param client_invoice_id: Client Invoice ID assigned by the client. Either invoiceId or clientInvoiceId is required.
|
|
270
|
+
:param cursor: Cursor for pagination.
|
|
271
|
+
:param limit: No description is provided.
|
|
272
|
+
:return: ``InvoicePaymentsList``.
|
|
273
|
+
"""
|
|
274
|
+
params = _identifier("invoiceId", invoice_id, "clientInvoiceId", client_invoice_id)
|
|
275
|
+
params.update(_without_none(cursor=cursor, limit=limit))
|
|
276
|
+
return InvoicePaymentsList.de_json(self._request("GET", "/api/v1/invoice/payments", params=params))
|
|
277
|
+
|
|
278
|
+
def create_invoice_payment_address(self, pay_network: str, invoice_id: str | None = None,
|
|
279
|
+
client_invoice_id: str | None = None) -> InvoicePaymentAddress:
|
|
280
|
+
"""Create invoice payment address.
|
|
281
|
+
|
|
282
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/invoice-payment-controller-create-invoice-payment-address
|
|
283
|
+
|
|
284
|
+
:param pay_network: Network code for payment.
|
|
285
|
+
:param invoice_id: xRocket Invoice ID. Either invoiceId or clientInvoiceId is required. If both are passed, invoiceId will be used.
|
|
286
|
+
:param client_invoice_id: Client Invoice ID assigned by the client. Either invoiceId or clientInvoiceId is required.
|
|
287
|
+
:return: ``InvoicePaymentAddress``.
|
|
288
|
+
"""
|
|
289
|
+
return InvoicePaymentAddress.de_json(self._request(
|
|
290
|
+
"POST", "/api/v1/invoices/payments/address",
|
|
291
|
+
params=_identifier("invoiceId", invoice_id, "clientInvoiceId", client_invoice_id), body={"payNetwork": pay_network},
|
|
292
|
+
))
|
|
293
|
+
|
|
294
|
+
def create_cheque(self, asset: str, amount: str, client_cheque_id: str | None = None, password: str | None = None,
|
|
295
|
+
description: str | None = None, callback: Mapping[str, Any] | None = None, url: Mapping[str, Any] | None = None,
|
|
296
|
+
target_type: str | None = None, target: str | None = None) -> Cheque:
|
|
297
|
+
"""Create cheque.
|
|
298
|
+
|
|
299
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/cheque-controller-create-cheque
|
|
300
|
+
Issue a personal cheque to perform an accept-type payout. The amount is reserved from the application balance and can be redeemed by the recipient or cancelled before redemption. When targetType and target are set, only the addressed user is allowed to redeem the cheque.
|
|
301
|
+
|
|
302
|
+
:param asset: Currency of transfer.
|
|
303
|
+
:param amount: Cheque amount.
|
|
304
|
+
:param client_cheque_id: Unique cheque ID in your system to prevent double spends.
|
|
305
|
+
:param password: Cheque password, the recipient has to enter it to redeem the cheque.
|
|
306
|
+
:param description: Description for cheque.
|
|
307
|
+
:param callback: Webhook settings for cheque activation updates.
|
|
308
|
+
:param url: User redirect urls after cheque activation.
|
|
309
|
+
:param target_type: Target type for cheque, has to be passed together with target.
|
|
310
|
+
:param target: Target for cheque, has to be passed together with targetType.
|
|
311
|
+
:return: ``Cheque``.
|
|
312
|
+
"""
|
|
313
|
+
return Cheque.de_json(self._request("POST", "/api/v1/cheques", body=_without_none(
|
|
314
|
+
asset=asset, amount=str(amount), clientChequeId=client_cheque_id, password=password, description=description,
|
|
315
|
+
callback=callback, url=url, targetType=target_type, target=target,
|
|
316
|
+
)))
|
|
317
|
+
|
|
318
|
+
def get_cheques_list(self, from_date: str | None = None, to_date: str | None = None, target_type: str | None = None,
|
|
319
|
+
target: str | None = None, state: str | None = None, cursor: str | None = None, limit: int | None = None) -> ChequesList:
|
|
320
|
+
"""Get list of cheques.
|
|
321
|
+
|
|
322
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/cheque-controller-get-cheques
|
|
323
|
+
List personal cheques issued for accept-type transfers. Use this to monitor pending, redeemed, or cancelled cheques. Cancelled cheques are excluded from the list.
|
|
324
|
+
|
|
325
|
+
:param from_date: From date (ISO 8601).
|
|
326
|
+
:param to_date: To date (ISO 8601).
|
|
327
|
+
:param target_type: Target type for cheque, has to be passed together with target.
|
|
328
|
+
:param target: Target identifier for cheque (depends on targetType), has to be passed together with targetType.
|
|
329
|
+
:param state: Cheque state.
|
|
330
|
+
:param cursor: Cursor for pagination.
|
|
331
|
+
:param limit: No description is provided.
|
|
332
|
+
:return: ``ChequesList``.
|
|
333
|
+
"""
|
|
334
|
+
return ChequesList.de_json(self._request("GET", "/api/v1/cheques", params=_without_none(
|
|
335
|
+
fromDate=from_date, toDate=to_date, targetType=target_type, target=target, state=state, cursor=cursor, limit=limit,
|
|
336
|
+
)))
|
|
337
|
+
|
|
338
|
+
def get_cheque_info(self, cheque_id: str | None = None, client_cheque_id: str | None = None) -> Cheque:
|
|
339
|
+
"""Get cheque info.
|
|
340
|
+
|
|
341
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/cheque-controller-get-cheque
|
|
342
|
+
Fetch details of a personal cheque used for an accept-type payout, including status and reserved amount. A cancelled cheque is returned with the deleted flag set.
|
|
343
|
+
|
|
344
|
+
:param cheque_id: Cheque id.
|
|
345
|
+
:param client_cheque_id: Unique cheque id in your system.
|
|
346
|
+
:return: ``Cheque``.
|
|
347
|
+
"""
|
|
348
|
+
return Cheque.de_json(self._request("GET", "/api/v1/cheque", params=_identifier("chequeId", cheque_id, "clientChequeId", client_cheque_id)))
|
|
349
|
+
|
|
350
|
+
def update_cheque(self, description: str, cheque_id: str | None = None, client_cheque_id: str | None = None) -> Cheque:
|
|
351
|
+
"""Update cheque.
|
|
352
|
+
|
|
353
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/cheque-controller-update-cheque
|
|
354
|
+
Modify an active unredeemed cheque. Only description can be updated, pass an empty string to clear it. The cheque must be in active state, not cancelled and not yet redeemed.
|
|
355
|
+
|
|
356
|
+
:param description: Cheque description (set empty string to clear description).
|
|
357
|
+
:param cheque_id: Cheque id.
|
|
358
|
+
:param client_cheque_id: Unique cheque id in your system.
|
|
359
|
+
:return: ``Cheque``.
|
|
360
|
+
"""
|
|
361
|
+
return Cheque.de_json(self._request("PUT", "/api/v1/cheques", params=_identifier("chequeId", cheque_id, "clientChequeId", client_cheque_id), body={"description": description}))
|
|
362
|
+
|
|
363
|
+
def delete_cheque(self, cheque_id: str | None = None, client_cheque_id: str | None = None) -> None:
|
|
364
|
+
"""Delete cheque.
|
|
365
|
+
|
|
366
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/cheque-controller-delete-cheque
|
|
367
|
+
Cancel an unredeemed personal cheque. Upon cancellation, the reserved funds are released back to the application balance.
|
|
368
|
+
|
|
369
|
+
:param cheque_id: Cheque id.
|
|
370
|
+
:param client_cheque_id: Unique cheque id in your system.
|
|
371
|
+
:return: ``None``.
|
|
372
|
+
"""
|
|
373
|
+
self._request("DELETE", "/api/v1/cheques", params=_identifier("chequeId", cheque_id, "clientChequeId", client_cheque_id))
|
|
374
|
+
|
|
375
|
+
def payout_funds_to_user(self, target: str, target_type: str, asset: str, amount: str, client_payout_id: str | None = None,
|
|
376
|
+
description: str | None = None, callback: Mapping[str, Any] | None = None) -> Payout:
|
|
377
|
+
"""Payout funds to user.
|
|
378
|
+
|
|
379
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/payout-controller-payout
|
|
380
|
+
|
|
381
|
+
:param target: Target.
|
|
382
|
+
:param target_type: Target type.
|
|
383
|
+
:param asset: Asset of transfer.
|
|
384
|
+
:param amount: Payout amount.
|
|
385
|
+
:param client_payout_id: Unique payout ID in your system to prevent double spends.
|
|
386
|
+
:param description: Payout description.
|
|
387
|
+
:param callback: Webhook settings for payout status updates.
|
|
388
|
+
:return: ``Payout``.
|
|
389
|
+
"""
|
|
390
|
+
return Payout.de_json(self._request("POST", "/api/v1/payouts", body=_without_none(
|
|
391
|
+
target=target, targetType=target_type, asset=asset, amount=str(amount), clientPayoutId=client_payout_id,
|
|
392
|
+
description=description, callback=callback,
|
|
393
|
+
)))
|
|
394
|
+
|
|
395
|
+
def get_payouts_list(self, from_date: str | None = None, to_date: str | None = None, cursor: str | None = None,
|
|
396
|
+
limit: int | None = None) -> PayoutsList:
|
|
397
|
+
"""Get payouts list.
|
|
398
|
+
|
|
399
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/payout-controller-get-list-payouts
|
|
400
|
+
|
|
401
|
+
:param from_date: From date (ISO 8601).
|
|
402
|
+
:param to_date: To date (ISO 8601).
|
|
403
|
+
:param cursor: Cursor for pagination.
|
|
404
|
+
:param limit: No description is provided.
|
|
405
|
+
:return: ``PayoutsList``.
|
|
406
|
+
"""
|
|
407
|
+
return PayoutsList.de_json(self._request("GET", "/api/v1/payouts", params=_without_none(fromDate=from_date, toDate=to_date, cursor=cursor, limit=limit)))
|
|
408
|
+
|
|
409
|
+
def get_payout_info(self, payout_id: str | None = None, client_payout_id: str | None = None) -> Payout:
|
|
410
|
+
"""Get payout info.
|
|
411
|
+
|
|
412
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/payout-controller-get-payout
|
|
413
|
+
|
|
414
|
+
:param payout_id: Payout ID.
|
|
415
|
+
:param client_payout_id: Unique payout ID in your system to prevent double spends.
|
|
416
|
+
:return: ``Payout``.
|
|
417
|
+
"""
|
|
418
|
+
return Payout.de_json(self._request("GET", "/api/v1/payout", params=_identifier("payoutId", payout_id, "clientPayoutId", client_payout_id)))
|
|
419
|
+
|
|
420
|
+
def create_mass_payouts(self, asset: str, payouts: Iterable[Mapping[str, Any]]) -> MassPayouts:
|
|
421
|
+
"""Create mass payouts (Telegram users only).
|
|
422
|
+
|
|
423
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/mass-payouts-controller-create-mass-payouts
|
|
424
|
+
|
|
425
|
+
:param asset: Asset of payouts.
|
|
426
|
+
:param payouts: List of payouts to process.
|
|
427
|
+
:return: ``MassPayouts``.
|
|
428
|
+
"""
|
|
429
|
+
return MassPayouts.de_json(self._request("POST", "/api/v1/mass-payouts", body={"asset": asset, "payouts": list(payouts)}))
|
|
430
|
+
|
|
431
|
+
def withdrawal_funds(self, client_withdrawal_id: str, network: str, address: str, asset: str, amount: str,
|
|
432
|
+
comment: str | None = None, callback: Mapping[str, Any] | None = None) -> Withdrawal:
|
|
433
|
+
"""Withdrawal funds from application to external wallet.
|
|
434
|
+
|
|
435
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/withdrawal-controller-create-withdrawal
|
|
436
|
+
|
|
437
|
+
:param client_withdrawal_id: Unique withdrawal ID in your system to prevent double spends.
|
|
438
|
+
:param network: Network code.
|
|
439
|
+
:param address: Withdrawal address.
|
|
440
|
+
:param asset: Asset code.
|
|
441
|
+
:param amount: Withdrawal amount.
|
|
442
|
+
:param comment: Withdrawal comment.
|
|
443
|
+
:param callback: Webhook settings for withdrawal status updates.
|
|
444
|
+
:return: ``Withdrawal``.
|
|
445
|
+
"""
|
|
446
|
+
return Withdrawal.de_json(self._request("POST", "/api/v1/withdrawals", body=_without_none(
|
|
447
|
+
clientWithdrawalId=client_withdrawal_id, network=network, address=address, asset=asset, amount=str(amount),
|
|
448
|
+
comment=comment, callback=callback,
|
|
449
|
+
)))
|
|
450
|
+
|
|
451
|
+
def get_withdrawals_list(self, from_date: str | None = None, to_date: str | None = None, status: str | None = None,
|
|
452
|
+
cursor: str | None = None, limit: int | None = None) -> WithdrawalsList:
|
|
453
|
+
"""Get application withdrawals.
|
|
454
|
+
|
|
455
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/withdrawal-controller-get-withdrawals
|
|
456
|
+
|
|
457
|
+
:param from_date: From date (ISO 8601).
|
|
458
|
+
:param to_date: To date (ISO 8601).
|
|
459
|
+
:param status: Withdrawal status.
|
|
460
|
+
:param cursor: Cursor for pagination.
|
|
461
|
+
:param limit: No description is provided.
|
|
462
|
+
:return: ``WithdrawalsList``.
|
|
463
|
+
"""
|
|
464
|
+
return WithdrawalsList.de_json(self._request("GET", "/api/v1/withdrawals", params=_without_none(
|
|
465
|
+
fromDate=from_date, toDate=to_date, status=status, cursor=cursor, limit=limit,
|
|
466
|
+
)))
|
|
467
|
+
|
|
468
|
+
def get_withdrawal_info(self, withdrawal_id: str | None = None, client_withdrawal_id: str | None = None) -> Withdrawal:
|
|
469
|
+
"""Get application withdrawal info.
|
|
470
|
+
|
|
471
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/withdrawal-controller-get-withdrawal
|
|
472
|
+
|
|
473
|
+
:param withdrawal_id: Withdrawal ID.
|
|
474
|
+
:param client_withdrawal_id: Unique withdrawal ID in your system to prevent double spends.
|
|
475
|
+
:return: ``Withdrawal``.
|
|
476
|
+
"""
|
|
477
|
+
return Withdrawal.de_json(self._request("GET", "/api/v1/withdrawal", params=_identifier("withdrawalId", withdrawal_id, "clientWithdrawalId", client_withdrawal_id)))
|
|
478
|
+
|
|
479
|
+
def get_withdrawal_quotas(self, network: str, asset: str) -> WithdrawalQuotas:
|
|
480
|
+
"""Get application withdrawal quotas.
|
|
481
|
+
|
|
482
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/withdrawal-controller-get-withdrawal-fees
|
|
483
|
+
|
|
484
|
+
:param network: Network code.
|
|
485
|
+
:param asset: Asset code.
|
|
486
|
+
:return: ``WithdrawalQuotas``.
|
|
487
|
+
"""
|
|
488
|
+
return WithdrawalQuotas.de_json(self._request("GET", "/api/v1/withdrawal-quotas", params={"network": network, "asset": asset}))
|
|
489
|
+
|
|
490
|
+
def create_withdrawal_link(self, network: str, address: str, asset: str, amount: str, comment: str | None = None,
|
|
491
|
+
platform: str | None = None) -> WithdrawalLink:
|
|
492
|
+
"""Create withdrawal link.
|
|
493
|
+
|
|
494
|
+
API: https://docs.xrocket.exchange/api/pay/reference/http/withdrawal-links-controller-create-withdrawal-link
|
|
495
|
+
|
|
496
|
+
:param network: Network code.
|
|
497
|
+
:param address: Withdrawal address.
|
|
498
|
+
:param asset: Asset code.
|
|
499
|
+
:param amount: Withdrawal amount.
|
|
500
|
+
:param comment: Withdrawal comment.
|
|
501
|
+
:param platform: Platform identifier (optional, use only if provided by xRocket).
|
|
502
|
+
:return: ``WithdrawalLink``.
|
|
503
|
+
"""
|
|
504
|
+
return WithdrawalLink.de_json(self._request("POST", "/api/v1/withdrawal-link", body=_without_none(
|
|
505
|
+
network=network, address=address, asset=asset, amount=str(amount), comment=comment, platform=platform,
|
|
506
|
+
)))
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
class xRocketAPIException(Exception):
|
|
2
|
+
"""An HTTP or transport failure returned while calling xRocket Pay."""
|
|
3
|
+
|
|
4
|
+
def __init__(
|
|
5
|
+
self,
|
|
6
|
+
message: str,
|
|
7
|
+
status: int | None = None,
|
|
8
|
+
problem_type: str | None = None,
|
|
9
|
+
title: str | None = None,
|
|
10
|
+
detail: str | None = None,
|
|
11
|
+
instance: str | None = None,
|
|
12
|
+
kind: str | None = None,
|
|
13
|
+
info: object | None = None,
|
|
14
|
+
) -> None:
|
|
15
|
+
super().__init__(message)
|
|
16
|
+
self.status = status
|
|
17
|
+
self.problem_type = problem_type
|
|
18
|
+
self.title = title
|
|
19
|
+
self.detail = detail
|
|
20
|
+
self.instance = instance
|
|
21
|
+
self.kind = kind
|
|
22
|
+
self.info = info
|