ipg/apps/pg/views.py
Haydar Ghasemi 6aceb75185 FEAT(pg): ipg commission calculation
api/calculate_commission/?amount=300000
2025-11-15 14:15:54 +03:30

185 lines
6.9 KiB
Python

from django.contrib import messages
from django.http import HttpResponseRedirect, HttpResponse
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
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 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
required_scopes = ['wallet.wallet:get_balance'] # TODO: is it good scope?
model = PaymentRequest
def perform_create(self, serializer):
user = self.request.user
application = get_application(self.request)
charge_request: PaymentRequest = serializer.save(user=user, application=application)
# TODO: web view
# charge_request.charge_wallet_balance()
class ApplicationPaymentRequestCreateApiView(generics.CreateAPIView):
permission_classes = [IsAuthenticatedOrTokenHasScope]
serializer_class = PaymentRequestSerializer
required_scopes = ['ipg.application:request_user_charge'] # TODO: is it good scope?
model = PaymentRequest
def perform_create(self, serializer):
user_uuid = self.kwargs.get('uuid')
user, created = User.objects.get_or_create(uuid=user_uuid)
application = get_application(self.request)
charge_request: PaymentRequest = serializer.save(user=user, application=application)
# TODO: web view
# charge_request.charge_wallet_balance()
@method_decorator(csrf_exempt, name='dispatch')
class PaymentRequestView(UpdateView):
template_name = 'pg/payment-request.html'
form_class = PaymentRequestForm
# pk_url_kwarg = 'uuid'
slug_field = 'uuid'
slug_url_kwarg = 'uuid'
# TODO: remove it in future
def get(self, request, *args, **kwargs):
charge_request: PaymentRequest = self.get_object()
charge_request.set_gateway({'pna': True})
charge_request.save_commission()
tool = charge_request.get_gateway_tools()
tool.make_request()
redirect_url = tool.get_pg_page_url()
return HttpResponseRedirect(redirect_url)
# TODO: remove it in future
def post(self, request, *args, **kwargs):
charge_request: PaymentRequest = self.get_object()
charge_request.set_gateway({'pna': True})
tool = charge_request.get_gateway_tools()
tool.make_request()
redirect_url = tool.get_pg_page_url()
return HttpResponseRedirect(redirect_url)
def get_queryset(self):
# return ChargeRequest.objects.all()
# return Charge.objects.filter(state__in=[StateChoices.CREATED.value, StateChoices.SUCCESS.value])
return PaymentRequest.objects.filter(state__in=[StateChoices.CREATED.value])
def form_valid(self, form):
self.object = form.save()
charge_request: PaymentRequest = self.get_object()
charge_request.set_gateway(form.data)
tool = charge_request.get_gateway_tools()
tool.make_request()
redirect_url = tool.get_pg_page_url()
if redirect_url:
return HttpResponseRedirect(redirect_url)
else:
messages.error(self.request, 'can not redirect to payment gateway')
messages.info(self.request, 'در پردازش صفحه خطایی وجود دارد.')
# TODO: redirect to error page
return HttpResponseRedirect(reverse('pg:payment-confirm-view', kwargs={'uuid': charge_request.uuid}))
@method_decorator(csrf_exempt, name='dispatch')
class PaymentConfirmView(UpdateView):
template_name = 'pg/payment_failure.html'
# template_name = 'pg/payment_success.html'
form_class = PaymentRequestForm
# pk_url_kwarg = 'uuid'
slug_field = 'uuid'
slug_url_kwarg = 'uuid'
def get_queryset(self):
return PaymentRequest.objects.all()
# return Charge.objects.filter(state__in=[StateChoices.CREATED.value, StateChoices.SUCCESS.value])
def get(self, request, *args, **kwargs):
print('get')
print(args)
print(kwargs)
self.object = self.get_object()
tool = self.object.get_gateway_tools()
tool.confirm_request(request)
context = self.get_context_data()
return self.render_to_response(context)
def post(self, request, *args, **kwargs):
print("post")
print(request.POST)
print(args)
print(kwargs)
self.object = self.get_object()
if 'redirect-to-app' in request.POST:
response = HttpResponse(status=302)
response['Location'] = self.object.callback_url + f'?state={self.object.state}'
return response
tool = self.object.get_gateway_tools()
state, message = tool.confirm_request(request)
if state:
self.template_name = 'pg/payment_success.html'
context = self.get_context_data(object=self.object)
context['message'] = message
return self.render_to_response(context)
# def form_valid(self, form):
# self.object = form.save()
# charge_request: ChargeRequest = self.get_object()
# try:
#
# # transaction = Transaction.objects.create(
# # uuid=charge.uuid,
# # payee_id=charge.user.pk,
# # payee_type=1,
# # payer_id=payer_pk,
# # payer_type=2,
# # amount=amount,
# # details={'description': 'شارژ مجازی کیف پول'}
# # )
# # transaction.submit()
# # transaction.verify()
# # charge.change_state(from_state=StateChoices.PENDING.value, to_state=StateChoices.SUCCESS.value)
#
# except Exception as e:
# print(e)
# messages.error(self.request, 'خطایی رخ داده است')
# charge_request.change_state(from_state=StateChoices.PENDING.value, to_state=StateChoices.EXPECTED_FAILURE.value)
#
# return HttpResponseRedirect(self.get_success_url())