FEATURE(pg): check payment request success and add logger

check payment request success and add logger
This commit is contained in:
hgh 2025-10-20 13:39:03 +03:30
parent c8939de18f
commit fe31f41362
4 changed files with 96 additions and 78 deletions

View file

@ -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(
'<a class="button" href="{}">بررسی دوباره موفقیت</a>',
f'{obj.uuid}/check_success_again/'
@ -96,27 +97,19 @@ class PaymentRequestAdmin(admin.ModelAdmin):
path('<uuid:payment_request_uuid>/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", ".."))

View file

@ -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)

View file

@ -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')

View file

@ -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