diff --git a/apps/pg/admin.py b/apps/pg/admin.py
index 650555c..1af6777 100644
--- a/apps/pg/admin.py
+++ b/apps/pg/admin.py
@@ -1,3 +1,4 @@
+import logging
import io
import jdatetime
@@ -7,13 +8,13 @@ from django.db.models import Sum
from django.http import HttpResponse
from django.utils import timezone
from django.utils.html import format_html
-from django.shortcuts import redirect
+from django.shortcuts import redirect, get_object_or_404
from django.urls import path
-from utils.wallet_client import deposit_to_user_wallet_verify
from .constans import StateChoices
from .models import PaymentRequest, PNA, Fake
+logger = logging.getLogger(__name__)
class PNAAdmin(admin.ModelAdmin):
list_display = ['pna_status_code', 'pna_status_message', 'jajali_datetime', 'payment_request']
@@ -83,7 +84,7 @@ class PaymentRequestAdmin(admin.ModelAdmin):
return super().changelist_view(request, extra_context=extra_context)
def check_success_again(self, obj):
- if obj.state == StateChoices.WALLET_SUBMIT_SUCCESS:
+ if obj.state in [StateChoices.IPG_SUCCESS, StateChoices.WALLET_SUBMIT_PENDING, StateChoices.WALLET_SUBMIT_SUCCESS]:
return format_html(
'بررسی دوباره موفقیت',
f'{obj.uuid}/check_success_again/'
@@ -96,27 +97,19 @@ class PaymentRequestAdmin(admin.ModelAdmin):
path('/check_success_again/', self.admin_site.admin_view(self.check_success_again_view))
]
return custom_urls + urls
-
def check_success_again_view(self, request, payment_request_uuid):
- verify_response = deposit_to_user_wallet_verify(payment_request_uuid)
- if not verify_response:
- self.message_user(request, "خطای استعلام", level=messages.ERROR)
- else:
- if not verify_response.uuid or verify_response.state != 5:
- to_pay_failed = PaymentRequest.objects.filter(
- pk=payment_request_uuid,
- state=StateChoices.WALLET_SUBMIT_SUCCESS.value
- ).update(
- state=StateChoices.FAILED.value,
- )
- else:
- to_pay_success = PaymentRequest.objects.filter(
- pk=payment_request_uuid,
- state=StateChoices.WALLET_SUBMIT_SUCCESS.value
- ).update(
- state=StateChoices.SUCCESS.value,
- )
- self.message_user(request, f"درخواست {payment_request_uuid} بررسی شد ✅")
+ logger.info(f"[Admin panel] Check success again for payment_request_uuid={payment_request_uuid}")
+ payment_request: PaymentRequest = get_object_or_404(PaymentRequest, uuid=payment_request_uuid)
+ logger.info(f"[Admin panel] initial payment_request state={payment_request.state}")
+ if payment_request.state == StateChoices.IPG_SUCCESS:
+ payment_request.charge_wallet_balance()
+ elif payment_request.state == StateChoices.WALLET_SUBMIT_PENDING:
+ payment_request.deposit_submit()
+ elif payment_request.state == StateChoices.WALLET_SUBMIT_SUCCESS:
+ payment_request.deposit_verify()
+ payment_request.refresh_from_db()
+ logger.info(f"[Admin panel] final payment_request state={payment_request.state}")
+ self.message_user(request, f"درخواست {payment_request_uuid} بررسی شد ✅")
return redirect(request.META.get("HTTP_REFERER", ".."))
diff --git a/apps/pg/models.py b/apps/pg/models.py
index 68589c6..76f2e3f 100644
--- a/apps/pg/models.py
+++ b/apps/pg/models.py
@@ -1,5 +1,6 @@
+import logging
+
import urllib.parse
-from mimetypes import guess_all_extensions
import jdatetime
from django.conf import settings
@@ -18,7 +19,7 @@ from utils.wallet_client import deposit_to_user_wallet_submit, withdraw_from_use
from utils.pna import PNAClient
from django.utils.translation import gettext_lazy as _
-
+logger = logging.getLogger(__name__)
class GatewayChoise(TextChoices):
FAKE = "fake", _("fake")
@@ -114,7 +115,67 @@ class PaymentRequest(models.Model):
else:
raise Exception(error_message)
+ def deposit_submit(self):
+ data = {
+ "uuid": str(self.uuid),
+ "payee_id": str(self.user.uuid),
+ "payee_type": 1,
+ "amount": self.amount,
+ "details": {
+ 'description': str(_("charge via ipg")),
+ 'reference_id': str(self.uuid),
+ 'application_details_url': ''
+ },
+ }
+ submit_response = deposit_to_user_wallet_submit(settings.WALLET_CATEGORY_UUID, data)
+
+ if not submit_response or not submit_response.uuid:
+ logger.error(f"[Deposit Submit] Wallet submission failed | payment_id={self.pk}")
+ raise Exception('Failed to submit payment in wallet')
+
+ to_success = PaymentRequest.objects.filter(
+ pk=self.pk,
+ state=StateChoices.WALLET_SUBMIT_PENDING.value,
+ ).update(
+ state=StateChoices.WALLET_SUBMIT_SUCCESS.value)
+
+ if not to_success:
+ logger.error(f"[Deposit Submit] Failed to update state to WALLET_SUBMIT_SUCCESS | payment_id={self.pk}")
+ raise Exception('Cannot charge balance because state')
+ return to_success
+
+ def deposit_verify(self):
+ verify_response = deposit_to_user_wallet_verify(settings.WALLET_CATEGORY_UUID, self.uuid)
+
+ if not verify_response:
+ logger.error(f"[Deposit Verify] Failed to get response from wallet service | payment_id={self.pk}")
+ raise Exception('Failed to get response from wallet service')
+
+ if not verify_response.uuid or verify_response.state != 5:
+ logger.error(f"[Deposit Verify] Wallet verification failed | payment_id={self.pk}, response={verify_response}")
+ to_pay_failed = PaymentRequest.objects.filter(
+ pk=self.pk,
+ state=StateChoices.WALLET_SUBMIT_SUCCESS.value
+ ).update(
+ state=StateChoices.FAILED.value,
+ )
+ raise Exception('Failed to verify payment in wallet')
+
+ to_pay_success = PaymentRequest.objects.filter(
+ pk=self.pk,
+ state=StateChoices.WALLET_SUBMIT_SUCCESS.value
+ ).update(
+ state=StateChoices.SUCCESS.value,
+ )
+
+ if not to_pay_success:
+ logger.error(f"[Deposit Verify] Failed to update state to SUCCESS | payment_id={self.pk}")
+ raise Exception('Failed to update state payment')
+
+ return to_pay_success
+
def charge_wallet_balance(self):
+ logger.info(f"[Charge Wallet] Starting wallet charge process | payment_id={self.pk}")
if self.state in [StateChoices.IPG_SUCCESS]:
to_pending = PaymentRequest.objects.filter(
pk=self.pk,
@@ -122,54 +183,15 @@ class PaymentRequest(models.Model):
).update(
state=StateChoices.WALLET_SUBMIT_PENDING.value)
if not to_pending:
+ logger.error(f"[Charge Wallet] Failed to update state to WALLET_SUBMIT_PENDING | payment_id={self.pk}")
raise Exception('Cannot charge balance because state')
-
- data = {
- "uuid": str(self.uuid),
- "payee_id": str(self.user.uuid),
- "payee_type": 1,
- "amount": self.amount,
- "details": {
- 'description': str(_("charge via ipg")),
- 'reference_id': str(self.uuid),
- 'application_details_url': ''
- },
- }
- submit_response = deposit_to_user_wallet_submit(data)
-
- if not submit_response.uuid:
- raise Exception('Failed to submit payment in wallet')
-
- to_success = PaymentRequest.objects.filter(
- pk=self.pk,
- state=StateChoices.WALLET_SUBMIT_PENDING.value,
- ).update(
- state=StateChoices.WALLET_SUBMIT_SUCCESS.value)
-
- if not to_success:
- raise Exception('Cannot charge balance because state')
-
- verify_response = deposit_to_user_wallet_verify(self.uuid)
-
- if not verify_response.uuid or verify_response.state != 5:
- to_pay_failed = PaymentRequest.objects.filter(
- pk=self.pk,
- state=StateChoices.WALLET_SUBMIT_SUCCESS.value
- ).update(
- state=StateChoices.FAILED.value,
- )
- raise Exception('Failed to verify payment in wallet')
-
- to_pay_success = PaymentRequest.objects.filter(
- pk=self.pk,
- state=StateChoices.WALLET_SUBMIT_SUCCESS.value
- ).update(
- state=StateChoices.SUCCESS.value,
- )
-
- if not to_pay_success:
- raise Exception('Failed to update state payment')
-
+ logger.info(f"[Charge Wallet] State updated to WALLET_SUBMIT_PENDING | payment_id={self.pk}")
+ self.deposit_submit()
+ to_pay_success = self.deposit_verify()
+ if to_pay_success:
+ logger.info(f"[Charge Wallet] Wallet charged successfully | payment_id={self.pk}")
+ else:
+ logger.warning(f"[Charge Wallet] Wallet charge verification failed | payment_id={self.pk}")
return bool(to_pay_success)
diff --git a/main/settings.py b/main/settings.py
index 4a5e9a1..16c1f02 100644
--- a/main/settings.py
+++ b/main/settings.py
@@ -255,4 +255,5 @@ CACHES = {
PNA_CORPORATION_PIN = config('PNA_CORPORATION_PIN')
WALLET_BASE_PUBLIC_URL = config('WALLET_BASE_PUBLIC_URL')
+WALLET_CATEGORY_UUID = config('WALLET_CATEGORY_UUID')
IPG_BASE_PUBLIC_URL = config('IPG_BASE_PUBLIC_URL')
diff --git a/utils/wallet_client.py b/utils/wallet_client.py
index 0762eaa..729ae4b 100644
--- a/utils/wallet_client.py
+++ b/utils/wallet_client.py
@@ -8,8 +8,8 @@ from httpx import Request
from gooyal_wallet_client import AuthenticatedClient
from gooyal_wallet_client.models import MyWallet, UserTransaction, ApplicationDeposit, ApplicationWithdraw
-from gooyal_wallet_client.api.wallet import (wallet_api_application_deposit_create,
- wallet_api_application_deposit_verify_retrieve,
+from gooyal_wallet_client.api.wallet import (wallet_api_application_deposit_create_2,
+ wallet_api_application_deposit_verify_retrieve_2,
wallet_api_application_withdraw_create,
wallet_api_application_withdraw_verify_retrieve)
from gooyal_wallet_client.types import Response
@@ -73,22 +73,24 @@ def get_client():
return client
-def deposit_to_user_wallet_submit(data):
+def deposit_to_user_wallet_submit(category_uuid, data):
class Tmp():
def to_dict(self):
return data
deposit_data = Tmp()
client = get_client()
- response: ApplicationDeposit = wallet_api_application_deposit_create.sync(client=client, body=deposit_data)
+ response: ApplicationDeposit = wallet_api_application_deposit_create_2.sync(category_uuid= category_uuid,
+ client=client,
+ body=deposit_data)
print(response)
return response
-def deposit_to_user_wallet_verify(uuid):
+def deposit_to_user_wallet_verify(category_uuid, uuid):
client = get_client()
- response: ApplicationDeposit = wallet_api_application_deposit_verify_retrieve.sync(uuid=uuid, client=client)
+ response: ApplicationDeposit = wallet_api_application_deposit_verify_retrieve_2.sync(category_uuid=category_uuid, uuid=uuid, client=client)
print(response)
return response