Allow payment providers to process user input

This commit is contained in:
Raphael Michel
2015-03-06 23:35:48 +01:00
parent e630858a35
commit e57b23e616
4 changed files with 47 additions and 4 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -21,7 +21,8 @@
</label>
</h4>
</div>
<div id="payment_{{ p.provider.identifier }}" class="panel-collapse collapse">
<div id="payment_{{ p.provider.identifier }}"
class="panel-collapse collapse {% if request.POST.payment == p.provider.identifier %}in{% endif %}">
<div class="panel-body form-horizontal">
{{ p.form }}
</div>

View File

@@ -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