Created
July 20, 2018 04:43
-
-
Save levivm/cf898a45f095f2d8d00e799c031454e8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from zeep import Client | |
from zeep.helpers import serialize_object | |
from rest_framework import status | |
import traceback | |
import sys | |
from mo_integration.communication import services as communication_service | |
from .exceptions import ( | |
CriticalBSAPIResponse, | |
ServiceBSUnavailable, | |
MerchantNotFound, | |
OtherBSException, | |
BSMalformedResponse | |
) | |
from .mixins import ( | |
ParseXMLResponseMixin, | |
RenameResponseAttributesMixin | |
) | |
from ..constants import ( | |
PARTNER_API_URL, | |
PARTNER_API_USERNAME, | |
PARTNER_API_PASSWORD, | |
SENSITIVE_PARTNER_API_URL, | |
SENSITIVE_PARTNER_API_USERNAME, | |
SENSITIVE_PARTNER_API_PASSWORD, | |
BlackstoneResponseCode | |
) | |
from ..utils import ( | |
convert_dict_values_to_str | |
) | |
from mo_security.security.mixins import ( | |
KinesisLogViewMixin | |
) | |
class BlackstoneAPI( | |
ParseXMLResponseMixin, | |
RenameResponseAttributesMixin, | |
KinesisLogViewMixin | |
): | |
WSDL_URL = None | |
soap_client = None | |
BLACKSTONE_USERNAME = None | |
BLACKSTONE_PASSWORD = None | |
def __init__(self, wsdl_url, username, password): | |
if not self.soap_client: | |
self.WSDL_URL = wsdl_url | |
self.BLACKSTONE_USERNAME = username | |
self.BLACKSTONE_PASSWORD = password | |
self.soap_client = self.get_soap_client() | |
def get_soap_client(self): | |
""" | |
:return: client: Client | |
""" | |
try: | |
client = Client(self.WSDL_URL) | |
except Exception as e: | |
exc_type, exc_value, exc_traceback = sys.exc_info() | |
msg = ServiceBSUnavailable.default_detail\ | |
.format(type(e).__name__, e.args) | |
trace = repr(traceback.extract_tb(exc_traceback)) | |
communication_service\ | |
.alert_error_communication_with_partner(msg, trace) | |
exp = ServiceBSUnavailable(msg) | |
data_to_log = dict(response_detail=exp.get_full_details()) | |
self.log_kinesis_partner_connection(data_to_log) | |
raise exp | |
return client | |
@classmethod | |
def parse_xml_response(cls, xml_response): | |
""" | |
Parse and validate the response dict | |
:param xml_response: dict | |
:return: dict | |
""" | |
parsed_response = cls.parse_xml_raw_response( | |
xml_response | |
) | |
cls.validate_response(parsed_response) | |
parsed_response_content = cls.parse_xml_raw_content(xml_response) | |
return parsed_response_content | |
@classmethod | |
def parse_response(cls, response): | |
""" | |
:param response: json | |
:return: parsed_response: dict | |
""" | |
if not cls.is_complex_response(response): | |
serialized_object = serialize_object(response) | |
cls.validate_response(serialized_object) | |
return serialized_object | |
try: | |
parsed_response = cls.parse_xml_response( | |
response | |
) | |
except AttributeError as exception: | |
raise BSMalformedResponse | |
return parsed_response | |
@classmethod | |
def validate_response(cls, parsed_response): | |
""" | |
Validate the response code from parsed response | |
if is not valid raise an exception | |
:param parsed_response: | |
""" | |
if not parsed_response.get('ErrorCode') is None: | |
code = parsed_response.get('ErrorCode') | |
message = parsed_response.get('ErrorDescription') | |
else: | |
code = parsed_response.get('response')\ | |
.get('response_code') | |
message = parsed_response.get('response')\ | |
.get('response_description') | |
if BlackstoneResponseCode.is_critical_response(code): | |
exception = BlackstoneResponseCode.get_api_exception_by_code( | |
code | |
) | |
raise exception( | |
"Error code: {0} \nError message: {1}" | |
.format( | |
code, | |
message | |
) | |
) | |
if not BlackstoneResponseCode.is_success_response(code): | |
exception = BlackstoneResponseCode.get_api_exception_by_code( | |
code | |
) | |
if exception.status_code == status.HTTP_404_NOT_FOUND: | |
raise exception | |
raise exception({ | |
'non_field_errors': [message] | |
}) | |
@classmethod | |
def alert_invalid_response_code( | |
cls, | |
request_data, | |
service_name, | |
exception, | |
receivers=None | |
): | |
""" | |
Alert the invalid response code received from BS | |
:param request_data: dict | |
:param service_name: str | |
:param exception: Exception | |
:param receivers: list | |
:return: | |
""" | |
del request_data['credential'] | |
request_data = convert_dict_values_to_str(request_data) | |
communication_service.alert_invalid_response_code_from_partner( | |
service_name=service_name, | |
data_sent=request_data, | |
exception_message=exception.get_full_details(), | |
receivers=receivers | |
) | |
def send_unauthorized_request(self, service_name, data=None): | |
"""" | |
:param service_name: str | |
:param data: dict | |
:return: res | |
""" | |
soap_method = getattr( | |
self.soap_client.service, | |
service_name, | |
None | |
) | |
request_data = { | |
'request': data | |
} if data else {} | |
return self.call_request_method( | |
soap_method, | |
request_data, | |
service_name | |
) | |
def send_request(self, service_name, data=None): | |
""" | |
:param service_name: str | |
:param data: dict | |
:return: res | |
""" | |
soap_method = getattr( | |
self.soap_client.service, | |
service_name, | |
None | |
) | |
request_data = { | |
'credential': { | |
'Username': self.BLACKSTONE_USERNAME, | |
'Password': self.BLACKSTONE_PASSWORD | |
}, | |
'request': data | |
} | |
return self.call_request_method( | |
soap_method, | |
request_data, | |
service_name | |
).get( | |
'content', | |
) | |
def call_request_method(self, soap_method, request_data, service_name): | |
""" | |
:param soap_method: function | |
:param request_data: dict | |
:param service_name: str | |
:return: dict | |
""" | |
parsed_response = {} | |
data_to_log = dict( | |
service_name=service_name, | |
request_data=request_data, | |
response_detail="" | |
) | |
try: | |
response = soap_method(**request_data) | |
parsed_response = self.parse_response(response) | |
data_to_log.update(dict( | |
response_detail=u'Transaction success', | |
)) | |
except CriticalBSAPIResponse as critical_exception: | |
self.alert_invalid_response_code( | |
request_data, | |
service_name, | |
critical_exception | |
) | |
data_to_log.update(dict( | |
response_detail=critical_exception.get_full_details()) | |
) | |
self.log_kinesis_partner_request(data_to_log) | |
raise critical_exception | |
except MerchantNotFound as merchant_not_found_exception: | |
receivers = [ | |
'[email protected]', | |
'[email protected]', | |
'[email protected]' | |
] | |
self.alert_invalid_response_code( | |
request_data, | |
service_name, | |
merchant_not_found_exception, | |
receivers | |
) | |
data_to_log.update( | |
dict( | |
response_detail=merchant_not_found_exception | |
.get_full_details() | |
) | |
) | |
self.log_kinesis_partner_request(data_to_log) | |
raise merchant_not_found_exception | |
except OtherBSException as other_bs_exception: | |
self.alert_invalid_response_code( | |
request_data, | |
service_name, | |
other_bs_exception | |
) | |
data_to_log.update( | |
dict( | |
response_detail=other_bs_exception.get_full_details() | |
) | |
) | |
self.log_kinesis_partner_request(data_to_log) | |
raise other_bs_exception | |
except BSMalformedResponse as bs_malformed_response: | |
self.alert_invalid_response_code( | |
request_data, | |
service_name, | |
bs_malformed_response | |
) | |
data_to_log.update( | |
dict(response_detail=bs_malformed_response) | |
) | |
communication_service.alert_error_communication_with_partner( | |
bs_malformed_response.get_full_details() | |
) | |
self.log_kinesis_partner_request(data_to_log) | |
raise BSMalformedResponse( | |
dict( | |
non_field_errors=[ | |
bs_malformed_response.error_display_message | |
] | |
) | |
) | |
except Exception as e: | |
exc_type, exc_value, exc_traceback = sys.exc_info() | |
trace = repr(traceback.extract_tb(exc_traceback)) | |
error_message = ServiceBSUnavailable.default_detail.format( | |
type(e).__name__, | |
e.args | |
) | |
communication_service.alert_error_communication_with_partner( | |
error_message, | |
trace | |
) | |
exp = ServiceBSUnavailable(error_message) | |
data_to_log.update( | |
dict( | |
response_detail=exp.get_full_details() | |
) | |
) | |
self.log_kinesis_partner_request(data_to_log) | |
raise exp | |
self.log_kinesis_partner_request(data_to_log) | |
return parsed_response | |
class PublicBlackstoneAPI(BlackstoneAPI): | |
API_URL = PARTNER_API_URL | |
USERNAME = PARTNER_API_USERNAME | |
PASSWORD = PARTNER_API_PASSWORD | |
def __init__(self): | |
super(PublicBlackstoneAPI, self).__init__( | |
self.API_URL, | |
self.USERNAME, | |
self.PASSWORD | |
) | |
def get_merchants_info_from_phone_or_email( | |
self, | |
phone_number=None, | |
email=None | |
): | |
""" | |
Verify merchant's email or phone number | |
US_ID = 571 | |
:param phone_number: str | |
:param email: str | |
:return: external_id: str | |
""" | |
SERVICE_NAME = 'VerifyMerchant' | |
data = { | |
'merchant_emailaddress': email | |
} if email else { | |
'merchant_phonenumber': phone_number | |
} | |
response = self.send_request( | |
SERVICE_NAME, | |
data | |
) | |
renamed_response = self.rename_response_attributes( | |
response, | |
[ | |
('merchant_fk', 'merchant_id'), | |
('merchant_busphone', 'phone_number'), | |
('merchant_BusinessName', 'merchant_name'), | |
('merchant_email', 'email'), | |
] | |
) | |
return renamed_response | |
def get_merchants_data_by_date( | |
self, | |
from_date=None, | |
to_date=None | |
): | |
""" | |
Get the anonymous information for merchants | |
US_ID = 567 | |
:param from_date: str | |
:param to_date: str | |
:return: dict | |
""" | |
SERVICE_NAME = 'Retrievemerchants' | |
data = dict( | |
dateTo=to_date, | |
dateFrom=from_date | |
) | |
return self.send_request( | |
SERVICE_NAME, | |
data | |
) | |
def update_merchant_amount_cash_advance( | |
self, | |
merchant_pk=None, | |
merchant_mcaa=None, | |
merchant_mo_status=None | |
): | |
""" | |
Notify BS the Merchants Maximum Amount of Cash Advance (ACA) and | |
MO status | |
US_ID = 569 | |
:param merchant_pk: int | |
:param merchant_mcaa: decimal | |
:param merchant_mo_status: str | |
:return: dict | |
""" | |
SERVICE_NAME = 'UpdateMCAAStatus' | |
data = dict( | |
merchant_pk=merchant_pk, | |
merchant_MCAA=merchant_mcaa, | |
merchant_MO_Status=merchant_mo_status | |
) | |
response = self.send_request( | |
SERVICE_NAME, | |
data | |
) | |
return response | |
def retrieve_all_merchants_status(self, dateFrom, dateTo): | |
""" | |
service US_ID = 577 | |
:param dateFrom: str | |
:param dateTo: str | |
:return: dict | |
""" | |
data = dict( | |
dateFrom=dateFrom, | |
dateTo=dateTo | |
) | |
service = "Retrievestatusupdates" | |
return self.send_request(service, data) | |
def notify_merchant_registration( | |
self, | |
merchant_id=None | |
): | |
""" | |
Notify BS that a new merchant was registered | |
US_ID = 572 | |
:param merchant_id: | |
:return: dict | |
""" | |
SERVICE_NAME = 'RegisterMerchant' | |
data = dict( | |
merchant_pk=str(merchant_id), | |
) | |
response = self.send_request( | |
SERVICE_NAME, | |
data | |
) | |
return response | |
def echo(self): | |
""" | |
Echo service | |
US_ID = 578 | |
:return: | |
""" | |
SERVICE_NAME = 'Echo' | |
response = self.send_unauthorized_request( | |
SERVICE_NAME | |
) | |
return response | |
class PrivateBlackstoneAPI(BlackstoneAPI): | |
API_URL = SENSITIVE_PARTNER_API_URL | |
USERNAME = SENSITIVE_PARTNER_API_USERNAME | |
PASSWORD = SENSITIVE_PARTNER_API_PASSWORD | |
def __init__(self): | |
super(PrivateBlackstoneAPI, self).__init__( | |
self.API_URL, | |
self.USERNAME, | |
self.PASSWORD | |
) | |
def update_merchant_basic_information(self, merchant_id): | |
""" | |
service US_ID = 573 | |
:param merchant_id: int | |
:return: dict | |
""" | |
data = dict( | |
merchant_pk=merchant_id, | |
) | |
service = "Retrievemerchantbankupdte" | |
return self.send_request(service, data) | |
def get_merchant_basic_information(self, merchant_id): | |
""" | |
service US_ID = 570 | |
:param merchant_id: int | |
:return: dict | |
""" | |
data = dict( | |
merchant_pk=merchant_id, | |
) | |
service = "RetrieveMerchantinformation" | |
return self.send_request(service, data) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment