from django.contrib import messages from django.http import HttpResponse from django.shortcuts import redirect from django.views.generic import View, TemplateView from django.views.decorators.csrf import csrf_exempt from django.urls import reverse_lazy from django.utils.decorators import method_decorator from paymentwall import Pingback, Product, Widget from apps.course.models import Course from apps.school.models import SchoolSchedule from .models import AuthorBalance, CoursePayment, SchoolPayment class CourseBuyView(TemplateView): template_name = 'payment/paymentwall_widget.html' def get(self, request, pk=None, *args, **kwargs): host = request.scheme + '://' + request.get_host() course = Course.objects.get(id=pk) course_payment = CoursePayment.objects.create( user=request.user, course=course, ) product = Product( f'course_{course_payment.id}', course.price, 'RUB', f'Курс "{course.title}"', ) widget = Widget( str(request.user.id), 'p1', [product], extra_params={ 'lang': 'ru', 'evaluation': 1, 'success_url': host + str(reverse_lazy('payment-success')), 'failure_url': host + str(reverse_lazy('payment-error')), } ) return self.render_to_response(context={'widget': widget.get_html_code()}) class SchoolBuyView(TemplateView): template_name = 'payment/paymentwall_widget.html' def get(self, request, *args, **kwargs): host = request.scheme + '://' + request.get_host() weekdays = set(request.GET.getlist('weekdays', [])) if not weekdays: messages.error(request, 'Выберите несколько дней недели.') return redirect('index') try: weekdays = [int(weekday) for weekday in weekdays] except ValueError: messages.error(request, 'Ошибка выбора дней недели.') return redirect('index') school_payment = SchoolPayment.objects.create( user=request.user, weekdays=weekdays, ) product = Product( f'school_{school_payment.id}', school_payment.amount, 'RUB', 'Школа', ) widget = Widget( str(request.user.id), 'p1', [product], extra_params={ 'lang': 'ru', 'evaluation': 1, 'success_url': host + str(reverse_lazy('payment-success')), 'failure_url': host + str(reverse_lazy('payment-error')), } ) return self.render_to_response(context={'widget': widget.get_html_code()}) @method_decorator(csrf_exempt, name='dispatch') class PaymentwallCallbackView(View): def get_request_ip(self): x_forwarded_for = self.request.META.get('HTTP_X_FORWARDED_FOR') if x_forwarded_for: ip = x_forwarded_for.split(',')[0] else: ip = self.request.META.get('REMOTE_ADDR') return ip def get(self, request, *args, **kwargs): payment_raw_data = request.GET.copy() pingback = Pingback(payment_raw_data, self.get_request_ip()) if pingback.validate(): product_type_name, payment_id = pingback.get_product().get_id().split('_') if product_type_name == 'course': product_payment_class = CoursePayment elif product_type_name == 'school': product_payment_class = SchoolPayment else: return HttpResponse(status=403) try: payment = product_payment_class.objects.get(pk=payment_id) except product_payment_class.DoesNotExist: return HttpResponse(status=403) payment.status = pingback.get_type() payment.data = payment_raw_data payment.save() author_balance = getattr(payment, 'author_balance', None) if author_balance: if pingback.is_deliverable(): payment.author_balance.status = AuthorBalance.ACCEPTED elif pingback.is_under_review(): payment.author_balance.status = AuthorBalance.PENDING else: payment.author_balance.status = AuthorBalance.DECLINED payment.author_balance.save() return HttpResponse('OK', status=403) else: return