Skip to content

Commit

Permalink
Add Asan Pardakht gateway support (ali-zahedi#119)
Browse files Browse the repository at this point in the history
  • Loading branch information
miladkoohi committed Sep 14, 2024
1 parent 5913b37 commit fa381cb
Show file tree
Hide file tree
Showing 59 changed files with 205 additions and 0 deletions.
Empty file modified .editorconfig
100644 → 100755
Empty file.
Empty file modified .github/workflows/linters.yaml
100644 → 100755
Empty file.
Empty file modified .github/workflows/release.yaml
100644 → 100755
Empty file.
Empty file modified .gitignore
100644 → 100755
Empty file.
Empty file modified .pre-commit-config.yaml
100644 → 100755
Empty file.
Empty file modified .releaserc.yaml
100644 → 100755
Empty file.
Empty file modified .yamllint.yml
100644 → 100755
Empty file.
Empty file modified LICENSE
100644 → 100755
Empty file.
Empty file modified MANIFEST.in
100644 → 100755
Empty file.
7 changes: 7 additions & 0 deletions README.md
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@

1. [درگاه پی ورژن ۱](https://www.pay.ir/)

1. [درگاه آسان پرداخت ](https://asanpardakht.ir/)

[[_TOC_]]

<h1 dir="rtl">آموزشی</h1>
Expand Down Expand Up @@ -96,6 +98,11 @@
"MERCHANT_CODE": "<YOUR MERCHANT CODE>",
"X_SANDBOX": 0, # 0 disable, 1 active
},
"ASANPARDAKHT": { # اضافه کردن آسان پرداخت
"MERCHANT_CONFIGURATION_ID": "<YOUR MERCHANT CONFIGURATION ID>",
"USERNAME": "<YOUR USERNAME>",
"PASSWORD": "<YOUR PASSWORD>",
},
},
"IS_SAMPLE_FORM_ENABLE": True, # اختیاری و پیش فرض غیر فعال است
"DEFAULT": "BMI",
Expand Down
Empty file modified azbankgateways/__init__.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/admin.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/apps.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/bankfactories.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/banks/__init__.py
100644 → 100755
Empty file.
195 changes: 195 additions & 0 deletions azbankgateways/banks/asanpardakht.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
import logging
import requests
from azbankgateways.banks import BaseBank
from azbankgateways.exceptions import (
BankGatewayConnectionError,
BankGatewayRejectPayment,
SettingDoesNotExist,
)
from azbankgateways.models import BankType, CurrencyEnum, PaymentStatus
from azbankgateways.utils import get_json


class AsanPardakht(BaseBank):
_merchant_configuration_id = None
_username = None
_password = None

def __init__(self, **kwargs):
super(AsanPardakht, self).__init__(**kwargs)

self.set_gateway_currency(CurrencyEnum.IRR)
self._token_api_url = "https://ipgrest.asanpardakht.ir/v1/Token"
self._payment_url = "https://asan.shaparak.ir"
self._verify_api_url = "https://ipgrest.asanpardakht.ir/v1/Verify"

def get_bank_type(self):
return BankType.ASANPARDAKHT

def set_default_settings(self):
required_settings = ["MERCHANT_CONFIGURATION_ID", "USERNAME", "PASSWORD"]
for item in required_settings:
if item not in self.default_setting_kwargs:
raise SettingDoesNotExist(f"{item} is not set in settings.")
setattr(self, f"_{item.lower()}", self.default_setting_kwargs[item])

def get_pay_data(self):
data = {
"serviceTypeId": 1,
"merchantConfigurationId": self._merchant_configuration_id,
"localInvoiceId": self.get_tracking_code(),
"amountInRials": self.get_gateway_amount(),
"localDate": self._get_local_date(),
"callbackURL": self._get_gateway_callback_url(),
}
return data

def prepare_pay(self):
super(AsanPardakht, self).prepare_pay()

def pay(self):
super(AsanPardakht, self).pay()
data = self.get_pay_data()
headers = {
"Content-Type": "application/json",
"usr": self._username,
"pwd": self._password,
}
response_json = self._send_request(self._token_api_url, data, headers)

status = response_json.get("ResCode")

if status == "0": # تراکنش موفق
token = response_json.get("Token")
self._set_reference_number(token)
else:
status_text = self._get_status_text(status)
self._set_transaction_status_text(status_text)
logging.critical(status_text)
raise BankGatewayRejectPayment(self.get_transaction_status_text())

def _get_status_text(self, status):
status_codes = {
"0": "Transaction successful",
"1": "Issuer declined transaction",
"2": "Transaction already confirmed",
"3": "Invalid merchant",
"4": "Card captured",
"5": "Transaction not processed",
"6": "Error occurred",
"12": "Invalid transaction",
"13": "Incorrect correction amount",
"14": "Invalid card number",
"15": "Invalid issuer",
"16": "Transaction approved, update track 3",
"19": "Resend transaction",
"23": "Invalid commission amount",
"25": "Original transaction not found",
"30": "Message format error",
"31": "Merchant not supported by switch",
"33": "Card expiration date exceeded",
"34": "Transaction not successfully completed",
"36": "Card restricted",
"38": "Too many incorrect PIN entries",
"39": "Credit card account not found",
"40": "Requested operation not supported",
"41": "Lost card, capture card",
"43": "Stolen card, capture card",
"51": "Insufficient funds",
"54": "Card expiration date exceeded",
"55": "Invalid card PIN",
"57": "Transaction not allowed",
"61": "Transaction amount exceeds limit",
"63": "Security violation",
"65": "Too many transaction attempts",
"75": "Too many incorrect PIN attempts",
"77": "Invalid transaction date",
"78": "Card inactive",
"79": "Invalid linked account",
"80": "Transaction unsuccessful",
"84": "Card issuer not responding",
"86": "Transaction destination in off sign mode",
"90": "Card issuer performing end-of-day operations",
"92": "No routing to destination",
"94": "Duplicate transaction",
"96": "System error occurred",
"97": "Issuer or acquirer performing key change"
}
return status_codes.get(status, "Unknown error")

def _get_gateway_payment_url_parameter(self):
return self._payment_url

def _get_gateway_payment_method_parameter(self):
return "POST"

def _get_gateway_payment_parameter(self):
params = {
"RefId": self.get_reference_number(),
}
return params

def prepare_verify_from_gateway(self):
super(AsanPardakht, self).prepare_verify_from_gateway()
request = self.get_request()
ref_id = request.POST.get("RefId")
res_code = request.POST.get("ResCode")
self._set_reference_number(ref_id)
self._set_bank_record()
if res_code == "0":
self._bank.extra_information = f"ResCode={res_code}, RefId={ref_id}"
self._bank.save()
else:
logging.error(f"Payment failed with ResCode: {res_code}")
self._set_payment_status(PaymentStatus.CANCEL_BY_USER)

def verify_from_gateway(self, request):
super(AsanPardakht, self).verify_from_gateway(request)

def get_verify_data(self):
data = {
"merchantConfigurationId": self._merchant_configuration_id,
"payGateTranId": self.get_reference_number(),
}
return data

def prepare_verify(self, tracking_code):
super(AsanPardakht, self).prepare_verify(tracking_code)

def verify(self, transaction_code):
super(AsanPardakht, self).verify(transaction_code)
data = self.get_verify_data()
headers = {
"Content-Type": "application/json",
"usr": self._username,
"pwd": self._password,
}
response_json = self._send_request(self._verify_api_url, data, headers)
if response_json.get("IsSuccess"):
self._set_payment_status(PaymentStatus.COMPLETE)
else:
self._set_payment_status(PaymentStatus.CANCEL_BY_USER)
logging.error("Asan Pardakht verification failed.")

def _send_request(self, api_url, data, headers):
try:
response = requests.post(api_url, json=data, headers=headers, timeout=10)
response.raise_for_status()
except requests.Timeout:
logging.exception(f"Asan Pardakht gateway timeout: {data}")
raise BankGatewayConnectionError()
except requests.ConnectionError:
logging.exception(f"Asan Pardakht gateway connection error: {data}")
raise BankGatewayConnectionError()
except requests.HTTPError as e:
logging.exception(f"HTTP error occurred: {e}")
raise BankGatewayConnectionError()

response_json = get_json(response)
self._set_transaction_status_text(response_json.get("Message"))
return response_json

def _get_local_date(self):
from datetime import datetime

return datetime.now().strftime("%Y%m%d%H%M%S")
Empty file modified azbankgateways/banks/bahamta.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/banks/banks.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/banks/bmi.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/banks/idpay.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/banks/mellat.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/banks/payV1.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/banks/sep.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/banks/zarinpal.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/banks/zibal.py
100644 → 100755
Empty file.
2 changes: 2 additions & 0 deletions azbankgateways/default_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
"BAHAMTA": "azbankgateways.banks.Bahamta",
"MELLAT": "azbankgateways.banks.Mellat",
"PAYV1": "azbankgateways.banks.PayV1",
"ASANPARDAKHT": "azbankgateways.banks.AsanPardakht",
},
)

_AZ_IRANIAN_BANK_GATEWAYS = getattr(settings, "AZ_IRANIAN_BANK_GATEWAYS", {})
BANK_PRIORITIES = _AZ_IRANIAN_BANK_GATEWAYS.get("BANK_PRIORITIES", [])
BANK_GATEWAYS = _AZ_IRANIAN_BANK_GATEWAYS.get("GATEWAYS", {})
Expand Down
Empty file modified azbankgateways/exceptions/__init__.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/exceptions/exceptions.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/forms.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/locale/en/LC_MESSAGES/django.mo
100644 → 100755
Empty file.
Empty file modified azbankgateways/locale/en/LC_MESSAGES/django.po
100644 → 100755
Empty file.
Empty file modified azbankgateways/locale/fa/LC_MESSAGES/django.mo
100644 → 100755
Empty file.
Empty file modified azbankgateways/locale/fa/LC_MESSAGES/django.po
100644 → 100755
Empty file.
Empty file modified azbankgateways/migrations/0001_initial.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/migrations/0002_auto_20210102_0721.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/migrations/0003_bank_bank_choose_identifier.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/migrations/0004_auto_20211115_1500.py
100644 → 100755
Empty file.
Empty file.
Empty file modified azbankgateways/migrations/__init__.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/models/__init__.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/models/banks.py
100644 → 100755
Empty file.
1 change: 1 addition & 0 deletions azbankgateways/models/enum.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class BankType(models.TextChoices):
BAHAMTA = "BAHAMTA", _("Bahamta")
MELLAT = "MELLAT", _("Mellat")
PAYV1 = "PAYV1", _("PayV1")
ASANPARDAKHT = "ASANPARDAKHT", _("AsanPardakht")


class CurrencyEnum(models.TextChoices):
Expand Down
Empty file modified azbankgateways/readers/__init__.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/readers/bases.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/readers/defaults.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/templates/azbankgateways/redirect_to_bank.html
100644 → 100755
Empty file.
Empty file modified azbankgateways/templates/azbankgateways/samples/base.html
100644 → 100755
Empty file.
Empty file modified azbankgateways/templates/azbankgateways/samples/base_site.html
100644 → 100755
Empty file.
Empty file modified azbankgateways/templates/azbankgateways/samples/gateway.html
100644 → 100755
Empty file.
Empty file modified azbankgateways/templates/azbankgateways/samples/result.html
100644 → 100755
Empty file.
Empty file modified azbankgateways/types.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/urls.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/utils.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/views/__init__.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/views/banks.py
100644 → 100755
Empty file.
Empty file modified azbankgateways/views/samples.py
100644 → 100755
Empty file.
Empty file modified pyproject.toml
100644 → 100755
Empty file.
Empty file modified setup.cfg
100644 → 100755
Empty file.
Empty file modified tox.ini
100644 → 100755
Empty file.

0 comments on commit fa381cb

Please sign in to comment.