1 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
2 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
4 from hashlib import md5, sha256
5 from django.conf import settings
6 from django import http
7 from django.shortcuts import get_object_or_404
8 from django.utils.decorators import method_decorator
9 from django.utils.translation import get_language
10 from django.views.decorators.csrf import csrf_exempt
11 from django.views.generic import FormView, TemplateView, View
14 class Payment(TemplateView):
18 class RecPayment(FormView):
19 """ Set form_class to a CardTokenForm. """
20 template_name = 'payu/rec_payment.html'
22 def get_context_data(self, *args, **kwargs):
23 ctx = super().get_context_data(*args, **kwargs)
25 schedule = self.get_schedule()
29 'merchant-pos-id': pos.pos_id,
30 'shop-name': "SHOW NAME",
31 'total-amount': str(int(schedule.amount * 100)),
32 'currency-code': pos.currency_code,
33 'customer-language': get_language(), # filter to pos.languages
34 'customer-email': schedule.email,
36 'recurring-payment': 'true',
40 "".join(v for (k, v) in sorted(widget_args.items())) +
45 ctx['widget_args'] = widget_args
46 ctx['widget_sig'] = widget_sig
47 ctx['schedule'] = schedule
51 def form_valid(self, form):
53 return super().form_valid(form)
57 @method_decorator(csrf_exempt, name='dispatch')
58 class NotifyView(View):
59 """ Set `order_model` in subclass. """
60 def post(self, request, pk):
61 order = get_object_or_404(self.order_model, pk=pk)
64 openpayu = request.META['HTTP_OPENPAYU_SIGNATURE']
65 openpayu = dict(term.split('=') for term in openpayu.split(';'))
66 assert openpayu['algorithm'] == 'MD5'
67 assert openpayu['content'] == 'DOCUMENT'
68 assert openpayu['sender'] == 'checkout'
69 sig = openpayu['signature']
70 except (KeyError, ValueError, AssertionError):
71 return http.HttpResponseBadRequest('bad')
73 document = request.body + order.get_pos().secondary_key.encode('latin1')
74 if md5(document).hexdigest() != sig:
75 return http.HttpResponseBadRequest('wrong')
77 notification = order.notification_set.create(
82 return http.HttpResponse('ok')