diff --git a/paymentwall/__init__.py b/paymentwall/__init__.py new file mode 100644 index 0000000..934a9b8 --- /dev/null +++ b/paymentwall/__init__.py @@ -0,0 +1,7 @@ +from paymentwall.base import Paymentwall +from paymentwall.product import Product +from paymentwall.widget import Widget +from paymentwall.pingback import Pingback +from paymentwall.charge import Charge +from paymentwall.subscription import Subscription +from paymentwall.onetimetoken import OneTimeToken \ No newline at end of file diff --git a/paymentwall/apiobject.py b/paymentwall/apiobject.py new file mode 100644 index 0000000..857f38a --- /dev/null +++ b/paymentwall/apiobject.py @@ -0,0 +1,88 @@ +from paymentwall.httpaction import Httpaction +from paymentwall.base import Paymentwall +import json + +class ApiObject(Paymentwall, Httpaction): + API_BRICK_SUBPATH = 'brick' + API_OBJECT_CHARGE = 'charge' + API_OBJECT_SUBSCRIPTION = 'subscription' + API_OBJECT_ONE_TIME_TOKEN = 'token' + BRICK_ENDPOINTS = (API_OBJECT_CHARGE, API_OBJECT_SUBSCRIPTION, API_OBJECT_ONE_TIME_TOKEN) + + api_response = {} + + def __init__(self, id='', obj=''): + self.id = id + self.obj = obj + + def get_endpoint_name(self): + if self.obj and self.obj in self.BRICK_ENDPOINTS: + return self.obj + else: + return '' + + def get_api_url(self): + if self.obj == 'token' and self.is_test() == False: + return 'https://pwgateway.com/api/token' + else: + return self.BASE + '/' + self.API_BRICK_SUBPATH + '/' + self.get_endpoint_name() + + def get_api_header(self): + return {'X-ApiKey': self.get_secret_key()} if self.obj != 'token' else {} + + def build_query(self, params): + query = '' + for key, value in params.items(): + query = query + '&' + key + '=' + value + return query + + def do_api_action(self, action='', params={}, method='post'): + action_url = self.get_api_url() + '/' + self.id + '/' + action + http_action = Httpaction(action_url, params=params, header=self.get_api_header()) if method == 'post' else Httpaction(action_url + self.build_query(params), params={}, header={}) + response = http_action.api_request(method=method).text + self.set_response(json.loads(response)) + + def set_response(self, response): + if response: + self.api_response = response + return + else: + return 'Empty response' + + def get_response(self): + return self.api_response + + def get_public_data(self): + response = self.get_response() + result = {} + if 'type' in response and response['type'] == 'Error': + result = { + 'success': 0, + 'error': { + 'message': response['error'], + 'code': response['code'] + } + } + elif 'secure' in response and not self.object_response(): + result = { + 'success': 0, + 'secure': response['secure'] + } + elif self.object_response(): + result['success'] = 1 + else: + result = { + 'success': 0, + 'error': { + 'message': 'Internal error' + } + } + return result + + def create(self, params): + http_action = Httpaction(self.get_api_url(), params, self.get_api_header()) + response = http_action.api_request().text + self.set_response(json.loads(response)) + + def object_response(self): + return True if self.get_response()['object'] else False \ No newline at end of file diff --git a/paymentwall/base.py b/paymentwall/base.py index 82015e4..9becd8e 100644 --- a/paymentwall/base.py +++ b/paymentwall/base.py @@ -12,6 +12,7 @@ class Paymentwall: VC_CONTROLLER = 'ps' GOODS_CONTROLLER = 'subscription' CART_CONTROLLER = 'cart' + BASE = 'https://api.paymentwall.com/api' DEFAULT_SIGNATURE_VERSION = 3 SIGNATURE_VERSION_1 = 1 @@ -48,6 +49,10 @@ def set_secret_key(cls, secret_key): def get_secret_key(cls): return cls.secret_key + @classmethod + def is_test(cls): + return cls.app_key.find('t_') != -1 + @classmethod def append_to_errors(cls, err): cls.errors.append(err) @@ -86,3 +91,24 @@ def hash(cls, string, library_type): hashed_string = hashlib.md5() if library_type == 'md5' else hashlib.sha256() hashed_string.update(string.encode('utf-8')) return hashed_string.hexdigest() + + @classmethod + def request_calculate_signature(self, params, secret, version): + base_string = '' + is_array = lambda var: isinstance(var, (list, tuple)) + + params = sorted(params.items()) + + for i in range(len(params)): + if is_array(params[i][1]): + for key in range(len(params[i][1])): + base_string += str(params[i][0]) + '[' + str(key) + ']=' + str(params[i][1][key]) + else: + base_string += str(params[i][0]) + '=' + str(params[i][1]) + + base_string += secret + + if version == self.SIGNATURE_VERSION_2: + return self.hash(base_string, 'md5') + + return self.hash(base_string, 'sha256') \ No newline at end of file diff --git a/paymentwall/charge.py b/paymentwall/charge.py new file mode 100644 index 0000000..5bca05b --- /dev/null +++ b/paymentwall/charge.py @@ -0,0 +1,35 @@ +from paymentwall.apiobject import ApiObject + +class Charge(ApiObject): + def __init__(self, id=''): + ApiObject.__init__(self, id=id, obj='charge') if id else ApiObject.__init__(self, obj='charge') + + def get_id(self): + return self.id + + def get_token(self): + return self.get_response()['card']['token'] + + def is_test(self): + return self.get_response()['test'] + + def is_captured(self): + return self.get_response()['captured'] + + def is_successful(self): + return self.object_response() + + def is_under_review(self): + return self.get_response()['risk'] == 'pending' + + def is_refunded(self): + return self.get_response()['refunded'] + + def refund(self): + return self.do_api_action(action='refund') + + def capture(self): + return self.do_api_action(action='capture') + + def void(self): + return self.do_api_action(action='void') \ No newline at end of file diff --git a/paymentwall/httpaction.py b/paymentwall/httpaction.py new file mode 100644 index 0000000..884af85 --- /dev/null +++ b/paymentwall/httpaction.py @@ -0,0 +1,22 @@ +import requests + +class Httpaction(): + def __init__(self, baseurl, params, header): + self.baseurl = baseurl + self.params = params + self.header = header + + def get_base_url(self): + return self.baseurl + + def get_request_params(self): + return self.params + + def get_header_params(self): + return self.header + + def api_request(self, method='post'): + request_object = requests.post(self.baseurl, data=self.params, headers=self.header) + if method == 'get': + request_object = requests.get(self.baseurl, data=self.params, headers=self.header) + return request_object \ No newline at end of file diff --git a/paymentwall/onetimetoken.py b/paymentwall/onetimetoken.py new file mode 100644 index 0000000..bd0957b --- /dev/null +++ b/paymentwall/onetimetoken.py @@ -0,0 +1,15 @@ +from paymentwall.apiobject import ApiObject + +class OneTimeToken(ApiObject): + def __init__(self): + ApiObject.__init__(self, obj='token') + + def get_token(self): + return self.get_response()['token'] + + def is_active(self): + return self.get_response()['active'] + + def get_expiration_time(self): + return self.get_response()['expires_in'] + diff --git a/paymentwall/subscription.py b/paymentwall/subscription.py new file mode 100644 index 0000000..be43f93 --- /dev/null +++ b/paymentwall/subscription.py @@ -0,0 +1,29 @@ +from paymentwall.apiobject import ApiObject + +class Subscription(ApiObject): + def __init__(self, id=''): + ApiObject.__init__(self, id=id, obj='subscription') if id else ApiObject.__init__(self, obj='subscription') + + def get_id(self): + return self.id + + def get(self): + return self.do_api_action() + + def is_test(self): + return self.get_response()['test'] + + def is_trial(self): + return self.get_response()['is_trial'] + + def is_active(self): + return self.get_response()['active'] + + def is_expired(self): + return self.get_response()['expired'] + + def is_successful(self): + return self.object_response() + + def cancel(self): + return self.do_api_action('cancel') \ No newline at end of file