180 lines
6.7 KiB
Python
180 lines
6.7 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 drf_spectacular.utils import extend_schema
|
|
from django.shortcuts import render
|
|
|
|
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):
|
|
@extend_schema(
|
|
request=CommissionSerializer,
|
|
responses=CommissionSerializer
|
|
)
|
|
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)
|
|
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()
|
|
charge_request.refresh_from_db()
|
|
if charge_request.state == StateChoices.FAILED:
|
|
return render(request, 'pg/payment_failure.html', {
|
|
'object': charge_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()
|
|
charge_request.refresh_from_db()
|
|
if charge_request.state == StateChoices.FAILED:
|
|
return render(request, 'pg/payment_failure.html', {
|
|
'object': charge_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_confirm.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()
|
|
# state, message = tool.confirm_request(request)
|
|
# if state:
|
|
# self.template_name = 'pg/payment_success.html'
|
|
#
|
|
#
|
|
# # TODO:
|
|
# context = self.get_context_data(object=self.object)
|
|
# context['message'] = message
|
|
|
|
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)
|