pyCryptomusAPI 0.0.7__tar.gz → 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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyCryptomusAPI
3
- Version: 0.0.7
3
+ Version: 0.1.0
4
4
  Summary: Python implementation of Cryptomus (https://cryptomus.com) pubilc API
5
5
  Home-page: https://github.com/Badiboy/pyCryptomusAPI
6
6
  Author: Badiboy
@@ -0,0 +1,624 @@
1
+ from hashlib import md5
2
+ from time import sleep
3
+ import base64
4
+ import requests
5
+
6
+ from .cryto_types import *
7
+
8
+ API_URL = "https://api.cryptomus.com/v1/"
9
+
10
+ # noinspection PyPep8Naming
11
+ class pyCryptomusAPIException(Exception):
12
+ def __init__(self, code, message, full_error = ""):
13
+ self.code = code
14
+ self.message = message
15
+ self.full_error = full_error
16
+ super().__init__(self.message)
17
+
18
+
19
+ # noinspection PyPep8Naming
20
+ class pyCryptomusAPI:
21
+ """
22
+ Cryptomus API Client
23
+ """
24
+
25
+ def __init__(self,
26
+ merchant_uuid, payment_api_key = None, payout_api_key = None,
27
+ print_errors = False, timeout = None, add_request_params = None):
28
+ """
29
+ Create the pyCryptomusAPI instance.
30
+
31
+ :param merchant_uuid: The merchant's uuid, which you can find in the merchant's personal account in the settings section.
32
+ :param payment_api_key: API key for processing payments
33
+ :param payout_api_key: API key for accepting payment and making payouts
34
+ :param print_errors: (Optional) Print dumps on request errors
35
+ :param timeout: (Optional) Request timeout
36
+ :param add_request_params: (List, Optional) Additional request parameters to pass with API calls
37
+ """
38
+ self.merchant_uuid = merchant_uuid
39
+ self.payment_api_key = payment_api_key
40
+ self.payout_api_key = payout_api_key
41
+ self.print_errors = print_errors
42
+ self.timeout = timeout
43
+ self.add_request_params = add_request_params
44
+ if (not self.payment_api_key) and (not self.payout_api_key):
45
+ raise Exception("You must specify at least one API key.")
46
+
47
+ def __request(self, method_url, mode, **kwargs):
48
+ """
49
+ Send request to API
50
+
51
+ :param method_url: (String) API method url (part)
52
+ :param mode: (Int) Method mode (1: payment, 2: payout)
53
+ :param kwargs: request data
54
+ """
55
+ if kwargs:
56
+ data = dict(kwargs)
57
+ else:
58
+ data = {}
59
+
60
+ if self.add_request_params:
61
+ data.update(self.add_request_params)
62
+
63
+ base_resp = None
64
+ try:
65
+ key = self.payment_api_key if (mode == 1) else self.payout_api_key
66
+ if not key:
67
+ raise pyCryptomusAPIException(-6, "Key is empty")
68
+ if not(key.isascii()):
69
+ raise pyCryptomusAPIException(-6, "Key contains non-ascii characters")
70
+ if not self.merchant_uuid:
71
+ raise pyCryptomusAPIException(-6, "Merchant UUID is empty")
72
+ if not(self.merchant_uuid.isascii()):
73
+ raise pyCryptomusAPIException(-6, "Merchant UUID contains non-ascii characters")
74
+ json_dumps = json.dumps(data)
75
+ # json_dumps = json.dumps(data, ensure_ascii=False, separators=(',', ':'))
76
+ pre_sign = json_dumps if data else ""
77
+ if pre_sign and not(pre_sign.isascii()):
78
+ raise pyCryptomusAPIException(-6, "Data dump contains non-ascii characters")
79
+ sign = md5(base64.b64encode(pre_sign.encode('ascii')) + key.encode('ascii')).hexdigest()
80
+ headers = {
81
+ "merchant": self.merchant_uuid,
82
+ "sign": sign,
83
+ "Content-Type": "application/json",
84
+ }
85
+ base_resp = requests.post(API_URL + method_url, data=pre_sign, headers=headers, timeout=self.timeout)
86
+ resp = base_resp.json()
87
+ except ValueError as ve:
88
+ code = base_resp.status_code if base_resp else -2
89
+ message = "Response decode failed: {}".format(ve)
90
+ if self.print_errors:
91
+ print(message)
92
+ raise pyCryptomusAPIException(code, message)
93
+ except pyCryptomusAPIException as pe:
94
+ raise pe
95
+ except Exception as e:
96
+ code = base_resp.status_code if base_resp else -3
97
+ message = "Request unknown exception: {}".format(e)
98
+ if self.print_errors:
99
+ print(message)
100
+ raise pyCryptomusAPIException(code, message)
101
+ if not resp:
102
+ code = base_resp.status_code if base_resp else -4
103
+ message = "None request response"
104
+ if self.print_errors:
105
+ print(message)
106
+ raise pyCryptomusAPIException(code, message)
107
+ elif not resp.get("result"):
108
+ code = base_resp.status_code if base_resp else -5
109
+ if resp.get("message"):
110
+ message = resp["message"]
111
+ elif resp.get("errors"):
112
+ message = resp["errors"]
113
+ else:
114
+ message = "No error info provided"
115
+ if self.print_errors:
116
+ print("Response: {}".format(resp))
117
+ raise pyCryptomusAPIException(code, message)
118
+ # code -6 is used above
119
+ else:
120
+ return resp
121
+
122
+ def create_invoice(self,
123
+ amount, currency, order_id, network = None,
124
+ url_return = None, url_success = None, url_callback = None,
125
+ is_payment_multiple = None, lifetime = None, to_currency = None, subtract = None,
126
+ accuracy_payment_percent = None, additional_data = None, currencies = None,
127
+ except_currencies = None, course_source = None, from_referral_code = None,
128
+ discount_percent = None, is_refresh = None):
129
+ """
130
+ Creating an invoice
131
+ https://doc.cryptomus.com/payments/creating-invoice
132
+ Requires PAYMENT API key
133
+
134
+ amount: (Float) Amount to be paid. If there are pennies in the amount, then send them with a separator '.' Example: 10.28
135
+ currency: (String) Currency code (https://doc.cryptomus.com/reference)
136
+ order_id: (String[1..128]) Order ID in your system. The parameter should be a string consisting of alphabetic characters, numbers, underscores, and dashes. It should not contain any spaces or special characters.
137
+ network: (String, Optional) Blockchain network code (https://doc.cryptomus.com/reference)
138
+ url_return: (String[6..255], Optional) Before paying, the user can click on the button on the payment form and return to the store page at this URL.
139
+ url_success: (String[6..255], Optional) After successful payment, the user can click on the button on the payment form and return to this URL.
140
+ url_callback: (String[6..255], Optional) Url to which webhooks with payment status will be sent.
141
+ is_payment_multiple: (Bool, Optional) Whether the user is allowed to pay the remaining amount. This is useful when the user has not paid the entire amount of the invoice for one transaction, and you want to allow him to pay up to the full amount. If you disable this feature, the invoice will finalize after receiving the first payment and you will receive funds to your balance.
142
+ lifetime: (Int[300..43200], Optional) The lifespan of the issued invoice (?in seconds?)
143
+ to_currency: (String, Optional) The parameter is used to specify the target currency for converting the invoice amount. When creating an invoice, you provide an amount and currency, and the API will convert that amount to the equivalent value in the to_currency. For example, to create an invoice for 20 USD in bitcoin: amount: 20, currency: USD, to_currency: BTC. The API will convert 20 USD amount to its equivalent in BTC based on the current exchange rate and the user will pay in BTC.
144
+ subtract: (Int[0..100], Optional) Percentage of the payment commission charged to the client. If you have a rate of 1%, then if you create an invoice for 100 USDT with subtract = 100 (the client pays 100% commission), the client will have to pay 101 USDT.
145
+ accuracy_payment_percent: (Float[0..5], Optional) Acceptable inaccuracy in payment. For example, if you pass the value 5, the invoice will be marked as Paid even if the client has paid only 95% of the amount. The actual payment amount will be credited to the balance.
146
+ additional_data: (?String?, Optional) Additional information for you (not shown to the client).
147
+ currencies: (List[Currency][1..255], Optional) List of allowed currencies for payment. This is useful if you want to limit the list of coins that your customers can use to pay invoices.
148
+ except_currencies: (List[Currency], Optional) List of excluded currencies for payment.
149
+ course_source: (String[4..20], Optional) The service from which the exchange rates are taken for conversion in the invoice. If not passed, Cryptomus exchange rates are used. Available values: https://doc.cryptomus.com/payments/creating-invoice
150
+ from_referral_code: (String, Optional) The merchant who makes the request connects to a referrer by code. For example, you are an application that generates invoices via the Cryptomus API and your customers are other stores. They enter their api key and merchant id in your application, and you send requests with their credentials and passing your referral code. Thus, your clients become referrals on your Cryptomus account and you will receive income from their turnover.
151
+ discount_percent: (Int[-99..100], Optional) Positive numbers: allows you to set a discount. To set a 5% discount for the payment, you should pass a value: 5. Negative numbers: allows you to set custom additional commission. To set an additional commission of 10% for the payment, you should pass a value: -10.
152
+ is_refresh: (Bool, Optional) Using this parameter, you can update the lifetime and get a new address for the invoice if the lifetime has expired. To do that, you need to pass all required parameters, and the invoice with passed order_id will be refreshed.
153
+
154
+ * The order_id must be unique within the merchant invoices/static wallets/recurrence payments
155
+ * When we find an existing invoice with order_id, we return its details, a new invoice will not be created.
156
+ * The to_currency should always be the cryptocurrency code, not a fiat currency code.
157
+ * The discount percentage when creating an invoice is taken into account only if the invoice has a specific cryptocurrency.
158
+ * Only address, payment_status and expired_at are changed. No other fields are changed, regardless of the parameters passed.
159
+ """
160
+ method = "payment"
161
+ params = {
162
+ "amount": str(amount),
163
+ "currency": currency,
164
+ "order_id": str(order_id),
165
+ }
166
+ if network:
167
+ params["network"] = network
168
+ if url_return:
169
+ params["url_return"] = url_return
170
+ if url_success:
171
+ params["url_success"] = url_success
172
+ if url_callback:
173
+ params["url_callback"] = url_callback
174
+ if is_payment_multiple is not None:
175
+ params["is_payment_multiple"] = is_payment_multiple
176
+ if lifetime is not None:
177
+ params["lifetime"] = str(lifetime)
178
+ if to_currency:
179
+ params["to_currency"] = to_currency
180
+ if subtract is not None:
181
+ params["subtract"] = str(subtract)
182
+ if accuracy_payment_percent is not None:
183
+ params["accuracy_payment_percent"] = str(accuracy_payment_percent)
184
+ if additional_data:
185
+ params["additional_data"] = additional_data
186
+ if currencies:
187
+ params["currencies"] = [i.to_dict() for i in currencies]
188
+ if except_currencies:
189
+ params["except_currencies"] = [i.to_dict() for i in except_currencies]
190
+ if course_source:
191
+ params["course_source"] = course_source
192
+ if from_referral_code:
193
+ params["from_referral_code"] = from_referral_code
194
+ if discount_percent is not None:
195
+ params["discount_percent"] = str(discount_percent)
196
+ if is_refresh is not None:
197
+ params["is_refresh"] = is_refresh
198
+ resp = self.__request(method, 1, **params).get("result")
199
+ return Invoice.de_json(resp)
200
+
201
+ def create_wallet(self,
202
+ network, currency, order_id, url_callback = None, from_referral_code = None):
203
+ """
204
+ Creating a Static wallet
205
+ https://doc.cryptomus.com/payments/creating-static
206
+ Requires PAYMENT API key
207
+
208
+ network: (String) Blockchain network code (https://doc.cryptomus.com/reference)
209
+ currency: (String) Currency code (https://doc.cryptomus.com/reference)
210
+ order_id: (String[1..100]) Order ID in your system. The parameter should be a string consisting of alphabetic characters, numbers, underscores, and dashes. It should not contain any spaces or special characters.
211
+ url_callback: (String[6..255], Optional) URL, to which the webhook will be sent after each top-up of the wallet.
212
+ from_referral_code: (String, Optional) The merchant who makes the request connects to a referrer by code. For example, you are an application that generates invoices via the Cryptomus API and your customers are other stores. They enter their api key and merchant id in your application, and you send requests with their credentials and passing your referral code. Thus, your clients become referrals on your Cryptomus account and you will receive income from their turnover.
213
+
214
+ * The order_id must be unique within the merchant invoices/static wallets/recurrence payments
215
+ * When we find an existing invoice with order_id, we return its details, a new invoice will not be created.
216
+ """
217
+ method = "wallet"
218
+ params = {
219
+ "network": network,
220
+ "currency": currency,
221
+ "order_id": str(order_id),
222
+ }
223
+ if url_callback:
224
+ params["url_callback"] = url_callback
225
+ if from_referral_code:
226
+ params["from_referral_code"] = from_referral_code
227
+ resp = self.__request(method, 1, **params).get("result")
228
+ return Wallet.de_json(resp)
229
+
230
+ def block_wallet(self,
231
+ wallet_uuid = None, order_id = None, is_force_refund = None):
232
+ """
233
+ Block static wallet
234
+ https://doc.cryptomus.com/payments/block-wallet
235
+ You need to pass one of the required parameters, if you pass both, the account will be identified by order_id
236
+ Requires PAYMENT API key
237
+
238
+ wallet_uuid: (String, Optional if order_id set) UUID of a static wallet
239
+ order_id: (String[1..32], Optional if wallet_uuid set) Order ID of a static wallet
240
+ is_force_refund: (Bool, Optional) Refund all incoming payments to sender’s address
241
+
242
+ * You need to pass one of the required parameters, if you pass both, the account will be identified by order_id
243
+ """
244
+ method = "wallet/block-address"
245
+ params = {
246
+ }
247
+ if (not wallet_uuid) and (not order_id):
248
+ raise pyCryptomusAPIException(0, "You need to pass one of the required parameters")
249
+ if wallet_uuid:
250
+ params["uuid"] = wallet_uuid
251
+ if order_id:
252
+ params["order_id"] = order_id
253
+ if is_force_refund is not None:
254
+ params["is_force_refund"] = is_force_refund
255
+ resp = self.__request(method, 1, **params).get("result")
256
+ return resp
257
+
258
+ def block_wallet_refund(self,
259
+ address, wallet_uuid = None, order_id = None):
260
+ """
261
+ Refund payments on blocked address
262
+ https://doc.cryptomus.com/payments/refundblocked
263
+ You need to pass one of the required parameters, if you pass both, the account will be identified by order_id
264
+ Requires PAYMENT API key
265
+
266
+ address: (String[10..128]) Refund all blocked funds to this address
267
+ wallet_uuid: (String, Optional if order_id set) UUID of a static wallet
268
+ order_id: (String[1..32], Optional if wallet_uuid set) Order ID of a static wallet
269
+
270
+ * To refund payments you need to pass either uuid or order_id, if you pass both, the static wallet will be identified by uuid
271
+ """
272
+ method = "wallet/blocked-address-refund"
273
+ params = {
274
+ "address": address,
275
+ }
276
+ if (not wallet_uuid) and (not order_id):
277
+ raise pyCryptomusAPIException(0, "You need to pass one of the required parameters")
278
+ if wallet_uuid:
279
+ params["uuid"] = wallet_uuid
280
+ if order_id:
281
+ params["order_id"] = order_id
282
+ resp = self.__request(method, 1, **params).get("result")
283
+ return resp
284
+
285
+ def payment_information(self,
286
+ invoice_uuid = None, order_id = None):
287
+ """
288
+ Payment information
289
+ https://doc.cryptomus.com/payments/payment-information
290
+ You need to pass one of the required parameters, if you pass both, the account will be identified by order_id
291
+ Requires PAYMENT API key
292
+
293
+ invoice_uuid: (String, Optional if order_id set) Invoice UUID
294
+ order_id: (String[1..128], Optional if wallet_uuid set) Invoice order ID
295
+
296
+ * To get the invoice status you need to pass one of the required parameters, if you pass both, the account will be identified by order_id
297
+ """
298
+ method = "payment/info"
299
+ params = {
300
+ }
301
+ if (not invoice_uuid) and (not order_id):
302
+ raise pyCryptomusAPIException(0, "You need to pass one of the required parameters")
303
+ if invoice_uuid:
304
+ params["uuid"] = invoice_uuid
305
+ if order_id:
306
+ params["order_id"] = order_id
307
+ resp = self.__request(method, 1, **params).get("result")
308
+ return Invoice.de_json(resp)
309
+
310
+ def refund(self,
311
+ address, is_subtract, invoice_uuid = None, order_id = None):
312
+ """
313
+ Refund
314
+ https://doc.cryptomus.com/payments/refund
315
+ You need to pass one of the required parameters, if you pass both, the account will be identified by invoice_uuid
316
+ Requires PAYMENT API key
317
+
318
+ address: (String) The address to which the refund should be made
319
+ is_subtract: (Bool) Whether to take a commission from the merchant's balance or from the refund amount. true - take the commission from merchant balance. false - reduce the refundable amount by the commission amount
320
+ invoice_uuid: (String, Optional if order_id set) Invoice UUID
321
+ order_id: (String[1..128], Optional if invoice_uuid set) Invoice order ID
322
+
323
+ * Invoice is identified by order_id or uuid, if you pass both, the account will be identified by uuid
324
+ """
325
+ method = "payment/refund"
326
+ params = {
327
+ "address": address,
328
+ "is_subtract": is_subtract,
329
+ }
330
+ if (not invoice_uuid) and (not order_id):
331
+ raise pyCryptomusAPIException(0, "You need to pass one of the required parameters")
332
+ if invoice_uuid:
333
+ params["uuid"] = invoice_uuid
334
+ if order_id:
335
+ params["order_id"] = order_id
336
+ resp = self.__request(method, 1, **params).get("result")
337
+ return Invoice.de_json(resp)
338
+
339
+ def payment_history(self, date_from = None, date_to = None, cursor = None):
340
+ """
341
+ Payment history
342
+ https://doc.cryptomus.com/payments/payment-history
343
+ Requires PAYMENT API key
344
+
345
+ date_from: (String, Optional) Filtering by creation date, from
346
+ date_to: (String, Optional) Filtering by creation date, to
347
+ cursor: (String, Optional) Page cursor (hash)
348
+ """
349
+ params = {
350
+ }
351
+ if date_from:
352
+ params["date_from"] = date_from.strftime(CryptomusDateFormat)
353
+ if date_to:
354
+ params["date_to"] = date_to.strftime(CryptomusDateFormat)
355
+ if cursor:
356
+ params["cursor"] = cursor
357
+ method = "payment/list"
358
+ if params:
359
+ resp = self.__request(method, 1, **params).get("result")
360
+ else:
361
+ resp = self.__request(method, 1).get("result")
362
+ return PaymentsHistory.de_json(resp)
363
+
364
+ def payment_history_filtered(
365
+ self,
366
+ date_from = None, date_to = None,
367
+ max_results = 15, max_pages = 10,
368
+ currencies = None, networks = None, addresses = None,
369
+ statuses = None, is_final = None, page_delay = 1):
370
+ """
371
+ Payment history (advanced mode)
372
+
373
+ Based on: payment_history
374
+ https://doc.cryptomus.com/payments/payment-history
375
+ Requires PAYMENT API key
376
+
377
+ Collects only results under filters.
378
+ Process as many pages as needed to collect max_results, but not more than max_pages.
379
+
380
+ date_from: (String, Optional) Filtering by creation date, from
381
+ date_to: (String, Optional) Filtering by creation date, to
382
+ max_results: (Int, Optional, default=15) Max number of results to collect
383
+ max_pages: (Int, Optional, default=10) Max number of pages to process
384
+ currencies: (List of Strings, Optional) List of accepted currencies. Codes: https://doc.cryptomus.com/reference
385
+ networks: (List of Strings, Optional) List of accepted networks. Codes: https://doc.cryptomus.com/reference
386
+ addresses: (List of Strings, Optional) List of accepted addresses
387
+ statuses: (List of Strings, Optional) List of accepted statuses. Codes: https://doc.cryptomus.com/payments/payment-statuses
388
+ is_final: (Bool, Optional) If True, only final payments will be collected, if False - only non-final
389
+ page_delay: (Int, Optional, default=1) Delay between pages (in seconds)
390
+ """
391
+
392
+ result = PaymentsHistory()
393
+
394
+ page_number = 0
395
+ cursor = None
396
+ while page_number < max_pages:
397
+ if page_number > 0: sleep(page_delay)
398
+ resp = self.payment_history(date_from = date_from, date_to = date_to, cursor = cursor)
399
+
400
+ if not resp.items:
401
+ # No (more) payments
402
+ break
403
+
404
+ for payment in resp.items:
405
+ if currencies and not(payment.currency in currencies):
406
+ continue
407
+ if networks and not(payment.network in networks):
408
+ continue
409
+ if addresses and not(payment.address in addresses):
410
+ continue
411
+ if statuses and not(payment.status in statuses):
412
+ continue
413
+ if (is_final is not None) and payment.is_final != is_final:
414
+ continue
415
+ result.items.append(payment)
416
+
417
+ if len(result.items) >= max_results:
418
+ # Enough results collected
419
+ break
420
+
421
+ if len(result.items) >= max_results:
422
+ # Enough results collected
423
+ break
424
+
425
+ cursor = resp.paginate.nextCursor
426
+ if not cursor:
427
+ # No more pages
428
+ break
429
+ page_number += 1
430
+
431
+ return result
432
+
433
+ def payment_services(self):
434
+ """
435
+ Get collection of all available payment services
436
+ https://doc.cryptomus.com/payments/list-of-services
437
+ Requires PAYMENT API key
438
+ """
439
+ method = "payment/services"
440
+ resp = self.__request(method, 1).get("result")
441
+ return [Service.de_json(i) for i in resp]
442
+
443
+ """
444
+ Request
445
+ Query parameters
446
+ NAME PARAMETER TYPE DEFAULT VALUE DEFINITION
447
+ amount* string Payout amount
448
+ currency* string
449
+ Currency code for the payout
450
+ If Currency if fiat, the to_currency parameter is required.
451
+ order_id*
452
+ string
453
+ min:1
454
+ max:100
455
+ alpha_dash
456
+ Order ID in your system
457
+ The parameter should be a string consisting of alphabetic characters, numbers, underscores, and dashes. It should not contain any spaces or special characters.
458
+ The order_id must be unique within the merchant payouts
459
+ When we find an existing payout with order_id, we return its details, a new payout will not be created.
460
+ address* string The address of the wallet to which the withdrawal will be made
461
+ is_subtract* boolean
462
+ Defines where the withdrawal fee will be deducted
463
+ true - from your balance
464
+ false - from payout amount, the payout amount will be decreased
465
+ network* string
466
+ Blockchain network code
467
+ Not required when the currency/to_currency is a cryptocurrency and has only one network, for example BTC
468
+ url_callback URL to which webhooks with payout status will be sent
469
+ to_currency Cryptocurrency code in which the payout will be made. It is used when the currency parameter is fiat. See examples below
470
+ course_source string
471
+ Available values
472
+ -
473
+ Binance
474
+ -
475
+ BinanceP2p
476
+ -
477
+ Exmo
478
+ -
479
+ Kucoin
480
+ -
481
+ Garantexio
482
+ Value from merchant's settings
483
+ The service from which the exchange rates are taken for conversion in the invoice.
484
+ The parameter is applied only if the currency is fiat, otherwise the default value is taken from the merchant's settings.
485
+ from_currency string null Allows to automatically convert the withdrawal amount and use the from_currency balance. Only USDT is available.
486
+ priority
487
+ string
488
+ min: 4
489
+ max: 11
490
+ Available values
491
+ -
492
+ recommended
493
+ -
494
+ economy
495
+ -
496
+ high
497
+ -
498
+ highest
499
+ recommended
500
+ The parameter for selecting the withdrawal priority. The cost of the withdrawal fee depends on the selected parameter.
501
+ This parameter is applied only in case of using the BTC, ETH, POLYGON, and BSC networks.
502
+ memo
503
+ string
504
+ min: 1
505
+ max: 30
506
+ Additional identifier for TON, used to specify a particular recipient or target
507
+ * - mandatory parameter
508
+ """
509
+
510
+ def create_payout(self,
511
+ amount, currency, order_id, address, is_subtract, network,
512
+ url_callback = None, to_currency = None, course_source = None,
513
+ from_currency = None, priority = None, memo = None):
514
+ """
515
+ Creating a payout
516
+ https://doc.cryptomus.com/payouts/creating-payout
517
+ Requires PAYOUT API key
518
+
519
+ amount: (String) Payout amount
520
+ currency: (String) Currency code for the payout. If Currency if fiat, the to_currency parameter is required.
521
+ order_id: (String[1..100]) Order ID in your system. The parameter should be a string consisting of alphabetic characters, numbers, underscores, and dashes. It should not contain any spaces or special characters. The order_id must be unique within the merchant payouts. When we find an existing payout with order_id, we return its details, a new payout will not be created.
522
+ address: (String) The address of the wallet to which the withdrawal will be made
523
+ is_subtract: (Bool) Defines where the withdrawal fee will be deducted. true - from your balance. false - from payout amount, the payout amount will be decreased.
524
+ network: (String) Blockchain network code.Not required when the currency/to_currency is a cryptocurrency and has only one network, for example BTC
525
+ url_callback: (String, Optional) URL to which webhooks with payout status will be sent
526
+ to_currency: (String, Optional) Cryptocurrency code in which the payout will be made. It is used when the currency parameter is fiat.
527
+ course_source: (String, Optional) The service from which the exchange rates are taken for conversion in the invoice. The parameter is applied only if the currency is fiat, otherwise the default value is taken from the merchant's settings.
528
+ from_currency: (String, Optional) Allows to automatically convert the withdrawal amount and use the from_currency balance. Only USDT is available.
529
+ priority: (String, Optional) The parameter for selecting the withdrawal priority. The cost of the withdrawal fee depends on the selected parameter. This parameter is applied only in case of using the BTC, ETH, POLYGON, and BSC networks. Available values: recommended, economy, high, highest
530
+ memo: (String, Optional) Additional identifier for TON, used to specify a particular recipient or target
531
+ """
532
+ method = "payout"
533
+ params = {
534
+ "amount": str(amount),
535
+ "currency": currency,
536
+ "order_id": str(order_id),
537
+ "address": address,
538
+ "is_subtract": is_subtract,
539
+ "network": network,
540
+ }
541
+ if url_callback:
542
+ params["url_callback"] = url_callback
543
+ if to_currency:
544
+ params["to_currency"] = to_currency
545
+ if course_source:
546
+ params["course_source"] = course_source
547
+ if from_currency:
548
+ params["from_currency"] = from_currency
549
+ if priority:
550
+ params["priority"] = priority
551
+ if memo:
552
+ params["memo"] = memo
553
+ resp = self.__request(method, 2, **params).get("result")
554
+ return Payout.de_json(resp)
555
+
556
+ def payout_information(self,
557
+ payout_uuid = None, order_id = None):
558
+ """
559
+ Payout information
560
+ https://doc.cryptomus.com/payouts/payout-information
561
+ You need to pass one of the required parameters, if you pass both, the account will be identified by order_id
562
+ Requires PAYOUT API key
563
+
564
+ payout_uuid: (String, Optional if order_id set) Payout UUID
565
+ order_id: (String[1..128], Optional if wallet_uuid set) Payout order ID
566
+
567
+ * To get the payout information you need to pass one of the parameters, if you pass both, the payout will be identified by order_id
568
+ """
569
+ method = "payout/info"
570
+ params = {
571
+ }
572
+ if (not payout_uuid) and (not order_id):
573
+ raise pyCryptomusAPIException(0, "You need to pass one of the required parameters")
574
+ if payout_uuid:
575
+ params["uuid"] = payout_uuid
576
+ if order_id:
577
+ params["order_id"] = order_id
578
+ resp = self.__request(method, 1, **params).get("result")
579
+ return Payout.de_json(resp)
580
+
581
+ def payout_history(self, date_from = None, date_to = None, cursor = None):
582
+ """
583
+ Payout history
584
+ https://doc.cryptomus.com/payments/payment-history
585
+ Requires PAYOUT API key
586
+
587
+ date_from: (String, Optional) Filtering by creation date, from
588
+ date_to: (String, Optional) Filtering by creation date, to
589
+ cursor: (String, Optional) Page cursor (hash)
590
+ """
591
+ params = {
592
+ }
593
+ if date_from:
594
+ params["date_from"] = date_from.strftime(CryptomusDateFormat)
595
+ if date_to:
596
+ params["date_to"] = date_to.strftime(CryptomusDateFormat)
597
+ if cursor:
598
+ params["cursor"] = cursor
599
+ method = "payment/list"
600
+ if params:
601
+ resp = self.__request(method, 1, **params).get("result")
602
+ else:
603
+ resp = self.__request(method, 1).get("result")
604
+ return PayoutHistory.de_json(resp)
605
+
606
+ def payout_services(self):
607
+ """
608
+ Get collection of all available payout services
609
+ https://doc.cryptomus.com/payouts/list-of-services
610
+ Requires PAYMOUT API key
611
+ """
612
+ method = "payout/services"
613
+ resp = self.__request(method, 2).get("result")
614
+ return [Service.de_json(i) for i in resp]
615
+
616
+ def balance(self):
617
+ """
618
+ Get balance of merchant(account) or user(wallet)
619
+ https://doc.cryptomus.com/balance
620
+ Requires PAYMENT API key
621
+ """
622
+ method = "balance"
623
+ resp = self.__request(method, 1).get("result")
624
+ return Balance.de_json(resp[0])
@@ -1,6 +1,7 @@
1
1
  import json
2
2
  from abc import ABC
3
3
 
4
+ CryptomusDateFormat = "%Y-%m-%d %H:%M:%S"
4
5
 
5
6
  class Dictionaryable(ABC):
6
7
  """
@@ -128,9 +129,11 @@ class Balance(JsonDeserializable):
128
129
  raise ValueError("Not a balance")
129
130
  if "merchant" in data:
130
131
  for item in data["merchant"]:
132
+ # noinspection PyUnresolvedReferences
131
133
  instance.merchant.append(BalanceItem.de_json(item))
132
134
  if "user" in data:
133
135
  for item in data["user"]:
136
+ # noinspection PyUnresolvedReferences
134
137
  instance.user.append(BalanceItem.de_json(item))
135
138
  return instance
136
139
 
@@ -218,19 +221,22 @@ class Invoice(JsonDeserializable):
218
221
  self.amount = None
219
222
  self.payment_amount = None
220
223
  self.payer_amount = None
224
+ self.discount_percent = None
225
+ self.discount = None
221
226
  self.payer_currency = None
222
227
  self.currency = None
223
- self.comments = None
228
+ self.merchant_amount = None
224
229
  self.network = None
225
230
  self.address = None
226
231
  self.from_ = None
227
232
  self.txid = None
233
+ self.payment_status = None
228
234
  self.url = None
229
235
  self.expired_at = None
230
- self.payment_status = None
231
236
  self.is_final = None
232
237
  self.additional_data = None
233
- self.currencies = None
238
+ self.created_at = None
239
+ self.updated_at = None
234
240
 
235
241
  @classmethod
236
242
  def de_json(cls, json_dict):
@@ -242,10 +248,16 @@ class Invoice(JsonDeserializable):
242
248
  instance.payment_amount = float(instance.payment_amount)
243
249
  if instance.payer_amount is not None:
244
250
  instance.payer_amount = float(instance.payer_amount)
245
- if instance.expired_at is not None:
246
- instance.expired_at = int(instance.expired_at)
247
- if instance.currencies:
248
- instance.currencies = [Currency.de_json(i) for i in instance.currencies]
251
+ if instance.discount_percent is not None:
252
+ instance.discount_percent = float(instance.discount_percent)
253
+ if instance.discount is not None:
254
+ instance.discount = float(instance.discount)
255
+ if instance.merchant_amount is not None:
256
+ instance.merchant_amount = float(instance.merchant_amount)
257
+ # if instance.created_at is not None:
258
+ # instance.created_at = datetime.datetime.strptime(instance.created_at, CryptomusDateFormat)
259
+ # if instance.updated_at is not None:
260
+ # instance.updated_at = datetime.datetime.strptime(instance.updated_at, CryptomusDateFormat)
249
261
  return instance
250
262
 
251
263
  # noinspection PyMethodOverriding
@@ -293,3 +305,44 @@ class PaymentsHistory(JsonDeserializable):
293
305
  instance.items = [Invoice.de_json(i) for i in instance.items]
294
306
  instance.paginate = PaymentPaginate.de_json(instance.paginate)
295
307
  return instance
308
+
309
+ # noinspection PyMethodOverriding
310
+ class Payout(JsonDeserializable):
311
+ def __init__(self):
312
+ self.uuid = None
313
+ self.amount = None
314
+ self.currency = None
315
+ self.network = None
316
+ self.address = None
317
+ self.txid = None
318
+ self.status = None
319
+ self.is_final = None
320
+ self.balance = None
321
+ self.payer_currency = None
322
+ self.payer_amount = None
323
+
324
+ @classmethod
325
+ def de_json(cls, json_dict):
326
+ data = cls.check_json(json_dict)
327
+ instance = super(Payout, cls).de_json(data, process_mode=2)
328
+ if instance.amount is not None:
329
+ instance.amount = float(instance.amount)
330
+ if instance.payer_amount is not None:
331
+ instance.payer_amount = float(instance.payer_amount)
332
+ if instance.balance is not None:
333
+ instance.balance = float(instance.balance)
334
+ return instance
335
+
336
+ # noinspection PyMethodOverriding
337
+ class PayoutHistory(JsonDeserializable):
338
+ def __init__(self):
339
+ self.items = []
340
+ self.paginate = PaymentPaginate()
341
+
342
+ @classmethod
343
+ def de_json(cls, json_dict):
344
+ data = cls.check_json(json_dict)
345
+ instance = super(PayoutHistory, cls).de_json(data, process_mode=2)
346
+ instance.items = [Payout.de_json(i) for i in instance.items]
347
+ instance.paginate = PaymentPaginate.de_json(instance.paginate)
348
+ return instance
@@ -50,6 +50,7 @@ def test_api_functions():
50
50
  run_and_print(lambda: client.payment_history())
51
51
  run_and_print(lambda: client.payment_history_filtered(is_final=True))
52
52
  run_and_print(lambda: client.payout_services())
53
+ run_and_print(lambda: client.payout_history())
53
54
  run_and_print(lambda: client.balance())
54
55
 
55
56
  test_api_functions()
@@ -1,3 +1,3 @@
1
1
  # Versions should comply with PEP440.
2
2
  # This line is parsed in setup.py:
3
- __version__ = '0.0.7'
3
+ __version__ = '0.1.0'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyCryptomusAPI
3
- Version: 0.0.7
3
+ Version: 0.1.0
4
4
  Summary: Python implementation of Cryptomus (https://cryptomus.com) pubilc API
5
5
  Home-page: https://github.com/Badiboy/pyCryptomusAPI
6
6
  Author: Badiboy
@@ -1,415 +0,0 @@
1
- from hashlib import md5
2
- from time import sleep
3
- import base64
4
- import requests
5
-
6
- from .cryto_types import *
7
-
8
- API_URL = "https://api.cryptomus.com/v1/"
9
-
10
-
11
- # noinspection PyPep8Naming
12
- class pyCryptomusAPIException(Exception):
13
- def __init__(self, code, message, full_error = ""):
14
- self.code = code
15
- self.message = message
16
- self.full_error = full_error
17
- super().__init__(self.message)
18
-
19
-
20
- # noinspection PyPep8Naming
21
- class pyCryptomusAPI:
22
- """
23
- Cryptomus API Client
24
- """
25
-
26
- def __init__(self,
27
- merchant_uuid, payment_api_key = None, payout_api_key = None,
28
- print_errors = False, timeout = None, add_request_params = None):
29
- """
30
- Create the pyCryptomusAPI instance.
31
-
32
- :param merchant_uuid: The merchant's uuid, which you can find in the merchant's personal account in the settings section.
33
- :param payment_api_key: API key for processing payments
34
- :param payout_api_key: API key for accepting payment and making payouts
35
- :param print_errors: (Optional) Print dumps on request errors
36
- :param timeout: (Optional) Request timeout
37
- :param add_request_params: (List, Optional) Additional request parameters to pass with API calls
38
- """
39
- self.merchant_uuid = merchant_uuid
40
- self.payment_api_key = payment_api_key
41
- self.payout_api_key = payout_api_key
42
- self.print_errors = print_errors
43
- self.timeout = timeout
44
- self.add_request_params = add_request_params
45
- if not(self.payment_api_key) and not(self.payout_api_key):
46
- raise Exception("You must specify at least one API key.")
47
-
48
- def __request(self, method_url, mode, **kwargs):
49
- """
50
- Send request to API
51
-
52
- :param method_url: (String) API method url (part)
53
- :param mode: (Int) Method mode (1: payment, 2: payout)
54
- :param kwargs: request data
55
- """
56
- if kwargs:
57
- data = dict(kwargs)
58
- else:
59
- data = {}
60
-
61
- if self.add_request_params:
62
- data.update(self.add_request_params)
63
-
64
- base_resp = None
65
- try:
66
- key = self.payment_api_key if (mode == 1) else self.payout_api_key
67
- if not(key):
68
- raise pyCryptomusAPIException(-6, "Key is empty")
69
- if not(key.isascii()):
70
- raise pyCryptomusAPIException(-6, "Key contains non-ascii characters")
71
- if not(self.merchant_uuid):
72
- raise pyCryptomusAPIException(-6, "Merchant UUID is empty")
73
- if not(self.merchant_uuid.isascii()):
74
- raise pyCryptomusAPIException(-6, "Merchant UUID contains non-ascii characters")
75
- json_dumps = json.dumps(data)
76
- # json_dumps = json.dumps(data, ensure_ascii=False, separators=(',', ':'))
77
- pre_sign = json_dumps if data else ""
78
- if pre_sign and not(pre_sign.isascii()):
79
- raise pyCryptomusAPIException(-6, "Data dump contains non-ascii characters")
80
- sign = md5(base64.b64encode(pre_sign.encode('ascii')) + key.encode('ascii')).hexdigest()
81
- headers = {
82
- "merchant": self.merchant_uuid,
83
- "sign": sign,
84
- "Content-Type": "application/json",
85
- }
86
- base_resp = requests.post(API_URL + method_url, data=pre_sign, headers=headers, timeout=self.timeout)
87
- resp = base_resp.json()
88
- except ValueError as ve:
89
- code = base_resp.status_code if base_resp else -2
90
- message = "Response decode failed: {}".format(ve)
91
- if self.print_errors:
92
- print(message)
93
- raise pyCryptomusAPIException(code, message)
94
- except pyCryptomusAPIException as pe:
95
- raise pe
96
- except Exception as e:
97
- code = base_resp.status_code if base_resp else -3
98
- message = "Request unknown exception: {}".format(e)
99
- if self.print_errors:
100
- print(message)
101
- raise pyCryptomusAPIException(code, message)
102
- if not resp:
103
- code = base_resp.status_code if base_resp else -4
104
- message = "None request response"
105
- if self.print_errors:
106
- print(message)
107
- raise pyCryptomusAPIException(code, message)
108
- elif not resp.get("result"):
109
- code = base_resp.status_code if base_resp else -5
110
- if resp.get("message"):
111
- message = resp["message"]
112
- elif resp.get("errors"):
113
- message = resp["errors"]
114
- else:
115
- message = "No error info provided"
116
- if self.print_errors:
117
- print("Response: {}".format(resp))
118
- raise pyCryptomusAPIException(code, message)
119
- # code -6 is used above
120
- else:
121
- return resp
122
-
123
- def create_invoice(self,
124
- amount, currency, order_id, network = None, url_return = None, url_callback = None,
125
- is_payment_multiple = None, lifetime = None, to_currency = None, subtract = None,
126
- accuracy_payment_percent = None, additional_data = None, currencies = None,
127
- except_currencies = None):
128
- """
129
- Creating an invoice
130
- https://doc.cryptomus.com/payments/creating-invoice
131
- Requires PAYMENT API key
132
-
133
- amount: (Float) The amount of the invoice
134
- currency: (String) Currency code (https://doc.cryptomus.com/reference)
135
- order_id: (String) Order ID in your system
136
- network: (String, Optional) Blockchain network code (https://doc.cryptomus.com/reference)
137
- url_return: (String, Optional) Url to which the user will return after payment
138
- url_callback: (String, Optional) Url to which webhooks with payment status will be sent
139
- is_payment_multiple: (Bool, Optional) Whether payment of the remaining amount is possible (true/false)
140
- lifetime: (?Int?, Optional) The lifespan of the issued invoice (?in seconds?)
141
- to_currency: (String, Optional) Currency code for accepting payments
142
- subtract: (?Float?, Optional) Percentage of the payment commission charged to the client. The subtract parameter allows you to specify what percentage of the payment acceptance will be paid by the client. If you have a payment commission 1%, then if you create an invoice for 100 USDT with subtract=100 (the client pays 100% commission), the client will have to pay 101 USDT.
143
- accuracy_payment_percent: (?Float?, Optional) Acceptable inaccuracy in payment (min 0, max 5.00)
144
- additional_data: (?String?, Optional) Additional information
145
- currencies: (List[Currency], Optional) List of allowed currencies for payment Structure
146
- except_currencies: (List[Currency], Optional) List of excluded currencies for payment Structure
147
- """
148
- method = "payment"
149
- params = {
150
- "amount": str(amount),
151
- "currency": currency,
152
- "order_id": str(order_id),
153
- }
154
- if network:
155
- params["network"] = network
156
- if url_return:
157
- params["url_return"] = url_return
158
- if url_callback:
159
- params["url_callback"] = url_callback
160
- if is_payment_multiple is not None:
161
- params["is_payment_multiple"] = is_payment_multiple
162
- if lifetime is not None:
163
- params["lifetime"] = str(lifetime)
164
- if to_currency:
165
- params["to_currency"] = to_currency
166
- if subtract is not None:
167
- params["subtract"] = str(subtract)
168
- if accuracy_payment_percent is not None:
169
- params["accuracy_payment_percent"] = str(accuracy_payment_percent)
170
- if additional_data:
171
- params["additional_data"] = additional_data
172
- if currencies:
173
- params["currencies"] = [i.to_dict() for i in currencies]
174
- if except_currencies:
175
- params["except_currencies"] = [i.to_dict() for i in except_currencies]
176
- resp = self.__request(method, 1, **params).get("result")
177
- return Invoice.de_json(resp)
178
-
179
- def create_wallet(self,
180
- network, currency, order_id, url_callback = None):
181
- """
182
- Creating a Static wallet
183
- https://doc.cryptomus.com/payments/creating-static
184
- Requires PAYMENT API key
185
-
186
- network: (String) Blockchain network code (https://doc.cryptomus.com/reference)
187
- currency: (String) Currency code (https://doc.cryptomus.com/reference)
188
- order_id: (String) Order ID in your system
189
- url_callback: (String, Optional) Url to which webhooks with payment status will be sent
190
- """
191
- method = "wallet"
192
- params = {
193
- "network": network,
194
- "currency": currency,
195
- "order_id": str(order_id),
196
- }
197
- if url_callback:
198
- params["url_callback"] = url_callback
199
- resp = self.__request(method, 1, **params).get("result")
200
- return Wallet.de_json(resp)
201
-
202
- def block_wallet(self,
203
- wallet_uuid = None, order_id = None, is_force_refund = None):
204
- """
205
- Block static wallet
206
- https://doc.cryptomus.com/payments/block-wallet
207
- You need to pass one of the required parameters, if you pass both, the account will be identified by order_id
208
- Requires PAYMENT API key
209
-
210
- wallet_uuid: (String, Optional if order_id set) Wallet UUID
211
- order_id: (String, Optional if wallet_uuid set) Order ID in your system
212
- is_force_refund: (Bool, Optional) Refund all incoming payments to sender’s address
213
- """
214
- method = "wallet/block-address"
215
- params = {
216
- }
217
- if not(wallet_uuid) and not(order_id):
218
- raise pyCryptomusAPIException(0, "You need to pass one of the required parameters")
219
- if wallet_uuid:
220
- params["uuid"] = wallet_uuid
221
- if order_id:
222
- params["order_id"] = order_id
223
- if is_force_refund is not None:
224
- params["is_force_refund"] = is_force_refund
225
- resp = self.__request(method, 1, **params).get("result")
226
- return resp
227
-
228
- def block_wallet_refund(self,
229
- address, wallet_uuid = None, order_id = None):
230
- """
231
- Refund payments on blocked address
232
- https://doc.cryptomus.com/payments/refundblocked
233
- You need to pass one of the required parameters, if you pass both, the account will be identified by order_id
234
- Requires PAYMENT API key
235
-
236
- address: (String) Address (wallet addres? refund address?)
237
- wallet_uuid: (String, Optional if order_id set) Wallet UUID
238
- order_id: (String, Optional if wallet_uuid set) Order ID in your system
239
- """
240
- method = "wallet/blocked-address-refund"
241
- params = {
242
- "address": address,
243
- }
244
- if not(wallet_uuid) and not(order_id):
245
- raise pyCryptomusAPIException(0, "You need to pass one of the required parameters")
246
- if wallet_uuid:
247
- params["uuid"] = wallet_uuid
248
- if order_id:
249
- params["order_id"] = order_id
250
- resp = self.__request(method, 1, **params).get("result")
251
- return resp
252
-
253
- def payment_information(self,
254
- invoice_uuid = None, order_id = None):
255
- """
256
- Payment information
257
- https://doc.cryptomus.com/payments/payment-information
258
- You need to pass one of the required parameters, if you pass both, the account will be identified by order_id
259
- Requires PAYMENT API key
260
-
261
- invoice_uuid: (String, Optional if order_id set) Invoice UUID
262
- order_id: (String, Optional if wallet_uuid set) Order ID in your system
263
- """
264
- method = "payment/info"
265
- params = {
266
- }
267
- if not(invoice_uuid) and not(order_id):
268
- raise pyCryptomusAPIException(0, "You need to pass one of the required parameters")
269
- if invoice_uuid:
270
- params["uuid"] = invoice_uuid
271
- if order_id:
272
- params["order_id"] = order_id
273
- resp = self.__request(method, 1, **params).get("result")
274
- return Invoice.de_json(resp)
275
-
276
- def refund(self,
277
- address, is_subtract, invoice_uuid = None, order_id = None):
278
- """
279
- Refund
280
- https://doc.cryptomus.com/payments/refund
281
- You need to pass one of the required parameters, if you pass both, the account will be identified by invoice_uuid
282
- Requires PAYMENT API key
283
-
284
- address: (String) Refund address
285
- is_subtract: (Bool) Determines whether the commission is to be charged to the merchant or to the client (True - to the merchant, False - to the client)
286
- invoice_uuid: (String, Optional if order_id set) Invoice UUID
287
- order_id: (String, Optional if wallet_uuid set) Order ID in your system
288
- """
289
- method = "payment/refund"
290
- params = {
291
- "address": address,
292
- "is_subtract": is_subtract,
293
- }
294
- if not(invoice_uuid) and not(order_id):
295
- raise pyCryptomusAPIException(0, "You need to pass one of the required parameters")
296
- if invoice_uuid:
297
- params["uuid"] = invoice_uuid
298
- if order_id:
299
- params["order_id"] = order_id
300
- resp = self.__request(method, 1, **params).get("result")
301
- return Invoice.de_json(resp)
302
-
303
- def payment_history(self, cursor = None):
304
- """
305
- Payment history
306
- https://doc.cryptomus.com/payments/payment-history
307
- Requires PAYMENT API key
308
-
309
- cursor: (String, Optional) Page cursor (hash)
310
- """
311
- params = {
312
- }
313
- if cursor:
314
- params["cursor"] = cursor
315
- method = "payment/list"
316
- if params:
317
- resp = self.__request(method, 1, **params).get("result")
318
- else:
319
- resp = self.__request(method, 1).get("result")
320
- return PaymentsHistory.de_json(resp)
321
-
322
- def payment_history_filtered(
323
- self, max_results = 15, max_pages = 10,
324
- currencies = None, networks = None, addresses = None,
325
- statuses = None, is_final = None, page_delay = 1):
326
- """
327
- Payment history (advanced mode)
328
-
329
- Based on: payment_history
330
- https://doc.cryptomus.com/payments/payment-history
331
- Requires PAYMENT API key
332
-
333
- Collects only results under filters.
334
- Process as many pages as needed to collect max_results, but not more than max_pages.
335
-
336
- max_results: (Int, Optional, default=15) Max number of results to collect
337
- max_pages: (Int, Optional, default=10) Max number of pages to process
338
- currencies: (List of Strings, Optional) List of accepted currencies. Codes: https://doc.cryptomus.com/reference
339
- networks: (List of Strings, Optional) List of accepted networks. Codes: https://doc.cryptomus.com/reference
340
- addresses: (List of Strings, Optional) List of accepted addresses
341
- statuses: (List of Strings, Optional) List of accepted statuses. Codes: https://doc.cryptomus.com/payments/payment-statuses
342
- is_final: (Bool, Optional) If True, only final payments will be collected, if False - only non-final
343
- page_delay: (Int, Optional, default=1) Delay between pages (in seconds)
344
- """
345
-
346
- result = PaymentsHistory()
347
-
348
- page_number = 0
349
- cursor = None
350
- while page_number < max_pages:
351
- if page_number > 0: sleep(page_delay)
352
- resp = self.payment_history(cursor = cursor)
353
-
354
- if not resp.items:
355
- # No (more) payments
356
- break
357
-
358
- for payment in resp.items:
359
- if currencies and not(payment.currency in currencies):
360
- continue
361
- if networks and not(payment.network in networks):
362
- continue
363
- if addresses and not(payment.address in addresses):
364
- continue
365
- if statuses and not(payment.status in statuses):
366
- continue
367
- if (is_final is not None) and payment.is_final != is_final:
368
- continue
369
- result.items.append(payment)
370
-
371
- if len(result.items) >= max_results:
372
- # Enough results collected
373
- break
374
-
375
- if len(result.items) >= max_results:
376
- # Enough results collected
377
- break
378
-
379
- cursor = resp.paginate.nextCursor
380
- if not cursor:
381
- # No more pages
382
- break
383
- page_number += 1
384
-
385
- return result
386
-
387
- def payment_services(self):
388
- """
389
- Get collection of all available payment services
390
- https://doc.cryptomus.com/payments/list-of-services
391
- Requires PAYMENT API key
392
- """
393
- method = "payment/services"
394
- resp = self.__request(method, 1).get("result")
395
- return [Service.de_json(i) for i in resp]
396
-
397
- def payout_services(self):
398
- """
399
- Get collection of all available payout services
400
- https://doc.cryptomus.com/payouts/list-of-services
401
- Requires PAYMOUT API key
402
- """
403
- method = "payout/services"
404
- resp = self.__request(method, 2).get("result")
405
- return [Service.de_json(i) for i in resp]
406
-
407
- def balance(self):
408
- """
409
- Get balance of merchant(account) or user(wallet)
410
- https://doc.cryptomus.com/balance
411
- Requires PAYMENT API key
412
- """
413
- method = "balance"
414
- resp = self.__request(method, 1).get("result")
415
- return Balance.de_json(resp[0])
File without changes
File without changes
File without changes
File without changes