From 73eeffcae27d896ab1c37189957c5fac2c38f009 Mon Sep 17 00:00:00 2001
From: Hame hiani
Date: Fri, 23 Feb 2024 15:35:16 +0330
Subject: [PATCH 1/5] Fix: error occurs when the main language of site is
persian and it has to use gettext_lazy translation
---
azbankgateways/models/enum.py | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/azbankgateways/models/enum.py b/azbankgateways/models/enum.py
index aa713da..e705a6a 100644
--- a/azbankgateways/models/enum.py
+++ b/azbankgateways/models/enum.py
@@ -28,11 +28,11 @@ def toman_to_rial(cls, amount):
class PaymentStatus(settings.TEXT_CHOICES):
- WAITING = _("Waiting")
- REDIRECT_TO_BANK = _("Redirect to bank")
- RETURN_FROM_BANK = _("Return from bank")
- CANCEL_BY_USER = _("Cancel by user")
- EXPIRE_GATEWAY_TOKEN = _("Expire gateway token")
- EXPIRE_VERIFY_PAYMENT = _("Expire verify payment")
- COMPLETE = _("Complete")
- ERROR = _("Unknown error acquired")
+ WAITING = "WAITING", _("Waiting")
+ REDIRECT_TO_BANK = "REDIRECT_TO_BANK", _("Redirect to bank")
+ RETURN_FROM_BANK = "RETURN_FROM_BANK", _("Return from bank")
+ CANCEL_BY_USER = "CANCEL_BY_USER", _("Cancel by user")
+ EXPIRE_GATEWAY_TOKEN = "EXPIRE_GATEWAY_TOKEN", _("Expire gateway token")
+ EXPIRE_VERIFY_PAYMENT = "EXPIRE_VERIFY_PAYMENT", _("Expire verify payment")
+ COMPLETE = "COMPLETE", _("Complete")
+ ERROR = "ERROR", _("Unknown error acquired")
From 0835cd3ff7ebdd53399284c503e84acb60286a15 Mon Sep 17 00:00:00 2001
From: Ali Zahedigol
Date: Thu, 28 Mar 2024 15:51:53 +0200
Subject: [PATCH 2/5] fix: migration problem #70
---
.pre-commit-config.yaml | 1 -
...ank_type_alter_bank_created_at_and_more.py | 58 +++++++++++++++++++
2 files changed, 58 insertions(+), 1 deletion(-)
create mode 100644 azbankgateways/migrations/0005_alter_bank_bank_type_alter_bank_created_at_and_more.py
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 825b9bd..64fab04 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -20,7 +20,6 @@ repos:
rev: 23.7.0
hooks:
- id: black
- exclude: ^(.*/)?(migrations|load_geojson_data)/
args: ['--config=pyproject.toml']
- repo: https://github.com/adamchainz/blacken-docs
rev: 1.13.0
diff --git a/azbankgateways/migrations/0005_alter_bank_bank_type_alter_bank_created_at_and_more.py b/azbankgateways/migrations/0005_alter_bank_bank_type_alter_bank_created_at_and_more.py
new file mode 100644
index 0000000..1eb26ed
--- /dev/null
+++ b/azbankgateways/migrations/0005_alter_bank_bank_type_alter_bank_created_at_and_more.py
@@ -0,0 +1,58 @@
+# Generated by Django 5.0.3 on 2024-03-28 13:42
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ('azbankgateways', '0004_auto_20211115_1500'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='bank',
+ name='bank_type',
+ field=models.CharField(
+ choices=[
+ ('BMI', 'BMI'),
+ ('SEP', 'SEP'),
+ ('ZARINPAL', 'Zarinpal'),
+ ('IDPAY', 'IDPay'),
+ ('ZIBAL', 'Zibal'),
+ ('BAHAMTA', 'Bahamta'),
+ ('MELLAT', 'Mellat'),
+ ('PAYV1', 'PayV1'),
+ ],
+ max_length=50,
+ verbose_name='Bank',
+ ),
+ ),
+ migrations.AlterField(
+ model_name='bank',
+ name='created_at',
+ field=models.DateTimeField(auto_now_add=True, verbose_name='Created at'),
+ ),
+ migrations.AlterField(
+ model_name='bank',
+ name='status',
+ field=models.CharField(
+ choices=[
+ ('WAITING', 'Waiting'),
+ ('REDIRECT_TO_BANK', 'Redirect to bank'),
+ ('RETURN_FROM_BANK', 'Return from bank'),
+ ('CANCEL_BY_USER', 'Cancel by user'),
+ ('EXPIRE_GATEWAY_TOKEN', 'Expire gateway token'),
+ ('EXPIRE_VERIFY_PAYMENT', 'Expire verify payment'),
+ ('COMPLETE', 'Complete'),
+ ('ERROR', 'Unknown error acquired'),
+ ],
+ max_length=50,
+ verbose_name='Status',
+ ),
+ ),
+ migrations.AlterField(
+ model_name='bank',
+ name='update_at',
+ field=models.DateTimeField(auto_now=True, verbose_name='Updated at'),
+ ),
+ ]
From a4eebca3bbc808df2cc3a92a0c9b260443edcc6e Mon Sep 17 00:00:00 2001
From: Ali Zahedigol
Date: Thu, 28 Mar 2024 15:54:27 +0200
Subject: [PATCH 3/5] chore: thanks https://github.com/shiani #83
---
README.md | 278 +++++++++++++++++++++++++++++-------------------------
1 file changed, 150 insertions(+), 128 deletions(-)
diff --git a/README.md b/README.md
index 3e5bb19..91baf78 100644
--- a/README.md
+++ b/README.md
@@ -10,32 +10,32 @@
کدهای آزاد و متن باز به زبان پایتون (python) که برای ارتباط با درگاه های بانکهای ایرانی در جنگو (Django) توسعه داده شده است.
-
+
در حال حاضر درگاه های با درگاه های زیر می توانید پرداخت کنید.
-
+
1. [درگاه پرداخت بانک ملی ایران (BMI)](https://mmp.sadadpsp.ir/Browse/MerchantRequestForm?@TermType_Shaparakabbr=INT)
-
+
1. [درگاه پرداخت بانک سامان (SEP)](https://www.sep.ir/iemerchantregister)
-
+
1. [درگاه پرداخت زرین پال](https://next.zarinpal.com/auth/register)
-
+
1. [درگاه پرداخت آی دی پی (IDPay)](https://idpay.ir/s/664153)
-
+
1. [درگاه پرداخت زیبال](https://zibal.ir)
-
+
1. [درگاه پرداخت باهمتا](https://webpay.bahamta.com?rc=Sv7oH)
-
+
1. [درگاه به پرداخت](http://www.behpardakht.com/)
-
+
1. [درگاه پی ورژن ۱](https://www.pay.ir/)
-
+
[[_TOC_]]
آموزشی
-1. [یوتیوب](https://youtu.be/VnwY7DJlPKs)
+1. [یوتیوب](https://youtu.be/VnwY7DJlPKs)
1. [آپارات](https://www.aparat.com/v/DxL5J)
1. [آکادمی ژاک](https://academy.zhaak.com/course/236/python-tips)
@@ -49,82 +49,82 @@
تنظیمات
-
+
### settings.py
در فایل `settings.py` تنظیمات زیر را انجام میدهیم.
-
+
``` python
-INSTALLED_APPS = [
- # ....
- 'azbankgateways',
- # ...
-]
-AZ_IRANIAN_BANK_GATEWAYS = {
- 'GATEWAYS': {
- 'BMI': {
- 'MERCHANT_CODE': '',
- 'TERMINAL_CODE': '',
- 'SECRET_KEY': '',
- },
- 'SEP': {
- 'MERCHANT_CODE': '',
- 'TERMINAL_CODE': '',
- },
- 'ZARINPAL': {
- 'MERCHANT_CODE': '',
- 'SANDBOX': 0, # 0 disable, 1 active
- },
- 'IDPAY': {
- 'MERCHANT_CODE': '',
- 'METHOD': 'POST', # GET or POST
- 'X_SANDBOX': 0, # 0 disable, 1 active
- },
- 'ZIBAL': {
- 'MERCHANT_CODE': '',
- },
- 'BAHAMTA': {
- 'MERCHANT_CODE': '',
- },
- 'MELLAT': {
- 'TERMINAL_CODE': '',
- 'USERNAME': '',
- 'PASSWORD': '',
- },
- 'PAYV1': {
- 'MERCHANT_CODE': '',
- 'X_SANDBOX': 0, # 0 disable, 1 active
- },
- },
- 'IS_SAMPLE_FORM_ENABLE': True, # اختیاری و پیش فرض غیر فعال است
- 'DEFAULT': 'BMI',
- 'CURRENCY': 'IRR', # اختیاری
- 'TRACKING_CODE_QUERY_PARAM': 'tc', # اختیاری
- 'TRACKING_CODE_LENGTH': 16, # اختیاری
- 'SETTING_VALUE_READER_CLASS': 'azbankgateways.readers.DefaultReader', # اختیاری
- 'BANK_PRIORITIES': [
- 'BMI',
- 'SEP',
- # and so on ...
- ], # اختیاری
- 'IS_SAFE_GET_GATEWAY_PAYMENT': False, #اختیاری، بهتر است True بزارید.
- 'CUSTOM_APP': None, # اختیاری
-}
+ INSTALLED_APPS = [
+ # ....
+ "azbankgateways",
+ # ...
+ ]
+ AZ_IRANIAN_BANK_GATEWAYS = {
+ "GATEWAYS": {
+ "BMI": {
+ "MERCHANT_CODE": "",
+ "TERMINAL_CODE": "",
+ "SECRET_KEY": "",
+ },
+ "SEP": {
+ "MERCHANT_CODE": "",
+ "TERMINAL_CODE": "",
+ },
+ "ZARINPAL": {
+ "MERCHANT_CODE": "",
+ "SANDBOX": 0, # 0 disable, 1 active
+ },
+ "IDPAY": {
+ "MERCHANT_CODE": "",
+ "METHOD": "POST", # GET or POST
+ "X_SANDBOX": 0, # 0 disable, 1 active
+ },
+ "ZIBAL": {
+ "MERCHANT_CODE": "",
+ },
+ "BAHAMTA": {
+ "MERCHANT_CODE": "",
+ },
+ "MELLAT": {
+ "TERMINAL_CODE": "",
+ "USERNAME": "",
+ "PASSWORD": "",
+ },
+ "PAYV1": {
+ "MERCHANT_CODE": "",
+ "X_SANDBOX": 0, # 0 disable, 1 active
+ },
+ },
+ "IS_SAMPLE_FORM_ENABLE": True, # اختیاری و پیش فرض غیر فعال است
+ "DEFAULT": "BMI",
+ "CURRENCY": "IRR", # اختیاری
+ "TRACKING_CODE_QUERY_PARAM": "tc", # اختیاری
+ "TRACKING_CODE_LENGTH": 16, # اختیاری
+ "SETTING_VALUE_READER_CLASS": "azbankgateways.readers.DefaultReader", # اختیاری
+ "BANK_PRIORITIES": [
+ "BMI",
+ "SEP",
+ # and so on ...
+ ], # اختیاری
+ "IS_SAFE_GET_GATEWAY_PAYMENT": False, # اختیاری، بهتر است True بزارید.
+ "CUSTOM_APP": None, # اختیاری
+ }
```
1. `GATEWAYS` : تنظیمات مربوط به هر بانک به صورت دیکشنری های جدا در این قسمت وجود دارد. تنظیماتی مانند کلاس اجرا کننده، کلیدهای امنیتی که توسط بانک در اختیار شما قرار می گیرد.
-1. `DEFAULT`: در زمانی که به سازنده فکتوری پارامتری ارسال نشود از این تنظیم به عنوان بانک پیش فرض استفاده خواهد شد و ارتباطات با این بانک برقرار می شود.
+1. `DEFAULT`: در زمانی که به سازنده فکتوری پارامتری ارسال نشود از این تنظیم به عنوان بانک پیش فرض استفاده خواهد شد و ارتباطات با این بانک برقرار می شود.
+
+1. `CURRENCY - (IRR, IRT)`: واحد پولی که نرم افزار با آن کار می کند. این واحد پولی فارغ از واحد پولی درگاه خواهد بود. در صورتی که واحد پولی نرم افزار با واحد پولی درگاه بانک متفاوت باشد تبدیل ریال به تومان یا بالعکس انجام خواهد شد.
-1. `CURRENCY - (IRR, IRT)`: واحد پولی که نرم افزار با آن کار می کند. این واحد پولی فارغ از واحد پولی درگاه خواهد بود. در صورتی که واحد پولی نرم افزار با واحد پولی درگاه بانک متفاوت باشد تبدیل ریال به تومان یا بالعکس انجام خواهد شد.
+1. `TRACKING_CODE_QUERY_PARAM `: پارامتری که در هنگام بازگشت از درگاه به کال بک یو آر ال تعیین شده تنظیم و ارسال می گردد. به عنوان مثال زمانی که از کاربر از درگاه بانک باز می گردد چه پرداخت موفق داشته باشد و چه نا موفق کاربر به لینکی که در هنگام استفاده از درگاه تنظیم شده است٬ ارجاع داده می شود و در انتهای آن این رشته + کد پیگیری بازگردانده می شود تا بتوان داده ها را از این طریق بازیابی کرد.
-1. `TRACKING_CODE_QUERY_PARAM `: پارامتری که در هنگام بازگشت از درگاه به کال بک یو آر ال تعیین شده تنظیم و ارسال می گردد. به عنوان مثال زمانی که از کاربر از درگاه بانک باز می گردد چه پرداخت موفق داشته باشد و چه نا موفق کاربر به لینکی که در هنگام استفاده از درگاه تنظیم شده است٬ ارجاع داده می شود و در انتهای آن این رشته + کد پیگیری بازگردانده می شود تا بتوان داده ها را از این طریق بازیابی کرد.
-
-1. `TRACKING_CODE_LENGTH`: طول کد پیگیری تولید شده توسط سیستم است. دقت شود که در برخی درگاه ها مانند درگاه بانک ملی ایران، طول ۲۰ کاراکتر خطای `شماره سفارش ارسال نشده است` را می دهد.
+1. `TRACKING_CODE_LENGTH`: طول کد پیگیری تولید شده توسط سیستم است. دقت شود که در برخی درگاه ها مانند درگاه بانک ملی ایران، طول ۲۰ کاراکتر خطای `شماره سفارش ارسال نشده است` را می دهد.
1. `SETTING_VALUE_READER_CLASS`: با مقدار دهی به این تنظیم شما می توانید حالت یک متغیر خوان اضافه کنید که قابلیت های دیگری مثل پروایدر و پشتیبانی از یک بانک با چند اکانت و ... را به آن اضافه کنید.
-
+
1. `BANK_PRIORITIES`: این آرایه اختیاری است. زمانی که وضعیت اتصال به درگاه به صورت خودکار تعیین شده باشد، ابتدا به بانک پیش فرض متصل می شود و سپس بر این اساس شروع به اتصال خواهد کرد، تا به اولین درگاه فعال برسد. در حالت پیش فرض این آرایه خالی است که بعد از اتصال به درگاه مورد نظر در صورت خطا بقیه درگاه ها امتحان نخواهند شد.
1. `IS_SAMPLE_FORM_ENABLE`: یو آر ال های مربوط به تست درگاه بانک را فعال و یا غیر فعال می کند. در صورت فعال بودن می توانید از طریق آدرس زیر درگاه پرداخت را امتحان کنید.
@@ -154,7 +154,7 @@ AZ_IRANIAN_BANK_GATEWAYS = {
CUSTOM_APP : 'api:payment',
```
- اگر نیاز ندارید توابع داخلی را اوررایت کنیدو فقط به این نیاز دارید که مسیر یو ار ال های داخلی را در اپ جداگانه ای قرارگیرد میتوانید از این گزینه برای ادرسی دهی محل قرار گیری اپ استفاده کنید
+ اگر نیاز ندارید توابع داخلی را اوررایت کنیدو فقط به این نیاز دارید که مسیر یو ار ال های داخلی را در اپ جداگانه ای قرارگیرد میتوانید از این گزینه برای ادرسی دهی محل قرار گیری اپ استفاده کنید
### urls.py
@@ -171,8 +171,8 @@ from azbankgateways.urls import az_bank_gateways_urls
admin.autodiscover()
urlpatterns = [
- path('admin/', admin.site.urls),
- path('bankgateways/', az_bank_gateways_urls()),
+ path("admin/", admin.site.urls),
+ path("bankgateways/", az_bank_gateways_urls()),
]
```
@@ -199,11 +199,15 @@ python manage.py migrate
برای استفاده و اتصال به درگاه بانک کافی است یک `BankFactory` ایجاد کنیم و پارامترهای اجباری را تنظیم کنیم. سپس کاربر را می توانیم به درگاه بانک هدایت کنیم.
-
+
```python
import logging
from django.urls import reverse
-from azbankgateways import bankfactories, models as bank_models, default_settings as settings
+from azbankgateways import (
+ bankfactories,
+ models as bank_models,
+ default_settings as settings,
+)
from azbankgateways.exceptions import AZBankGatewaysException
@@ -211,41 +215,46 @@ def go_to_gateway_view(request):
# خواندن مبلغ از هر جایی که مد نظر است
amount = 1000
# تنظیم شماره موبایل کاربر از هر جایی که مد نظر است
- user_mobile_number = '+989112221234' # اختیاری
+ user_mobile_number = "+989112221234" # اختیاری
factory = bankfactories.BankFactory()
try:
- bank = factory.auto_create() # or factory.create(bank_models.BankType.BMI) or set identifier
+ bank = (
+ factory.auto_create()
+ ) # or factory.create(bank_models.BankType.BMI) or set identifier
bank.set_request(request)
bank.set_amount(amount)
# یو آر ال بازگشت به نرم افزار برای ادامه فرآیند
- bank.set_client_callback_url(reverse('callback-gateway'))
+ bank.set_client_callback_url(reverse("callback-gateway"))
bank.set_mobile_number(user_mobile_number) # اختیاری
-
+
# در صورت تمایل اتصال این رکورد به رکورد فاکتور یا هر چیزی که بعدا بتوانید ارتباط بین محصول یا خدمات را با این
- # پرداخت برقرار کنید.
+ # پرداخت برقرار کنید.
bank_record = bank.ready()
-
+
# هدایت کاربر به درگاه بانک
return bank.redirect_gateway()
except AZBankGatewaysException as e:
logging.critical(e)
# TODO: redirect to failed page.
raise e
-
```
برای وقتی که تنظیمات IS_SAFE_GET_GATEWAY_PAYMENT': True'
- در این قسمت مثل مثال قبل عمل میکنیم تنها تفاوت این است که از تابع get_gateway بجای redirect_gateway استفاده میکنیم دلیل این کار افزایش امنیت و تغییر صفحهredirect میباشد.
+ در این قسمت مثل مثال قبل عمل میکنیم تنها تفاوت این است که از تابع get_gateway بجای redirect_gateway استفاده میکنیم دلیل این کار افزایش امنیت و تغییر صفحهredirect میباشد.
-
+
```python
import logging
from django.urls import reverse
from django.shortcuts import render
-from azbankgateways import bankfactories, models as bank_models, default_settings as settings
+from azbankgateways import (
+ bankfactories,
+ models as bank_models,
+ default_settings as settings,
+)
from azbankgateways.exceptions import AZBankGatewaysException
@@ -253,31 +262,32 @@ def go_to_gateway_view(request):
# خواندن مبلغ از هر جایی که مد نظر است
amount = 1000
# تنظیم شماره موبایل کاربر از هر جایی که مد نظر است
- user_mobile_number = '+989112221234' # اختیاری
+ user_mobile_number = "+989112221234" # اختیاری
factory = bankfactories.BankFactory()
try:
- bank = factory.auto_create() # or factory.create(bank_models.BankType.BMI) or set identifier
+ bank = (
+ factory.auto_create()
+ ) # or factory.create(bank_models.BankType.BMI) or set identifier
bank.set_request(request)
bank.set_amount(amount)
# یو آر ال بازگشت به نرم افزار برای ادامه فرآیند
- bank.set_client_callback_url(reverse('callback-gateway'))
+ bank.set_client_callback_url(reverse("callback-gateway"))
bank.set_mobile_number(user_mobile_number) # اختیاری
-
+
# در صورت تمایل اتصال این رکورد به رکورد فاکتور یا هر چیزی که بعدا بتوانید ارتباط بین محصول یا خدمات را با این
- # پرداخت برقرار کنید.
+ # پرداخت برقرار کنید.
bank_record = bank.ready()
-
+
# هدایت کاربر به درگاه بانک
context = bank.get_gateway()
- return render(request, 'redirect_to_bank.html', context=context)
+ return render(request, "redirect_to_bank.html", context=context)
except AZBankGatewaysException as e:
logging.critical(e)
- return render(request, 'redirect_to_bank.html')
-
+ return render(request, "redirect_to_bank.html")
```
-
+
در صورتیکه تمایل دارید به صورت خودکار به اولین درگاه در دسترس متصل شوید. ابتدا از قسمت تنظیمات در بخش `BANK_PRIORITIES
` اولویت های بانک های مد نظر را وارید کنید. سپس به جای استفاده از متد `factory.create` از متد `factory.auto_create` در این بخش استفاده کنید.
به متد auto_create می توانید مبلغ مد نظر را نیز برای صحت سنجی از حداقل مبلغ نیز ارسال کنید.
@@ -286,8 +296,8 @@ def go_to_gateway_view(request):
`set_mobile_number` متدی است که پارامتر شماره موبایل کاربری که قصد خرید دارد را به آن پاس میدهیم. این شماره موبایل جهت پرداخت و پیگیری آسان تر به درگاه ارسال می شود
ساخت صفحه redirect_to_bank.html
-
-این صفحه درصورتی کارمیکند که IS_SAFE_GET_GATEWAY_PAYMENT': True' و view مربوطه تنظیم شود.
برای این کار در پوشه templates پروژه فایل redirect_to_bank.html را ایجاد کرده و محتوای زیر را در آن قرار میدیم (میتونید با سلیقه خودتون سفاریشی کنید)
+
+این صفحه درصورتی کارمیکند که IS_SAFE_GET_GATEWAY_PAYMENT': True' و view مربوطه تنظیم شود.
برای این کار در پوشه templates پروژه فایل redirect_to_bank.html را ایجاد کرده و محتوای زیر را در آن قرار میدیم (میتونید با سلیقه خودتون سفاریشی کنید)
```html
@@ -304,7 +314,7 @@ def go_to_gateway_view(request):
{% else %}
خطا در ارتباط با درگاه
{% endif %}
-
+
{% if url %}
-
+
@@ -331,21 +341,21 @@ def go_to_gateway_view(request):
بازگشت از بانک
-
+
وضعیت رکورد بانک به شرح ذیل می باشد.
1. `WAITING`: در انتظار برای انتقال کاربر به درگاه بانک
1. `REDIRECT_TO_BANK`: کاربر به درگاه بانک منتقل شده است ولی هنوز از درگاه باز نگشته است.
-
-1. `RETURN_FROM_BANK`: کاربر از درگاه برگشته ولی عملیات صحت سنجی٬ یا تکمیل نشده است یا با خطا درهنگام تایید از سوی بانک مواجه شده است. در این شرایط می توان با فراخوانی مجدد در بازه زمانی کمتر از ۱۵ دقیقه که کاربر بازگشته است٬ عملیات تایید را مجدد درخواست کرد. شرح تایید مجدد در پایین تر آورده شده است.
-
-1. `CANCEL_BY_USER`: پرداخت توسط کاربر کنسل شده است.
-1. `EXPIRE_GATEWAY_TOKEN`: ارتباط با درگاه بانک برقرار شده ولی کاربر به درگاه هدایت نشده است.
+1. `RETURN_FROM_BANK`: کاربر از درگاه برگشته ولی عملیات صحت سنجی٬ یا تکمیل نشده است یا با خطا درهنگام تایید از سوی بانک مواجه شده است. در این شرایط می توان با فراخوانی مجدد در بازه زمانی کمتر از ۱۵ دقیقه که کاربر بازگشته است٬ عملیات تایید را مجدد درخواست کرد. شرح تایید مجدد در پایین تر آورده شده است.
+
+1. `CANCEL_BY_USER`: پرداخت توسط کاربر کنسل شده است.
-1. `EXPIRE_VERIFY_PAYMENT`: در بازه زمانی ۱۵ دقیقه پس از بازگشت٬ موفق به تایید اطلاعات پرداخت نشده ایم.
+1. `EXPIRE_GATEWAY_TOKEN`: ارتباط با درگاه بانک برقرار شده ولی کاربر به درگاه هدایت نشده است.
+
+1. `EXPIRE_VERIFY_PAYMENT`: در بازه زمانی ۱۵ دقیقه پس از بازگشت٬ موفق به تایید اطلاعات پرداخت نشده ایم.
1. `COMPLETE`: وضعیت پرداخت موفق است.
@@ -356,7 +366,11 @@ import logging
from django.http import HttpResponse, Http404
from django.urls import reverse
-from azbankgateways import bankfactories, models as bank_models, default_settings as settings
+from azbankgateways import (
+ bankfactories,
+ models as bank_models,
+ default_settings as settings,
+)
def callback_gateway_view(request):
@@ -378,7 +392,9 @@ def callback_gateway_view(request):
return HttpResponse("پرداخت با موفقیت انجام شد.")
# پرداخت موفق نبوده است. اگر پول کم شده است ظرف مدت ۴۸ ساعت پول به حساب شما بازخواهد گشت.
- return HttpResponse("پرداخت با شکست مواجه شده است. اگر پول کم شده است ظرف مدت ۴۸ ساعت پول به حساب شما بازخواهد گشت.")
+ return HttpResponse(
+ "پرداخت با شکست مواجه شده است. اگر پول کم شده است ظرف مدت ۴۸ ساعت پول به حساب شما بازخواهد گشت."
+ )
```
@@ -386,7 +402,11 @@ def callback_gateway_view(request):
```python
import logging
-from azbankgateways import bankfactories, models as bank_models, default_settings as settings
+from azbankgateways import (
+ bankfactories,
+ models as bank_models,
+ default_settings as settings,
+)
factory = bankfactories.BankFactory()
@@ -395,12 +415,13 @@ bank_models.Bank.objects.update_expire_records()
# مشخص کردن رکوردهایی که باید تعیین وضعیت شوند
for item in bank_models.Bank.objects.filter_return_from_bank():
- bank = factory.create(bank_type=item.bank_type, identifier=item.bank_choose_identifier)
- bank.verify(item.tracking_code)
- bank_record = bank_models.Bank.objects.get(tracking_code=item.tracking_code)
- if bank_record.is_success:
- logging.debug("This record is verify now.", extra={'pk': bank_record.pk})
-
+ bank = factory.create(
+ bank_type=item.bank_type, identifier=item.bank_choose_identifier
+ )
+ bank.verify(item.tracking_code)
+ bank_record = bank_models.Bank.objects.get(tracking_code=item.tracking_code)
+ if bank_record.is_success:
+ logging.debug("This record is verify now.", extra={"pk": bank_record.pk})
```
## TODO
@@ -413,7 +434,7 @@ for item in bank_models.Bank.objects.filter_return_from_bank():
- [X] Add Bahamta support
- [X] Add BehPardakht support
- [X] Add Pay.ir V1 support
-- [ ] Add Pay.ir V2 support
+- [ ] Add Pay.ir V2 support
- [ ] Add nextpay-ir support (need MERCHANT_CODE & etc.)
- [ ] Add Paystar support (need MERCHANT_CODE & etc.)
- [ ] Add Sepah Bank support (need MERCHANT_CODE & etc.)
@@ -427,11 +448,11 @@ for item in bank_models.Bank.objects.filter_return_from_bank():
## توسعه
- اگر از این بسته استفاده می کنید و خوشتون اومده با دادن ستاره به ما دلگرمی بدید.البته که اگر زمان بگذارید و گسترش بدید خیلی استقبال می کنیم و خوشحال میشیم. البته که در هیچ کدوم از این موارد اصراری نیست.
+ اگر از این بسته استفاده می کنید و خوشتون اومده با دادن ستاره به ما دلگرمی بدید.البته که اگر زمان بگذارید و گسترش بدید خیلی استقبال می کنیم و خوشحال میشیم. البته که در هیچ کدوم از این موارد اصراری نیست.
-برای نصب وابستگی ها از طریق زیر اقدام کنید و بعد از انجام تغییرات مرج ریکوئست ارسال کنید.
+برای نصب وابستگی ها از طریق زیر اقدام کنید و بعد از انجام تغییرات مرج ریکوئست ارسال کنید.
```shell
@@ -442,7 +463,7 @@ pre-commit install
بیشتر بخوانیم:
-* [flake8](https://flake8.pycqa.org/en/latest/)
+* [flake8](https://flake8.pycqa.org/en/latest/)
* [black](https://black.readthedocs.io/en/stable/)
@@ -450,8 +471,8 @@ pre-commit install
-# با تشکر از
-* [erfanmosaddeghi ](https://github.com/erfanmosaddeghi) برای اصلاح حداقل مبلغ زرین پال
+# با تشکر از
+* [erfanmosaddeghi ](https://github.com/erfanmosaddeghi) برای اصلاح حداقل مبلغ زرین پال
* [sina-am](https://github.com/sina-am) اضافه کردن درگاه بانک ملت
* [joejoe-am](https://github.com/joejoe-am) برای رفع مشکل اولویت بندی در اتصال خودکار
* [mash5026](https://github.com/mash5026) برای رفع مشکل unmarshalling ERROR: For input string
@@ -463,7 +484,8 @@ pre-commit install
* [Saman-Zand-H](https://github.com/Saman-Zand-H) رفع مشکل اتصال pay.ir در برخی موارد
* [MrMRM1](https://github.com/MrMRM1) [بابت رفع مشکل امنیتی](https://github.com/ali-zahedi/az-iranian-bank-gateways/pull/65#issuecomment-1624927632)
* [MrMRM1](https://github.com/MrMRM1) اضافه شدن قابلیت اوررایت یا تغییر ادرس یو آر ال های پیشفرض
-
+* [shiani](https://github.com/shiani) error occurs when the main language of site is Persian and it has to use gettext_lazy translation.
+
## License
The MIT License (MIT). Please see [License File](LICENSE) for more information.
From 17f86c274923a67a33fa383b6319cf1076b3572b Mon Sep 17 00:00:00 2001
From: Ali Zahedigol
Date: Thu, 28 Mar 2024 15:55:09 +0200
Subject: [PATCH 4/5] chore: remove gitlab ci and adjust django dependency
version
---
.gitlab-ci.yml | 51 --------------------------------------------------
setup.cfg | 2 +-
2 files changed, 1 insertion(+), 52 deletions(-)
delete mode 100644 .gitlab-ci.yml
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
deleted file mode 100644
index acde010..0000000
--- a/.gitlab-ci.yml
+++ /dev/null
@@ -1,51 +0,0 @@
-stages:
- - version
- - release
-
-variables:
- AUTHOR: 'Ali Zahedigol'
-
-.node: &node
- image: node:latest
- tags:
- - node
-
-.python: &python
- image: python:3.7
- tags:
- - python
-
-
-version:
- # Requires Node >= 10.13 version
- <<: *node
- stage: version
- only:
- refs:
- - master
- - develop
- script:
- - npm install @semantic-release/gitlab @semantic-release/exec @semantic-release/changelog
- - npx semantic-release --generate-notes false --dry-run
- - npx semantic-release
- artifacts:
- paths:
- - VERSION.txt
-
-release:
- <<: *python
- stage: release
- environment:
- name: release
- script:
- - echo "Version is $(cat VERSION.txt)"
- - sed -i "s/__version__ = \"1.0.0\"/__version__ = \"$(cat VERSION.txt)\"/g" azbankgateways/__init__.py
- - pip install build twine
- - python -m build
- - TWINE_PASSWORD=${TWINE_TOKEN} TWINE_USERNAME=${TWINE_USERNAME} python -m twine upload dist/*
- only:
- - master
- - develop
- dependencies:
- - version
-
diff --git a/setup.cfg b/setup.cfg
index a76e5b4..2aaf925 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -30,7 +30,7 @@ include_package_data = true
zip_safe = false
install_requires =
six
- Django >= 3.2, < 6
+ Django >= 3.0
pycryptodome >= 3.9.7
zeep
From b614fde587b93e09cde93c65cc5504a02bd33b99 Mon Sep 17 00:00:00 2001
From: Ali Zahedigol
Date: Thu, 28 Mar 2024 16:01:43 +0200
Subject: [PATCH 5/5] fix: remove deprecated enum
---
azbankgateways/default_settings.py | 18 +++----
azbankgateways/models/enum.py | 9 ++--
azbankgateways/models/enum_django.py | 77 ----------------------------
3 files changed, 10 insertions(+), 94 deletions(-)
delete mode 100644 azbankgateways/models/enum_django.py
diff --git a/azbankgateways/default_settings.py b/azbankgateways/default_settings.py
index 72d5401..f0436dd 100755
--- a/azbankgateways/default_settings.py
+++ b/azbankgateways/default_settings.py
@@ -1,18 +1,10 @@
"""Default settings for messaging."""
-import django
from django.conf import settings
from azbankgateways.apps import AZIranianBankGatewaysConfig
-if django.__version__ >= "3.0":
- from django.db import models
- TEXT_CHOICES = models.TextChoices
-else:
- from .models.enum_django import TextChoices
-
- TEXT_CHOICES = TextChoices
BANK_CLASS = getattr(
settings,
"CLASS",
@@ -24,7 +16,7 @@
"ZIBAL": "azbankgateways.banks.Zibal",
"BAHAMTA": "azbankgateways.banks.Bahamta",
"MELLAT": "azbankgateways.banks.Mellat",
- "PAYV1": "azbankgateways.banks.PayV1",
+ "PAYV1": "azbankgateways.banks.PayV1",
},
)
_AZ_IRANIAN_BANK_GATEWAYS = getattr(settings, "AZ_IRANIAN_BANK_GATEWAYS", {})
@@ -39,16 +31,18 @@
TRACKING_CODE_LENGTH = _AZ_IRANIAN_BANK_GATEWAYS.get("TRACKING_CODE_LENGTH", 16)
IS_SAMPLE_FORM_ENABLE = _AZ_IRANIAN_BANK_GATEWAYS.get("IS_SAMPLE_FORM_ENABLE", False)
IS_SAFE_GET_GATEWAY_PAYMENT = _AZ_IRANIAN_BANK_GATEWAYS.get("IS_SAFE_GET_GATEWAY_PAYMENT", False)
-CUSTOM_APP = _AZ_IRANIAN_BANK_GATEWAYS.get("CUSTOM_APP", None)
+CUSTOM_APP = _AZ_IRANIAN_BANK_GATEWAYS.get("CUSTOM_APP")
if CUSTOM_APP:
CALLBACK_NAMESPACE = f"{CUSTOM_APP}:{AZIranianBankGatewaysConfig.name}:callback"
GO_TO_BANK_GATEWAY_NAMESPACE = f"{CUSTOM_APP}:{AZIranianBankGatewaysConfig.name}:go-to-bank-gateway"
SAMPLE_RESULT_NAMESPACE = f"{CUSTOM_APP}:{AZIranianBankGatewaysConfig.name}:sample-result"
else:
- CALLBACK_NAMESPACE = _AZ_IRANIAN_BANK_GATEWAYS.get("CALLBACK_NAMESPACE", f"{AZIranianBankGatewaysConfig.name}:callback")
+ CALLBACK_NAMESPACE = _AZ_IRANIAN_BANK_GATEWAYS.get(
+ "CALLBACK_NAMESPACE", f"{AZIranianBankGatewaysConfig.name}:callback"
+ )
GO_TO_BANK_GATEWAY_NAMESPACE = _AZ_IRANIAN_BANK_GATEWAYS.get(
"GO_TO_BANK_GATEWAY_NAMESPACE", f"{AZIranianBankGatewaysConfig.name}:go-to-bank-gateway"
)
SAMPLE_RESULT_NAMESPACE = _AZ_IRANIAN_BANK_GATEWAYS.get(
"SAMPLE_RESULT_NAMESPACE", f"{AZIranianBankGatewaysConfig.name}:sample-result"
- )
\ No newline at end of file
+ )
diff --git a/azbankgateways/models/enum.py b/azbankgateways/models/enum.py
index e705a6a..ce0f1e5 100644
--- a/azbankgateways/models/enum.py
+++ b/azbankgateways/models/enum.py
@@ -1,9 +1,8 @@
+from django.db import models
from django.utils.translation import gettext_lazy as _
-import azbankgateways.default_settings as settings
-
-class BankType(settings.TEXT_CHOICES):
+class BankType(models.TextChoices):
BMI = "BMI", _("BMI")
SEP = "SEP", _("SEP")
ZARINPAL = "ZARINPAL", _("Zarinpal")
@@ -14,7 +13,7 @@ class BankType(settings.TEXT_CHOICES):
PAYV1 = "PAYV1", _("PayV1")
-class CurrencyEnum(settings.TEXT_CHOICES):
+class CurrencyEnum(models.TextChoices):
IRR = "IRR", _("Rial")
IRT = "IRT", _("Toman")
@@ -27,7 +26,7 @@ def toman_to_rial(cls, amount):
return amount * 10
-class PaymentStatus(settings.TEXT_CHOICES):
+class PaymentStatus(models.TextChoices):
WAITING = "WAITING", _("Waiting")
REDIRECT_TO_BANK = "REDIRECT_TO_BANK", _("Redirect to bank")
RETURN_FROM_BANK = "RETURN_FROM_BANK", _("Return from bank")
diff --git a/azbankgateways/models/enum_django.py b/azbankgateways/models/enum_django.py
deleted file mode 100644
index e18f1ab..0000000
--- a/azbankgateways/models/enum_django.py
+++ /dev/null
@@ -1,77 +0,0 @@
-import enum
-
-from django.utils.functional import Promise
-
-
-class ChoicesMeta(enum.EnumMeta):
- """A metaclass for creating a enum choices."""
-
- def __new__(metacls, classname, bases, classdict):
- labels = []
- for key in classdict._member_names:
- value = classdict[key]
- if isinstance(value, (list, tuple)) and len(value) > 1 and isinstance(value[-1], (Promise, str)):
- *value, label = value
- value = tuple(value)
- else:
- label = key.replace("_", " ").title()
- labels.append(label)
- # Use dict.__setitem__() to suppress defenses against double
- # assignment in enum's classdict.
- dict.__setitem__(classdict, key, value)
- cls = super().__new__(metacls, classname, bases, classdict)
- cls._value2label_map_ = dict(zip(cls._value2member_map_, labels))
- # Add a label property to instances of enum which uses the enum member
- # that is passed in as "self" as the value to use when looking up the
- # label in the choices.
- cls.label = property(lambda self: cls._value2label_map_.get(self.value))
- cls.do_not_call_in_templates = True
- return enum.unique(cls)
-
- def __contains__(cls, member):
- if not isinstance(member, enum.Enum):
- # Allow non-enums to match against member values.
- return any(x.value == member for x in cls)
- return super().__contains__(member)
-
- @property
- def names(cls):
- empty = ["__empty__"] if hasattr(cls, "__empty__") else []
- return empty + [member.name for member in cls]
-
- @property
- def choices(cls):
- empty = [(None, cls.__empty__)] if hasattr(cls, "__empty__") else []
- return empty + [(member.value, member.label) for member in cls]
-
- @property
- def labels(cls):
- return [label for _, label in cls.choices]
-
- @property
- def values(cls):
- return [value for value, _ in cls.choices]
-
-
-class Choices(enum.Enum, metaclass=ChoicesMeta):
- """Class for creating enumerated choices."""
-
- def __str__(self):
- """
- Use value when cast to str, so that Choices set as model instance
- attributes are rendered as expected in templates and similar contexts.
- """
- return str(self.value)
-
-
-class IntegerChoices(int, Choices):
- """Class for creating enumerated integer choices."""
-
- pass
-
-
-class TextChoices(str, Choices):
- """Class for creating enumerated string choices."""
-
- def _generate_next_value_(name, start, count, last_values):
- return name