Advertisement
MarkUa

Untitled

Apr 26th, 2020
753
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.87 KB | None | 0 0
  1. """
  2. LiqPay Python SDK
  3. ~~~~~~~~~~~~~~~~~
  4. supports python 3 version
  5. requires requests module
  6. """
  7.  
  8. __title__ = "LiqPay Python SDK"
  9. __version__ = "1.0"
  10.  
  11. import base64
  12. from copy import deepcopy
  13. import hashlib
  14. import json
  15. from urllib.parse import urljoin
  16.  
  17. import requests
  18.  
  19.  
  20. class ParamValidationError(Exception):
  21.     pass
  22.  
  23.  
  24. class LiqPay(object):
  25.     FORM_TEMPLATE = """\
  26.        <form method="post" action="{action}" accept-charset="utf-8">
  27.        \t{param_inputs}
  28.            <input type="image" src="//static.liqpay.ua/buttons/p1{language}.radius.png" name="btn_text" />
  29.        </form>"""
  30.     INPUT_TEMPLATE = "<input type='hidden' name='{name}' value='{value}'/>"
  31.  
  32.     SUPPORTED_PARAMS = [
  33.         "public_key", "amount", "currency", "description", "order_id",
  34.         "result_url", "server_url", "type", "signature", "language", "sandbox"
  35.     ]
  36.  
  37.     def __init__(self, public_key, private_key, host="https://www.liqpay.ua/api/"):
  38.         self._public_key = public_key
  39.         self._private_key = private_key
  40.         self._host = host
  41.  
  42.     def _make_signature(self, *args):
  43.         joined_fields = "".join(x for x in args)
  44.         joined_fields = joined_fields.encode("utf-8")
  45.         return base64.b64encode(hashlib.sha1(joined_fields).digest()).decode("ascii")
  46.  
  47.     def _prepare_params(self, params):
  48.         params = {} if params is None else deepcopy(params)
  49.         params.update(public_key=self._public_key)
  50.         return params
  51.  
  52.     def api(self, url, params=None):
  53.         params = self._prepare_params(params)
  54.  
  55.         json_encoded_params = json.dumps(params)
  56.         private_key = self._private_key
  57.         signature = self._make_signature(private_key, json_encoded_params, private_key)
  58.  
  59.         request_url = urljoin(self._host, url)
  60.         request_data = {"data": json_encoded_params, "signature": signature}
  61.         response = requests.post(request_url, data=request_data, verify=False)
  62.         return json.loads(response.content.decode("utf-8"))
  63.  
  64.     def cnb_form(self, params):
  65.         params = self._prepare_params(params)
  66.         params_validator = (
  67.             ("amount", lambda x: x is not None and float(x) > 0),
  68.             ("description", lambda x: x is not None)
  69.         )
  70.         for key, validator in params_validator:
  71.             if validator(params.get(key)):
  72.                 continue
  73.  
  74.             raise ParamValidationError("Invalid param: '{}'".format(key))
  75.  
  76.         # spike to set correct values for language, currency and sandbox params
  77.         language = params.get("language", "ru")
  78.         currency = params["currency"]
  79.         params.update(
  80.             language=language,
  81.             currency=currency if currency != "RUR" else "RUB",
  82.             sandbox=int(bool(params.get("sandbox")))
  83.         )
  84.  
  85.         encoded_data = self.data_to_sign(params)
  86.         params_templ = {"data": encoded_data}
  87.  
  88.         params_templ["signature"] = self._make_signature(self._private_key, params_templ["data"], self._private_key)
  89.         form_action_url = urljoin(self._host, "3/checkout/")
  90.         format_input = (lambda k, v: self.INPUT_TEMPLATE.format(name=k, value=v))
  91.         inputs = [format_input(k, v) for k, v in params_templ.items()]
  92.         return self.FORM_TEMPLATE.format(
  93.             action=form_action_url,
  94.             language=language,
  95.             param_inputs="\n\t".join(inputs)
  96.         )
  97.  
  98.     def cnb_signature(self, params):
  99.         params = self._prepare_params(params)
  100.  
  101.         data_to_sign = self.data_to_sign(params)
  102.         return self._make_signature(self._private_key, data_to_sign, self._private_key)
  103.  
  104.     def cnb_data(self, params):
  105.         params = self._prepare_params(params)
  106.         return self.data_to_sign(params)
  107.  
  108.     def str_to_sign(self, str):
  109.         return base64.b64encode(hashlib.sha1(str.encode("utf-8")).digest()).decode("ascii")
  110.  
  111.     def data_to_sign(self, params):
  112.         return base64.b64encode(json.dumps(params).encode("utf-8")).decode("ascii")
  113.  
  114.     def decode_data_from_str(self, data):
  115.         """Decoding data that were encoded by base64.b64encode(str)
  116.        Note:
  117.            Often case of using is decoding data from LiqPay Callback.
  118.            Dict contains all information about payment.
  119.            More info about callback params see in documentation
  120.            https://www.liqpay.ua/documentation/api/callback.
  121.        Args:
  122.            data: json string with api params and encoded by base64.b64encode(str).
  123.        Returns:
  124.            Dict
  125.        Example:
  126.            liqpay = LiqPay(settings.LIQPAY_PUBLIC_KEY, settings.LIQPAY_PRIVATE_KEY)
  127.            data = request.POST.get('data')
  128.            response = liqpay.decode_data_from_str(data)
  129.            print(response)
  130.            {'commission_credit': 0.0, 'order_id': 'order_id_1', 'liqpay_order_id': 'T8SRXWM71509085055293216', ...}
  131.        """
  132.         return json.loads(base64.b64decode(data).decode('utf-8'))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement