From 6aceb7518575747c7320c5d7e45b68dc77c575b0 Mon Sep 17 00:00:00 2001 From: Haydar Ghasemi Date: Sat, 15 Nov 2025 14:15:54 +0330 Subject: [PATCH 1/4] FEAT(pg): ipg commission calculation api/calculate_commission/?amount=300000 --- apps/pg/models.py | 9 +++------ apps/pg/serializers.py | 4 ++++ apps/pg/urls.py | 3 ++- apps/pg/views.py | 28 ++++++++++++++++++++-------- utils/commons.py | 9 +++++++++ 5 files changed, 38 insertions(+), 15 deletions(-) create mode 100644 utils/commons.py diff --git a/apps/pg/models.py b/apps/pg/models.py index 605229c..339e65f 100644 --- a/apps/pg/models.py +++ b/apps/pg/models.py @@ -14,6 +14,7 @@ from apps.core.models import BaseModel, BasePGModel from apps.pg.constans import StateChoices import uuid +from utils.commons import calculate_pna_commission from utils.wallet_client import deposit_to_user_wallet_submit, deposit_to_user_wallet_verify from main import settings @@ -69,12 +70,8 @@ class PaymentRequest(models.Model): return to_jalali(self.created_at) - def calculate_commission(self): - self.commission = settings.COMMISSION_LEVEL1 - if settings.COMMISSION_LEVEL2_MIN_AMOUNT <= self.amount <= settings.COMMISSION_LEVEL2_MAX_AMOUNT: - self.commission = settings.COMMISSION_LEVEL2_RATE * self.amount - elif settings.COMMISSION_LEVEL2_MAX_AMOUNT < self.amount: - self.commission = settings.COMMISSION_LEVEL3 + def save_commission(self): + self.commission = calculate_pna_commission(self.amount) self.save(update_fields=['commission']) def get_gateway_tools(self): diff --git a/apps/pg/serializers.py b/apps/pg/serializers.py index 1f5f18f..3be3ace 100644 --- a/apps/pg/serializers.py +++ b/apps/pg/serializers.py @@ -39,3 +39,7 @@ class ApplicationPaymentRequestSerializer(serializers.ModelSerializer): read_only_fields = ['uuid', 'updated_at', 'state', 'created_at'] + +class CommissionSerializer(serializers.Serializer): + amount = serializers.IntegerField() + commission = serializers.IntegerField(read_only=True) \ No newline at end of file diff --git a/apps/pg/urls.py b/apps/pg/urls.py index 4d3320d..6fa5c3f 100644 --- a/apps/pg/urls.py +++ b/apps/pg/urls.py @@ -1,6 +1,6 @@ from django.urls import path, include from .views import PaymentRequestView, PaymentRequestCreateApiView, PaymentConfirmView, \ - ApplicationPaymentRequestCreateApiView + ApplicationPaymentRequestCreateApiView, CalculateCommissionView app_name = "pg" @@ -9,4 +9,5 @@ urlpatterns = [ path('page/pna_callback//', PaymentConfirmView.as_view(), name='payment-confirm-view'), path('api/charge_create/', PaymentRequestCreateApiView.as_view(), name='charge-request-create-api-view'), path('api/application/charge_create/', ApplicationPaymentRequestCreateApiView.as_view(), name='application-user-charge-request-create-api-view'), + path('api/calculate_commission/', CalculateCommissionView.as_view(), name='calculate-commission-view'), ] diff --git a/apps/pg/views.py b/apps/pg/views.py index 4fd4469..50759bf 100644 --- a/apps/pg/views.py +++ b/apps/pg/views.py @@ -1,23 +1,35 @@ from django.contrib import messages -from django.contrib.auth.decorators import login_required from django.http import HttpResponseRedirect, HttpResponse -from django.shortcuts import render from django.urls import reverse from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_exempt -from django.views.generic import UpdateView, DetailView -from oauth2_provider.contrib.rest_framework import TokenHasScope, IsAuthenticatedOrTokenHasScope +from django.views.generic import UpdateView +from oauth2_provider.contrib.rest_framework import IsAuthenticatedOrTokenHasScope from rest_framework import generics +from rest_framework.response import Response from rest_framework.views import APIView -from .forms import PaymentRequestForm -from .models import PaymentRequest, GatewayChoise -from .serializers import PaymentRequestSerializer, ApplicationPaymentRequestSerializer +from utils.commons import calculate_pna_commission from .constans import StateChoices +from .forms import PaymentRequestForm +from .models import PaymentRequest +from .serializers import PaymentRequestSerializer, CommissionSerializer from ..gooyal_oauth2.utils import get_application from ..users.models import User +class CalculateCommissionView(APIView): + def get(self, request): + serializer = CommissionSerializer(data=request.query_params) + serializer.is_valid(raise_exception=True) + amount = serializer.validated_data['amount'] + commission = calculate_pna_commission(amount) + serializer = CommissionSerializer({ + "amount": amount, + "commission": commission + }) + return Response(serializer.data) + class PaymentRequestCreateApiView(generics.CreateAPIView): permission_classes = [IsAuthenticatedOrTokenHasScope] serializer_class = PaymentRequestSerializer @@ -59,7 +71,7 @@ class PaymentRequestView(UpdateView): def get(self, request, *args, **kwargs): charge_request: PaymentRequest = self.get_object() charge_request.set_gateway({'pna': True}) - charge_request.calculate_commission() + charge_request.save_commission() tool = charge_request.get_gateway_tools() tool.make_request() redirect_url = tool.get_pg_page_url() diff --git a/utils/commons.py b/utils/commons.py new file mode 100644 index 0000000..f48babd --- /dev/null +++ b/utils/commons.py @@ -0,0 +1,9 @@ +from main import settings + +def calculate_pna_commission(amount: int) -> int: + commission = settings.COMMISSION_LEVEL1 + if settings.COMMISSION_LEVEL2_MIN_AMOUNT <= amount <= settings.COMMISSION_LEVEL2_MAX_AMOUNT: + commission = settings.COMMISSION_LEVEL2_RATE * amount + elif settings.COMMISSION_LEVEL2_MAX_AMOUNT < amount: + commission = settings.COMMISSION_LEVEL3 + return commission \ No newline at end of file From 89133022b1c1e0eba876126d7d818081c990f4ad Mon Sep 17 00:00:00 2001 From: Haydar Ghasemi Date: Sat, 15 Nov 2025 14:38:47 +0330 Subject: [PATCH 2/4] FEAT(pg): ipg commission calculation api/calculate_commission/?amount=300000 --- apps/pg/models.py | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/pg/models.py b/apps/pg/models.py index 913f0d7..792b4ae 100644 --- a/apps/pg/models.py +++ b/apps/pg/models.py @@ -16,7 +16,6 @@ import uuid from utils.clients.wallet_client import deposit_to_user_wallet_submit, deposit_to_user_wallet_verify from utils.commons import calculate_pna_commission -from utils.wallet_client import deposit_to_user_wallet_submit, deposit_to_user_wallet_verify from main import settings from utils.pna import PNAClient From 179677756aad1e72554d0bd7ee825d98c3b8a87b Mon Sep 17 00:00:00 2001 From: Haydar Ghasemi Date: Sat, 15 Nov 2025 14:52:32 +0330 Subject: [PATCH 3/4] FEAT(pg): ipg commission calculation ipg commission calculation api/calculate_commission/?amount=300000 --- apps/pg/views.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/apps/pg/views.py b/apps/pg/views.py index 50759bf..c58ce1e 100644 --- a/apps/pg/views.py +++ b/apps/pg/views.py @@ -8,6 +8,7 @@ from oauth2_provider.contrib.rest_framework import IsAuthenticatedOrTokenHasScop from rest_framework import generics from rest_framework.response import Response from rest_framework.views import APIView +from drf_spectacular.utils import extend_schema, OpenApiParameter from utils.commons import calculate_pna_commission from .constans import StateChoices @@ -19,6 +20,18 @@ from ..users.models import User class CalculateCommissionView(APIView): + @extend_schema( + parameters=[ + OpenApiParameter( + name='amount', + required=True, + type=float, + location=OpenApiParameter.QUERY, + description='مبلغ' + ) + ], + responses=CommissionSerializer + ) def get(self, request): serializer = CommissionSerializer(data=request.query_params) serializer.is_valid(raise_exception=True) From d0e8b24321fb19ab2208be8de8c5738921df9fdb Mon Sep 17 00:00:00 2001 From: Haydar Ghasemi Date: Sat, 15 Nov 2025 14:59:15 +0330 Subject: [PATCH 4/4] FEAT(pg): ipg commission calculation ipg commission calculation api/calculate_commission/?amount=300000 --- apps/pg/views.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/apps/pg/views.py b/apps/pg/views.py index c58ce1e..5022bc1 100644 --- a/apps/pg/views.py +++ b/apps/pg/views.py @@ -8,7 +8,7 @@ from oauth2_provider.contrib.rest_framework import IsAuthenticatedOrTokenHasScop from rest_framework import generics from rest_framework.response import Response from rest_framework.views import APIView -from drf_spectacular.utils import extend_schema, OpenApiParameter +from drf_spectacular.utils import extend_schema from utils.commons import calculate_pna_commission from .constans import StateChoices @@ -21,19 +21,11 @@ from ..users.models import User class CalculateCommissionView(APIView): @extend_schema( - parameters=[ - OpenApiParameter( - name='amount', - required=True, - type=float, - location=OpenApiParameter.QUERY, - description='مبلغ' - ) - ], + request=CommissionSerializer, responses=CommissionSerializer ) - def get(self, request): - serializer = CommissionSerializer(data=request.query_params) + def post(self, request): + serializer = CommissionSerializer(data=request.data) serializer.is_valid(raise_exception=True) amount = serializer.validated_data['amount'] commission = calculate_pna_commission(amount)