import base64 import hashlib import hmac import urllib.parse from datetime import datetime, timedelta import requests from DepoT.settings import env class EPay: payment_types = { "pay_credit_card": "credit_paydirect", "pay_epay": "paylogin", } @staticmethod def encode_message(message): encoded_data = base64.b64encode(message.encode("utf-8")).decode("utf-8") secret_key = env("EPAY_SECURITY_KEY") checksum = hmac.new( secret_key.encode("utf-8"), encoded_data.encode("utf-8"), hashlib.sha1 ).hexdigest() return encoded_data, checksum @classmethod def generate_urls(self, invoice, amount): client_id = env("EPAY_CLIENT_ID") description = f"Invoice number: {invoice} with amount of {amount}" currency = "BGN" expiry = ( datetime.today() + timedelta(days=int(env("INVOICE_EXPIRE_PERIOD"))) ).strftime("%d.%m.%Y") if amount == 0: amount = 1000 message = f"MIN={client_id}\nINVOICE={invoice}\nAMOUNT={amount}\nCURRENCY={currency}\nEXP_TIME={expiry}\nDESCR={description}" encoded_data, checksum = EPay.encode_message(message) result = {} for pay_type, keyword in EPay.payment_types.items(): url = f"https://demo.epay.bg/?PAGE={keyword}&ENCODED={urllib.parse.quote(encoded_data)}&CHECKSUM={urllib.parse.quote(checksum)}" result[pay_type] = url return result @staticmethod def payment_result(encoded_data, checksum_received): secret_key = env("EPAY_SECURITY_KEY") decoded_data = base64.b64decode(encoded_data).decode("utf-8") checksum_calculated = hmac.new( secret_key.encode("utf-8"), encoded_data.encode("utf-8"), hashlib.sha1 ).hexdigest() checksum_result = checksum_calculated == checksum_received fields = decoded_data.split(":") fields_dict = {} for field in fields: try: name, value = field.split("=") except ValueError: print(fields) print(field) fields_dict[name] = value return fields_dict, checksum_result @staticmethod def send_response(encoded_data, checksum): url = f"https://demo.epay.bg/?ENCODED={urllib.parse.quote(encoded_data)}&CHECKSUM={urllib.parse.quote(checksum)}" print(url) res = requests.post(url) @staticmethod def send_ok(invoice): message = f"INVOICE={invoice}:STATUS=OK" encoded_data, checksum = EPay.encode_message(message) print(f"OK {invoice}") EPay.send_response(encoded_data, checksum) @staticmethod def send_no(invoice): message = f"INVOICE={invoice}:STATUS=NO" encoded_data, checksum = EPay.encode_message(message) print(f"NO {invoice}") EPay.send_response(encoded_data, checksum) @staticmethod def send_err(invoice): message = f"INVOICE={invoice}:STATUS=ERR:ERR=BAD_CHECKSUM" encoded_data, checksum = EPay.encode_message(message) print(f"ERR {invoice}") EPay.send_response(encoded_data, checksum)