145 lines
4.8 KiB
Python
145 lines
4.8 KiB
Python
import logging
|
|
|
|
import requests
|
|
|
|
from azbankgateways.banks import BaseBank
|
|
from azbankgateways.exceptions import SettingDoesNotExist
|
|
from azbankgateways.exceptions.exceptions import (
|
|
BankGatewayConnectionError,
|
|
BankGatewayRejectPayment,
|
|
)
|
|
from azbankgateways.models import BankType, CurrencyEnum, PaymentStatus
|
|
from azbankgateways.utils import get_json
|
|
|
|
|
|
class Zarinpal(BaseBank):
|
|
_merchant_code = None
|
|
_sandbox = None
|
|
|
|
def __init__(self, **kwargs):
|
|
kwargs.setdefault("SANDBOX", 0)
|
|
super(Zarinpal, self).__init__(**kwargs)
|
|
self.set_gateway_currency(CurrencyEnum.IRT)
|
|
self._payment_type = 'payment'
|
|
if self._sandbox:
|
|
self._payment_type = 'sandbox'
|
|
self._payment_url = f"https://{self._payment_type}.zarinpal.com/pg/v4/payment/request.json"
|
|
self._startpay_url = f"https://{self._payment_type}.zarinpal.com/pg/StartPay/"
|
|
self._verify_url = f"https://{self._payment_type}.zarinpal.com/pg/v4/payment/verify.json"
|
|
|
|
def get_bank_type(self):
|
|
return BankType.ZARINPAL
|
|
|
|
def set_default_settings(self):
|
|
for item in ["MERCHANT_CODE", "SANDBOX"]:
|
|
if item not in self.default_setting_kwargs:
|
|
raise SettingDoesNotExist(f"{item} does not exist in default_setting_kwargs")
|
|
setattr(self, f"_{item.lower()}", self.default_setting_kwargs[item])
|
|
|
|
"""
|
|
gateway
|
|
"""
|
|
|
|
@classmethod
|
|
def get_minimum_amount(cls):
|
|
return 1000
|
|
|
|
def _get_gateway_payment_url_parameter(self):
|
|
return self._startpay_url + "{}".format(self.get_reference_number())
|
|
|
|
def _get_gateway_payment_parameter(self):
|
|
return {}
|
|
|
|
def _get_gateway_payment_method_parameter(self):
|
|
return "GET"
|
|
|
|
"""
|
|
pay
|
|
"""
|
|
|
|
def get_pay_data(self):
|
|
description = "خرید با شماره پیگیری - {}".format(self.get_tracking_code())
|
|
|
|
data = {
|
|
"description": description,
|
|
"merchant_id": self._merchant_code,
|
|
"amount": self.get_gateway_amount(),
|
|
"currency": self.get_gateway_currency(),
|
|
"metadata": {},
|
|
"callback_url": self._get_gateway_callback_url(),
|
|
}
|
|
mobile_number = self.get_mobile_number()
|
|
if mobile_number:
|
|
data["metadata"].update({"mobile": mobile_number})
|
|
data.update(self.get_custom_data())
|
|
return data
|
|
|
|
def prepare_pay(self):
|
|
super(Zarinpal, self).prepare_pay()
|
|
|
|
def pay(self):
|
|
super(Zarinpal, self).pay()
|
|
data = self.get_pay_data()
|
|
result = self._send_data(api=self._payment_url, data=data)
|
|
if result['data']:
|
|
token = result['data']['authority']
|
|
self._set_reference_number(token)
|
|
else:
|
|
logging.critical("Zarinpal gateway reject payment")
|
|
raise BankGatewayRejectPayment(self.get_transaction_status_text())
|
|
|
|
"""
|
|
verify from gateway
|
|
"""
|
|
|
|
def prepare_verify_from_gateway(self):
|
|
super(Zarinpal, self).prepare_verify_from_gateway()
|
|
token = self.get_request().GET.get("Authority")
|
|
self._set_reference_number(token)
|
|
self._set_bank_record()
|
|
|
|
def verify_from_gateway(self, request):
|
|
super(Zarinpal, self).verify_from_gateway(request)
|
|
|
|
"""
|
|
verify
|
|
"""
|
|
|
|
def get_verify_data(self):
|
|
super(Zarinpal, self).get_verify_data()
|
|
return {
|
|
"merchant_id": self._merchant_code,
|
|
"authority": self.get_reference_number(),
|
|
"amount": self.get_gateway_amount(),
|
|
}
|
|
|
|
def prepare_verify(self, tracking_code):
|
|
super(Zarinpal, self).prepare_verify(tracking_code)
|
|
|
|
def verify(self, transaction_code):
|
|
super(Zarinpal, self).verify(transaction_code)
|
|
data = self.get_verify_data()
|
|
result = self._send_data(api=self._verify_url, data=data)
|
|
if result['data'] and result['data']['code'] in [100, 101]:
|
|
self._set_payment_status(PaymentStatus.COMPLETE)
|
|
else:
|
|
self._set_payment_status(PaymentStatus.CANCEL_BY_USER)
|
|
logging.debug("Zarinpal gateway unapprove payment")
|
|
|
|
def _send_data(self, api, data):
|
|
try:
|
|
response = requests.post(api, json=data, timeout=self.get_timeout())
|
|
except requests.Timeout:
|
|
logging.exception("ZARINPAL time out gateway {}".format(data))
|
|
raise BankGatewayConnectionError()
|
|
except requests.ConnectionError:
|
|
logging.exception("ZARINPAL time out gateway {}".format(data))
|
|
raise BankGatewayConnectionError()
|
|
|
|
response_json = get_json(response)
|
|
if response_json['data']:
|
|
self._set_transaction_status_text(response_json['data']['message'])
|
|
else:
|
|
self._set_transaction_status_text(response_json['errors']['message'])
|
|
return response_json
|