Skip to content

Commit b094020

Browse files
committed
Written payout, payoutbatches: exceptions,methods,testcases
1 parent 4132b80 commit b094020

14 files changed

+945
-5
lines changed

GUIDE.md

Lines changed: 312 additions & 0 deletions
Large diffs are not rendered by default.

src/bitpay_sdk/client.py

Lines changed: 200 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
from .utils.rest_cli import RESTcli
1616
from .models.ledger.ledger import Ledger
1717
from .models.wallet.wallet import Wallet
18+
from .models.payout.payout import Payout
1819
from .models.invoice.refund import Refund
1920
from .models.invoice.invoice import Invoice
21+
from .models.payout.payout_batch import PayoutBatch
2022
from .models.ledger.ledger_entry import LedgerEntry
2123
from .exceptions.bitpay_exception import BitPayException
2224
from .models.payout.payout_recipient import PayoutRecipient
@@ -26,19 +28,27 @@
2628
from .exceptions.ledger_query_exception import LedgerQueryException
2729
from .exceptions.wallet_query_exception import WalletQueryException
2830
from .exceptions.refund_query_exception import RefundQueryException
31+
from .exceptions.payout_query_exception import PayoutQueryException
2932
from .exceptions.bill_creation_exception import BillCreationException
3033
from .exceptions.bill_delivery_exception import BillDeliveryException
3134
from .exceptions.refund_update_exception import RefundUpdateException
3235
from .exceptions.invoice_query_exception import InvoiceQueryException
3336
from .exceptions.invoice_update_exception import InvoiceUpdateException
3437
from .exceptions.refund_creation_exception import RefundCreationException
38+
from .exceptions.payout_creation_exception import PayoutCreationException
3539
from .exceptions.invoice_creation_exception import InvoiceCreationException
40+
from .exceptions.payoutbatch_query_exception import PayoutBatchQueryException
3641
from .exceptions.refund_notification_exception import RefundNotificationException
3742
from .exceptions.refund_cancellation_exception import RefundCancellationException
43+
from .exceptions.payout_cancellation_exception import PayoutCancellationException
44+
from .exceptions.payout_notification_exception import PayoutNotificationException
3845
from .exceptions.invoice_cancellation_exception import InvoiceCancellationException
3946
from .exceptions.invoice_notification_exception import InvoiceNotificationException
47+
from .exceptions.payoutbatch_creation_exception import PayoutBatchCreationException
4048
from .exceptions.payout_recipient_query_exception import PayoutRecipientQueryException
4149
from .exceptions.payout_recipient_update_exception import PayoutRecipientUpdateException
50+
from .exceptions.payoutbatch_cancellation_exception import PayoutBatchCancellationException
51+
from .exceptions.payoutbatch_notification_exception import PayoutBatchNotificationException
4252
from .exceptions.payout_recipient_creation_exception import PayoutRecipientCreationException
4353
from .exceptions.payout_recipient_cancellation_exception import PayoutRecipientCancellationException
4454
from .exceptions.payout_recipient_notification_exception import PayoutRecipientNotificationException
@@ -800,7 +810,8 @@ def get_payout_recipient(self, recipient_id: str) -> PayoutRecipient:
800810
" (PayoutRecipients) : %s" % str(exe))
801811
return payout_recipient
802812

803-
def get_payout_recipients(self, status, limit=100, offset=0) -> [PayoutRecipient]:
813+
def get_payout_recipients(self, status: str = None, limit: int = 100,
814+
offset: int = 0) -> [PayoutRecipient]:
804815
try:
805816
params = {"token": self.get_access_token(Facade.Payout),
806817
"limit": str(limit), "offset": str(offset)}
@@ -821,7 +832,7 @@ def get_payout_recipients(self, status, limit=100, offset=0) -> [PayoutRecipient
821832
" (PayoutRecipients) : %s" % str(exe))
822833
return payout_recipients
823834

824-
def update_payout_recipient(self, recipient_id, recipient: PayoutRecipient) -> PayoutRecipient:
835+
def update_payout_recipient(self, recipient_id: str, recipient: PayoutRecipient) -> PayoutRecipient:
825836
try:
826837
recipient.set_token(self.get_access_token(Facade.Payout))
827838

@@ -837,7 +848,7 @@ def update_payout_recipient(self, recipient_id, recipient: PayoutRecipient) -> P
837848
" (PayoutRecipients) : %s" % str(exe))
838849
return payout_recipient
839850

840-
def delete_payout_recipient(self, recipient_id) -> bool:
851+
def delete_payout_recipient(self, recipient_id: str) -> bool:
841852
try:
842853
params = {"token": self.get_access_token(Facade.Payout)}
843854
response_json = self.__restcli.delete("recipients/%s" % recipient_id, params)
@@ -852,7 +863,7 @@ def delete_payout_recipient(self, recipient_id) -> bool:
852863
" (PayoutRecipients) : %s" % str(exe))
853864
return payout_recipient
854865

855-
def request_payout_recipient_notification(self, recipient_id) -> bool:
866+
def request_payout_recipient_notification(self, recipient_id: str) -> bool:
856867
try:
857868
params = {"token": self.get_access_token(Facade.Payout)}
858869
response_json = self.__restcli.post("recipients/%s" % recipient_id + "/notifications", params)
@@ -866,3 +877,188 @@ def request_payout_recipient_notification(self, recipient_id) -> bool:
866877
raise PayoutRecipientNotificationException("failed to deserialize BitPay server response "
867878
" (PayoutRecipients) : %s" % str(exe))
868879
return payout_recipient
880+
881+
def submit_payout(self, payout: Payout) -> Payout:
882+
try:
883+
payout.set_token(self.get_access_token(Facade.Payout))
884+
payout.to_json()
885+
886+
response_json = self.__restcli.post("payouts", payout, True)
887+
except BitPayException as exe:
888+
raise PayoutCreationException("failed to serialize Payout object : %s" % str(exe),
889+
exe.get_api_code())
890+
891+
try:
892+
payout = Payout(**response_json)
893+
except Exception as exe:
894+
raise PayoutCreationException("failed to deserialize BitPay server response "
895+
" (Payout) : %s" % str(exe))
896+
return payout
897+
898+
def get_payout(self, payout_id: str) -> Payout:
899+
try:
900+
params = {"token": self.get_access_token(Facade.Payout)}
901+
response_json = self.__restcli.get("payouts/%s" % payout_id, params)
902+
except BitPayException as exe:
903+
raise PayoutQueryException("failed to serialize Payout object : %s" % str(exe),
904+
exe.get_api_code())
905+
906+
try:
907+
payout = Payout(**response_json)
908+
except Exception as exe:
909+
raise PayoutQueryException("failed to deserialize BitPay server response "
910+
" (Payout) : %s" % str(exe))
911+
return payout
912+
913+
def get_payouts(self, start_date: str = None, end_date: str = None,
914+
status: str = None, reference: str = None, limit: int = None,
915+
offset: int = None) -> [Payout]:
916+
try:
917+
params = {"token": self.get_access_token(Facade.Payout)}
918+
if start_date:
919+
params["startDate"] = start_date
920+
if end_date:
921+
params["endDate"] = end_date
922+
if status:
923+
params["status"] = status
924+
if reference:
925+
params["reference"] = reference
926+
if limit:
927+
params["limit"] = limit
928+
if offset:
929+
params["offset"] = offset
930+
931+
response_json = self.__restcli.get("payouts", params)
932+
except BitPayException as exe:
933+
raise PayoutQueryException("failed to serialize Payout object : %s" % str(exe),
934+
exe.get_api_code())
935+
936+
try:
937+
payouts = []
938+
for payout in response_json:
939+
payouts.append(Payout(**payout))
940+
except Exception as exe:
941+
raise PayoutQueryException("failed to deserialize BitPay server response "
942+
" (Payout) : %s" % str(exe))
943+
return payouts
944+
945+
def cancel_payout(self, payout_id: str) -> bool:
946+
try:
947+
params = {"token": self.get_access_token(Facade.Payout)}
948+
response_json = self.__restcli.delete("payouts/%s" % payout_id, params)
949+
except BitPayException as exe:
950+
raise PayoutCancellationException("failed to serialize Payout object : %s" % str(exe),
951+
exe.get_api_code())
952+
953+
try:
954+
payout = Payout(**response_json)
955+
except Exception as exe:
956+
raise PayoutCancellationException("failed to deserialize BitPay server response "
957+
" (Payout) : %s" % str(exe))
958+
return payout
959+
960+
def request_payout_notification(self, payout_id: str) -> bool:
961+
try:
962+
params = {"token": self.get_access_token(Facade.Payout)}
963+
response_json = self.__restcli.post("payouts/%s" % payout_id + "/notifications", params)
964+
except BitPayException as exe:
965+
raise PayoutNotificationException("failed to serialize Payout object : %s" % str(exe),
966+
exe.get_api_code())
967+
968+
try:
969+
payout = Payout(**response_json)
970+
except Exception as exe:
971+
raise PayoutNotificationException("failed to deserialize BitPay server response "
972+
" (Payout) : %s" % str(exe))
973+
return payout
974+
975+
def submit_payout_batch(self, batch: PayoutBatch) -> PayoutBatch:
976+
try:
977+
batch.set_token(self.get_access_token(Facade.Payout))
978+
batch.to_json()
979+
980+
response_json = self.__restcli.post("payoutBatches", batch, True)
981+
except BitPayException as exe:
982+
raise PayoutBatchCreationException("failed to serialize PayoutBatch object : %s" % str(exe),
983+
exe.get_api_code())
984+
985+
try:
986+
payout_batch = PayoutBatch(**response_json)
987+
except Exception as exe:
988+
raise PayoutBatchCreationException("failed to deserialize BitPay server response "
989+
" (PayoutBatch) : %s" % str(exe))
990+
return payout_batch
991+
992+
def get_payout_batch(self, payout_batch_id: str) -> PayoutBatch:
993+
try:
994+
params = {"token": self.get_access_token(Facade.Payout)}
995+
response_json = self.__restcli.get("payoutBatches/%s" % payout_batch_id, params)
996+
except BitPayException as exe:
997+
raise PayoutBatchQueryException("failed to serialize Payout object : %s" % str(exe),
998+
exe.get_api_code())
999+
1000+
try:
1001+
payout_batch = PayoutBatch(**response_json)
1002+
except Exception as exe:
1003+
raise PayoutBatchQueryException("failed to deserialize BitPay server response "
1004+
" (Payout) : %s" % str(exe))
1005+
return payout_batch
1006+
1007+
def get_payout_batches(self, start_date: str = None, end_date: str = None, status: str = None,
1008+
limit: int = None, offset: int = None) -> [PayoutBatch]:
1009+
try:
1010+
params = {"token": self.get_access_token(Facade.Payout)}
1011+
if start_date:
1012+
params["startDate"] = start_date
1013+
if end_date:
1014+
params["endDate"] = end_date
1015+
if status:
1016+
params["status"] = status
1017+
if limit:
1018+
params["limit"] = limit
1019+
if offset:
1020+
params["offset"] = offset
1021+
1022+
response_json = self.__restcli.get("payoutBatches", params)
1023+
except BitPayException as exe:
1024+
raise PayoutBatchQueryException("failed to serialize PayoutBatch object : %s" % str(exe),
1025+
exe.get_api_code())
1026+
1027+
try:
1028+
payout_batches = []
1029+
for payout_batch in response_json:
1030+
payout_batches.append(PayoutBatch(**payout_batch))
1031+
except Exception as exe:
1032+
raise PayoutBatchQueryException("failed to deserialize BitPay server response "
1033+
" (PayoutBatch) : %s" % str(exe))
1034+
return payout_batches
1035+
1036+
def cancel_payout_batch(self, payout_batch_id: str) -> bool:
1037+
try:
1038+
params = {"token": self.get_access_token(Facade.Payout)}
1039+
response_json = self.__restcli.delete("payoutBatches/%s" % payout_batch_id, params)
1040+
except BitPayException as exe:
1041+
raise PayoutBatchCancellationException("failed to serialize PayoutBatch object : %s" % str(exe),
1042+
exe.get_api_code())
1043+
1044+
try:
1045+
payout_batch = PayoutBatch(**response_json)
1046+
except Exception as exe:
1047+
raise PayoutBatchCancellationException("failed to deserialize BitPay server response "
1048+
" (PayoutBatch) : %s" % str(exe))
1049+
return payout_batch
1050+
1051+
def request_payout_batch_notification(self, payout_batch_id: str):
1052+
try:
1053+
params = {"token": self.get_access_token(Facade.Payout)}
1054+
response_json = self.__restcli.post("payoutBatches/%s" % payout_batch_id + "/notifications", params)
1055+
except BitPayException as exe:
1056+
raise PayoutBatchNotificationException("failed to serialize PayoutBatch object : %s" % str(exe),
1057+
exe.get_api_code())
1058+
1059+
try:
1060+
payout_batch = PayoutBatch(**response_json)
1061+
except Exception as exe:
1062+
raise PayoutBatchNotificationException("failed to deserialize BitPay server response "
1063+
" (PayoutBatch) : %s" % str(exe))
1064+
return payout_batch
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""
2+
Payout Cancellation exception gets raised when it fails to cancel payout.
3+
"""
4+
from .payout_exception import PayoutException
5+
6+
7+
class PayoutCancellationException(PayoutException):
8+
"""
9+
PayoutCancellationException
10+
"""
11+
__bitpay_message = "Failed to cancel payout object"
12+
__bitpay_code = "BITPAY-PAYOUT-CANCEL"
13+
__api_code = ""
14+
15+
def __init__(self, message, code=124, api_code="000000"):
16+
"""
17+
Construct the PayoutCancellationException.
18+
19+
:param message: The Exception message to throw.
20+
:param code: [optional] The Exception code to throw.
21+
:param api_code: [optional] The API Exception code to throw.
22+
"""
23+
message = self.__bitpay_code + ": " + self.__bitpay_message + ":" + message
24+
self.__api_code = api_code
25+
super().__init__(message, code)
26+
27+
# def get_api_code(self):
28+
# """
29+
# :return: Error code provided by the BitPay REST API
30+
# """
31+
# return self.__api_code
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""
2+
Payout Creation Exception gets raised when request for payout creation gets failed.
3+
"""
4+
from .payout_exception import PayoutException
5+
6+
7+
class PayoutCreationException(PayoutException):
8+
"""
9+
PayoutCreationException
10+
"""
11+
__bitpay_message = "Failed to create payout"
12+
__bitpay_code = "BITPAY-PAYOUT-CREATE"
13+
__api_code = ""
14+
15+
def __init__(self, message, code=122, api_code="000000"):
16+
"""
17+
Construct the PayoutCreationException.
18+
19+
:param message: The Exception message to throw.
20+
:param code: [optional] The Exception code to throw.
21+
:param api_code: [optional] The API Exception code to throw.
22+
"""
23+
message = self.__bitpay_code + ": " + self.__bitpay_message + ":" + message
24+
self.__api_code = api_code
25+
super().__init__(message, code)
26+
27+
# def get_api_code(self):
28+
# return self.__api_code
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""
2+
Payout Exception gets raised when some unexpected error occurs while processing a request
3+
or trying to manage payout.
4+
"""
5+
from .bitpay_exception import BitPayException
6+
7+
8+
class PayoutException(BitPayException):
9+
"""
10+
PayoutException
11+
"""
12+
__bitpay_message = "An unexpected error occurred while trying to manage the payout"
13+
__bitpay_code = "BITPAY-PAYOUT-GENERIC"
14+
__api_code = ""
15+
16+
def __init__(self, message="", code=121, api_code="000000"):
17+
"""
18+
Construct the PayoutException.
19+
20+
:param message: The Exception message to throw.
21+
:param code: [optional] The Exception code to throw.
22+
:param api_code: [optional] The API Exception code to throw.
23+
"""
24+
message = self.__bitpay_code + ": " + self.__bitpay_message + ":" + message
25+
self.__api_code = api_code
26+
super().__init__(message, code)
27+
28+
# def get_api_code(self):
29+
# """
30+
# :return: Error code provided by the BitPay REST API
31+
# """
32+
# return self.__api_code
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""
2+
Payout Notification Exception gets raised when webhook fails to send notification
3+
"""
4+
from .payout_exception import PayoutException
5+
6+
7+
class PayoutNotificationException(PayoutException):
8+
"""
9+
PayoutNotificationException
10+
"""
11+
__bitpay_message = "Failed to send payout notification"
12+
__bitpay_code = "BITPAY-PAYOUT-NOTIFICATION"
13+
__api_code = ""
14+
15+
def __init__(self, message, code=126, api_code="000000"):
16+
"""
17+
Construct the PayoutNotificationException.
18+
19+
:param message: The Exception message to throw.
20+
:param code: [optional] The Exception code to throw.
21+
:param api_code: [optional] The API Exception code to throw.
22+
"""
23+
message = self.__bitpay_code + ": " + self.__bitpay_message + ":" + message
24+
self.__api_code = api_code
25+
super().__init__(message, code)
26+
27+
# def get_api_code(self):
28+
# """
29+
# :return: Error code provided by the BitPay REST API
30+
# """
31+
# return self.__api_code

0 commit comments

Comments
 (0)