From e57b23e6169484043e7385393858daf70fd54cab Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Fri, 6 Mar 2015 23:35:48 +0100 Subject: [PATCH] Allow payment providers to process user input --- src/pretix/base/payment.py | 23 +++++++++++++++++++ src/pretix/plugins/banktransfer/payment.py | 3 +++ .../pretixpresale/event/checkout_payment.html | 3 ++- src/pretix/presale/views/checkout.py | 22 +++++++++++++++--- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/pretix/base/payment.py b/src/pretix/base/payment.py index d19901489d..a3423be429 100644 --- a/src/pretix/base/payment.py +++ b/src/pretix/base/payment.py @@ -92,3 +92,26 @@ class BasePaymentProvider: template = get_template('pretixpresale/event/checkout_payment_form_default.html') ctx = Context({'request': request, 'form': form}) return template.render(ctx) + + def checkout_prepare(self, request, total): + """ + Will be called if the user selects this provider as his payment method. + If the payment provider provides a form to the user to enter payment data, + this method should at least store the user's input into his session. + + It should return True or False, depending of the validity of the user's input, + if the frontend should continue with default behaviour, or a custom HTTP response + (for example, a redirect), if you need special behaviour. + + On errors, it should use Django's message framework to display an error message + to the user (or the normal form validation error messages). + + :param total: The total price of the order, including the payment method fee. + """ + form = self.checkout_form(request) + if form.is_valid(): + for k, v in form.cleaned_data.items(): + request.session['payment_%s_%s' % (self.identifier, k)] = v + return True + else: + return False diff --git a/src/pretix/plugins/banktransfer/payment.py b/src/pretix/plugins/banktransfer/payment.py index 5206b5eca9..facb865839 100644 --- a/src/pretix/plugins/banktransfer/payment.py +++ b/src/pretix/plugins/banktransfer/payment.py @@ -23,3 +23,6 @@ class BankTransfer(BasePaymentProvider): template = get_template('pretixplugins/banktransfer/checkout_payment_form.html') ctx = Context({'request': request, 'event': self.event, 'settings': self.settings}) return template.render(ctx) + + def checkout_prepare(self, request, total): + return True diff --git a/src/pretix/presale/templates/pretixpresale/event/checkout_payment.html b/src/pretix/presale/templates/pretixpresale/event/checkout_payment.html index 4d3a5952fc..45a1553ff4 100644 --- a/src/pretix/presale/templates/pretixpresale/event/checkout_payment.html +++ b/src/pretix/presale/templates/pretixpresale/event/checkout_payment.html @@ -21,7 +21,8 @@ -
+
{{ p.form }}
diff --git a/src/pretix/presale/views/checkout.py b/src/pretix/presale/views/checkout.py index f45a38d99a..e396981725 100644 --- a/src/pretix/presale/views/checkout.py +++ b/src/pretix/presale/views/checkout.py @@ -6,6 +6,7 @@ from django.shortcuts import redirect from django.utils.functional import cached_property from django.views.generic import View, TemplateView from django.utils.translation import ugettext_lazy as _ +from django.http import HttpResponse from pretix.base.models import CartPosition, Question, QuestionAnswer from pretix.base.signals import register_payment_providers @@ -204,17 +205,20 @@ class PaymentDetails(EventViewMixin, CartDisplayMixin, EventLoginRequiredMixin, }) @cached_property - def provider_forms(self): - total = CartPosition.objects.current.filter( + def _total_order_value(self): + return CartPosition.objects.current.filter( Q(user=self.request.user) & Q(event=self.request.event) ).aggregate(sum=Sum('price'))['sum'] + + @cached_property + def provider_forms(self): providers = [] responses = register_payment_providers.send(self.request.event) for receiver, response in responses: provider = response(self.request.event) if not provider.is_enabled: continue - fee = provider.calculate_fee(total) + fee = provider.calculate_fee(self._total_order_value) providers.append({ 'provider': provider, 'fee': fee, @@ -222,6 +226,18 @@ class PaymentDetails(EventViewMixin, CartDisplayMixin, EventLoginRequiredMixin, }) return providers + def post(self, request, *args, **kwargs): + for p in self.provider_forms: + if p['provider'].identifier == request.POST.get('payment', ''): + total = self._total_order_value + p['provider'].calculate_fee(self._total_order_value) + resp = p['provider'].checkout_prepare(request, total) + if isinstance(resp, HttpResponse): + return resp + elif resp is True: + return redirect(self.get_success_url()) + else: + return self.get(request, *args, **kwargs) + def get_context_data(self, **kwargs): ctx = super().get_context_data(**kwargs) ctx['providers'] = self.provider_forms