Django 2.0
[wolnelektury.git] / src / club / payu / views.py
1 from hashlib import md5, sha256
2 from django.conf import settings
3 from django import http
4 from django.shortcuts import get_object_or_404
5 from django.utils.decorators import method_decorator
6 from django.utils.translation import get_language
7 from django.views.decorators.csrf import csrf_exempt
8 from django.views.generic import FormView, TemplateView, View
9
10
11 class Payment(TemplateView):
12     pass
13
14
15 class RecPayment(FormView):
16     """ Set form_class to a CardTokenForm. """
17     template_name = 'payu/rec_payment.html'
18
19     def get_context_data(self, *args, **kwargs):
20         ctx = super().get_context_data(*args, **kwargs)
21
22         schedule = self.get_schedule()
23         pos = self.get_pos()
24
25         widget_args = {
26             'merchant-pos-id': pos.pos_id,
27             'shop-name': "SHOW NAME",
28             'total-amount': str(int(schedule.amount * 100)),
29             'currency-code': pos.currency_code,
30             'customer-language': get_language(), # filter to pos.languages
31             'customer-email': schedule.email,
32             'store-card': 'true',
33             'recurring-payment': 'true',
34         }
35         widget_sig = sha256(
36             (
37                 "".join(v for (k, v) in sorted(widget_args.items())) +
38                 pos.secondary_key
39             ).encode('utf-8')
40         ).hexdigest()
41
42         ctx['widget_args'] = widget_args
43         ctx['widget_sig'] = widget_sig
44         ctx['schedule'] = schedule
45         ctx['pos'] = pos
46         return ctx
47
48     def form_valid(self, form):
49         form.save(self)
50         return super().form_valid(form)
51
52
53
54 @method_decorator(csrf_exempt, name='dispatch')
55 class NotifyView(View):
56     """ Set `order_model` in subclass. """
57     def post(self, request, pk):
58         order = get_object_or_404(self.order_model, pk=pk)
59
60         try:
61             openpayu = request.META['HTTP_OPENPAYU_SIGNATURE']
62             openpayu = dict(term.split('=') for term in openpayu.split(';'))
63             assert openpayu['algorithm'] == 'MD5'
64             assert openpayu['content'] == 'DOCUMENT'
65             assert openpayu['sender'] == 'checkout'
66             sig = openpayu['signature']
67         except (KeyError, ValueError, AssertionError):
68             return http.HttpResponseBadRequest('bad')
69
70         document = request.body + order.get_pos().secondary_key.encode('latin1')
71         if md5(document).hexdigest() != sig:
72             return http.HttpResponseBadRequest('wrong')
73
74         notification = order.notification_set.create(
75             body=request.body
76         )
77         notification.apply()
78
79         return http.HttpResponse('ok')