Skip to content

Commit dc316a3

Browse files
committed
Added payout recipient model, method and exceptions,tested setup method in test cases with different scenarios
1 parent 0cda8ab commit dc316a3

11 files changed

+483
-6
lines changed

src/bitpay_sdk/client.py

Lines changed: 112 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import json
1010

1111
from .config import Config
12-
from .exceptions.invoice_creation_exception import InvoiceCreationException
1312
from .tokens import Tokens
1413
from .models.facade import Facade
1514
from .models.bill.bill import Bill
@@ -20,6 +19,8 @@
2019
from .models.invoice.invoice import Invoice
2120
from .models.ledger.ledger_entry import LedgerEntry
2221
from .exceptions.bitpay_exception import BitPayException
22+
from .models.payout.payout_recipient import PayoutRecipient
23+
from .models.payout.payout_recipients import PayoutRecipients
2324
from .exceptions.bill_query_exception import BillQueryException
2425
from .exceptions.bill_update_exception import BillUpdateException
2526
from .exceptions.ledger_query_exception import LedgerQueryException
@@ -31,10 +32,16 @@
3132
from .exceptions.invoice_query_exception import InvoiceQueryException
3233
from .exceptions.invoice_update_exception import InvoiceUpdateException
3334
from .exceptions.refund_creation_exception import RefundCreationException
35+
from .exceptions.invoice_creation_exception import InvoiceCreationException
3436
from .exceptions.refund_notification_exception import RefundNotificationException
3537
from .exceptions.refund_cancellation_exception import RefundCancellationException
3638
from .exceptions.invoice_cancellation_exception import InvoiceCancellationException
3739
from .exceptions.invoice_notification_exception import InvoiceNotificationException
40+
from .exceptions.payout_recipient_query_exception import PayoutRecipientQueryException
41+
from .exceptions.payout_recipient_update_exception import PayoutRecipientUpdateException
42+
from .exceptions.payout_recipient_creation_exception import PayoutRecipientCreationException
43+
from .exceptions.payout_recipient_cancellation_exception import PayoutRecipientCancellationException
44+
from .exceptions.payout_recipient_notification_exception import PayoutRecipientNotificationException
3845

3946

4047
class Client:
@@ -100,6 +107,7 @@ def build_config(self, private_key_path: str, tokens: Tokens):
100107
read_file = open(private_key_path, 'r')
101108
plain_private_key = read_file.read()
102109
self.__ec_key = plain_private_key
110+
read_file.close()
103111
else:
104112
raise BitPayException("Private Key file not found")
105113

@@ -132,7 +140,10 @@ def init_keys(self):
132140

133141
def init(self):
134142
try:
135-
proxy = self.__configuration.get_envconfig()[self.__env]["proxy"]
143+
proxy = None
144+
if "proxy" in self.__configuration.get_envconfig()[self.__env]:
145+
proxy = self.__configuration.get_envconfig()[self.__env]["proxy"]
146+
136147
self.__restcli = RESTcli(self.__env, self.__ec_key, proxy)
137148
self.load_access_tokens()
138149
self.__currencies_info = self.load_currencies()
@@ -754,3 +765,102 @@ def get_ledgers(self) -> [Ledger]:
754765
raise LedgerQueryException("failed to deserialize BitPay server response"
755766
" (Ledger) : %s" % str(exe))
756767
return ledgers
768+
769+
def submit_payout_recipients(self, recipients: PayoutRecipients) -> [PayoutRecipient]:
770+
try:
771+
recipients.set_token(self.get_access_token(Facade.Payout))
772+
recipients.to_json()
773+
774+
response_json = self.__restcli.post("recipients", recipients, True)
775+
except BitPayException as exe:
776+
raise PayoutRecipientCreationException("failed to serialize PayoutRecipients object : %s" % str(exe),
777+
exe.get_api_code())
778+
779+
try:
780+
payout_recipients = PayoutRecipient(**response_json)
781+
except Exception as exe:
782+
raise PayoutRecipientCreationException("failed to deserialize BitPay server response "
783+
" (PayoutRecipients) : %s" % str(exe))
784+
return payout_recipients
785+
786+
def get_payout_recipient(self, recipient_id: str) -> PayoutRecipient:
787+
try:
788+
params = {"token": self.get_access_token(Facade.Payout)}
789+
response_json = self.__restcli.get("recipients/%s" % recipient_id, params)
790+
except BitPayException as exe:
791+
raise PayoutRecipientQueryException("failed to serialize PayoutRecipients object : %s" % str(exe),
792+
exe.get_api_code())
793+
794+
try:
795+
payout_recipient = PayoutRecipient(**response_json)
796+
except Exception as exe:
797+
raise PayoutRecipientQueryException("failed to deserialize BitPay server response "
798+
" (PayoutRecipients) : %s" % str(exe))
799+
return payout_recipient
800+
801+
def get_payout_recipients(self, status, limit=100, offset=0) -> [PayoutRecipient]:
802+
try:
803+
params = {"token": self.get_access_token(Facade.Payout),
804+
"limit": str(limit), "offset": str(offset)}
805+
if status:
806+
params["status"] = status
807+
808+
response_json = self.__restcli.get("recipients", params)
809+
except BitPayException as exe:
810+
raise PayoutRecipientQueryException("failed to serialize PayoutRecipients object : %s" % str(exe),
811+
exe.get_api_code())
812+
813+
try:
814+
payout_recipients = []
815+
for payout_recipient in response_json:
816+
payout_recipients.append(PayoutRecipient(**payout_recipient))
817+
except Exception as exe:
818+
raise PayoutRecipientQueryException("failed to deserialize BitPay server response "
819+
" (PayoutRecipients) : %s" % str(exe))
820+
return payout_recipients
821+
822+
def update_payout_recipient(self, recipient_id, recipient: PayoutRecipient) -> PayoutRecipient:
823+
try:
824+
recipient.set_token(self.get_access_token(Facade.Payout))
825+
826+
response_json = self.__restcli.update("recipients/%s" % recipient_id, recipient.to_json())
827+
except BitPayException as exe:
828+
raise PayoutRecipientUpdateException("failed to serialize PayoutRecipients object : %s" % str(exe),
829+
exe.get_api_code())
830+
831+
try:
832+
payout_recipient = PayoutRecipient(**response_json)
833+
except Exception as exe:
834+
raise PayoutRecipientUpdateException("failed to deserialize BitPay server response "
835+
" (PayoutRecipients) : %s" % str(exe))
836+
return payout_recipient
837+
838+
def delete_payout_recipient(self, recipient_id) -> bool:
839+
try:
840+
params = {"token": self.get_access_token(Facade.Payout)}
841+
response_json = self.__restcli.delete("recipients/%s" % recipient_id, params)
842+
except BitPayException as exe:
843+
raise PayoutRecipientCancellationException("failed to serialize PayoutRecipients object : %s" % str(exe),
844+
exe.get_api_code())
845+
846+
try:
847+
payout_recipient = PayoutRecipient(**response_json)
848+
except Exception as exe:
849+
raise PayoutRecipientCancellationException("failed to deserialize BitPay server response "
850+
" (PayoutRecipients) : %s" % str(exe))
851+
return payout_recipient
852+
853+
def request_payout_recipient_notification(self, recipient_id) -> bool:
854+
try:
855+
params = {"token": self.get_access_token(Facade.Payout)}
856+
response_json = self.__restcli.post("recipients/%s" % recipient_id + "/notifications", params)
857+
except BitPayException as exe:
858+
raise PayoutRecipientNotificationException("failed to serialize PayoutRecipients object : %s" % str(exe),
859+
exe.get_api_code())
860+
861+
try:
862+
payout_recipient = PayoutRecipient(**response_json)
863+
except Exception as exe:
864+
raise PayoutRecipientNotificationException("failed to deserialize BitPay server response "
865+
" (PayoutRecipients) : %s" % str(exe))
866+
return payout_recipient
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""
2+
PayoutRecipient Cancellation exception gets raised when it fails to cancel payout recipient.
3+
"""
4+
from .payout_recipient_exception import PayoutRecipientException
5+
6+
7+
class PayoutRecipientCancellationException(PayoutRecipientException):
8+
"""
9+
PayoutRecipientCancellationException
10+
"""
11+
__bitpay_message = "Failed to cancel payout recipient"
12+
__bitpay_code = "BITPAY-PAYOUT-RECIPIENT-CANCEL"
13+
__api_code = ""
14+
15+
def __init__(self, message, code=194, api_code="000000"):
16+
"""
17+
Construct the PayoutRecipientCancellationException.
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+
PayoutRecipientCreation Exception gets raised when request for recipient creation gets failed.
3+
"""
4+
from .payout_recipient_exception import PayoutRecipientException
5+
6+
7+
class PayoutRecipientCreationException(PayoutRecipientException):
8+
"""
9+
PayoutRecipientCreationException
10+
"""
11+
__bitpay_message = "Failed to create payout recipient"
12+
__bitpay_code = "BITPAY-PAYOUT-RECIPIENT-SUBMIT"
13+
__api_code = ""
14+
15+
def __init__(self, message, code=112, api_code="000000"):
16+
"""
17+
Construct the PayoutRecipientCreationException.
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: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
"""
2+
PayoutRecipient Exception gets raised when some unexpected error occurs while processing a request
3+
or trying to manage recipients.
4+
"""
5+
from .bitpay_exception import BitPayException
6+
7+
8+
class PayoutRecipientException(BitPayException):
9+
"""
10+
PayoutRecipientException
11+
"""
12+
__bitpay_message = "An unexpected error occurred while trying to manage the payout recipient"
13+
__bitpay_code = "BITPAY-PAYOUT-RECIPIENT-GENERIC"
14+
__api_code = ""
15+
16+
def __init__(self, message="", code=191, api_code="000000"):
17+
"""
18+
Construct the Payout Recipient Exception.
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+
# return self.__api_code
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""
2+
PayoutRecipientNotification Exception gets raised when webhook fails to send notification
3+
"""
4+
from .payout_recipient_exception import PayoutRecipientException
5+
6+
7+
class PayoutRecipientNotificationException(PayoutRecipientException):
8+
"""
9+
PayoutRecipientNotificationException
10+
"""
11+
__bitpay_message = "Failed to send payout recipient notification"
12+
__bitpay_code = "BITPAY-PAYOUT-RECIPIENT-NOTIFICATION"
13+
__api_code = ""
14+
15+
def __init__(self, message, code=196, api_code="000000"):
16+
"""
17+
Construct the PayoutRecipientNotificationException.
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: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""
2+
PayoutRecipientQuery Exception gets raised when request for recipient retrieval gets failed .
3+
"""
4+
from .invoice_exception import InvoiceException
5+
6+
7+
class PayoutRecipientQueryException(InvoiceException):
8+
"""
9+
PayoutRecipientQueryException
10+
"""
11+
__bitpay_message = "Failed to retrieve payout recipient"
12+
__bitpay_code = "BITPAY-PAYOUT-RECIPIENT-GET"
13+
__api_code = ""
14+
15+
def __init__(self, message, code=193, api_code="000000"):
16+
"""
17+
Construct the PayoutRecipientQueryException.
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+
PayoutRecipientUpdate Exception gets raised when it fails to update recipient
3+
"""
4+
from .payout_recipient_exception import PayoutRecipientException
5+
6+
7+
class PayoutRecipientUpdateException(PayoutRecipientException):
8+
"""
9+
PayoutRecipientUpdateException
10+
"""
11+
__bitpay_message = "Failed to update payout recipient"
12+
__bitpay_code = "BITPAY-PAYOUT-RECIPIENT-UPDATE"
13+
__api_code = ""
14+
15+
def __init__(self, message, code=195, api_code="000000"):
16+
"""
17+
Construct the PayoutRecipientUpdateException.
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

0 commit comments

Comments
 (0)