mirror of
https://github.com/pretix/pretix.git
synced 2026-05-09 15:54:03 +00:00
Fix #571 -- Partial payments and refunds
This commit is contained in:
@@ -484,7 +484,7 @@ class PaymentStep(QuestionsViewMixin, CartMixin, TemplateFlowStep):
|
||||
try:
|
||||
return prov.is_allowed(request, total=self._total_order_value)
|
||||
except TypeError:
|
||||
return prov.is_allowed(request)
|
||||
return prov.is_allowed(request, )
|
||||
|
||||
def is_completed(self, request, warn=False):
|
||||
self.request = request
|
||||
@@ -622,7 +622,8 @@ class ConfirmStep(CartMixin, AsyncAction, TemplateFlowStep):
|
||||
def get_order_url(self, order):
|
||||
return eventreverse(self.request.event, 'presale:event.order.pay.complete', kwargs={
|
||||
'order': order.code,
|
||||
'secret': order.secret
|
||||
'secret': order.secret,
|
||||
'payment': order.payments.first().pk
|
||||
})
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
{% load i18n %}
|
||||
{% load bootstrap3 %}
|
||||
{% load eventsignal %}
|
||||
{% load money %}
|
||||
{% load eventurl %}
|
||||
{% block title %}{% trans "Order details" %}{% endblock %}
|
||||
{% block content %}
|
||||
@@ -29,7 +30,7 @@
|
||||
Please save the following link if you want to access your order later. We
|
||||
also sent you an email containing the link to the address you specified.
|
||||
{% endblocktrans %}<br>
|
||||
<code>{{ url }}</code></p>
|
||||
<code>{{ url }}</code></p>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -43,28 +44,35 @@
|
||||
{% if order.status == "n" %}
|
||||
<div class="panel panel-danger">
|
||||
<div class="panel-heading">
|
||||
{% if can_change_method %}
|
||||
<div class="pull-right">
|
||||
<a href="{% eventurl event "presale:event.order.pay.change" secret=order.secret order=order.code %}">
|
||||
<span class="fa fa-edit"></span>
|
||||
{% trans "Use different payment method" %}
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
<h3 class="panel-title">
|
||||
{% trans "Payment" %}
|
||||
</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{% if can_retry %}
|
||||
<a href="{% eventurl event "presale:event.order.pay" secret=order.secret order=order.code %}"
|
||||
class="btn btn-primary pull-right"><i class="fa fa-money"></i> {% trans "Complete payment" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
{{ payment }}
|
||||
<strong>{% blocktrans trimmed with total=pending_sum|money:request.event.currency %}
|
||||
A payment of {{ total }} is still pending for this order.
|
||||
{% endblocktrans %}</strong>
|
||||
<strong>{% blocktrans trimmed with date=order.expires|date:"SHORT_DATE_FORMAT" %}
|
||||
Please complete your payment before {{ date }}
|
||||
{% endblocktrans %}</strong>
|
||||
{% if last_payment %}
|
||||
{{ last_payment_info }}
|
||||
{% if can_pay %}
|
||||
<div class="text-right">
|
||||
<a href="{% eventurl event "presale:event.order.pay.change" secret=order.secret order=order.code %}"
|
||||
class="btn btn-default">
|
||||
{% trans "Re-try payment or choose another payment method" %}
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if can_pay %}
|
||||
<div class="text-right">
|
||||
<a href="{% eventurl event "presale:event.order.pay.change" secret=order.secret order=order.code %}"
|
||||
class="btn btn-primary btn-lg">{% trans "Pay now" %}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<div class="panel-heading">
|
||||
<div class="pull-right">
|
||||
<strong>
|
||||
{% blocktrans trimmed with total=order.total|money:request.event.currency %}
|
||||
{% blocktrans trimmed with total=payment.amount|money:request.event.currency %}
|
||||
Total: {{ total }}
|
||||
{% endblocktrans %}
|
||||
</strong>
|
||||
@@ -29,7 +29,7 @@
|
||||
</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{{ payment }}
|
||||
{{ payment_info }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -62,12 +62,13 @@ event_patterns = [
|
||||
url(r'^order/(?P<order>[^/]+)/(?P<secret>[A-Za-z0-9]+)/modify$',
|
||||
pretix.presale.views.order.OrderModify.as_view(),
|
||||
name='event.order.modify'),
|
||||
url(r'^order/(?P<order>[^/]+)/(?P<secret>[A-Za-z0-9]+)/pay$', pretix.presale.views.order.OrderPaymentStart.as_view(),
|
||||
url(r'^order/(?P<order>[^/]+)/(?P<secret>[A-Za-z0-9]+)/pay/(?P<payment>[0-9]+)/$',
|
||||
pretix.presale.views.order.OrderPaymentStart.as_view(),
|
||||
name='event.order.pay'),
|
||||
url(r'^order/(?P<order>[^/]+)/(?P<secret>[A-Za-z0-9]+)/pay/confirm$',
|
||||
url(r'^order/(?P<order>[^/]+)/(?P<secret>[A-Za-z0-9]+)/pay/(?P<payment>[0-9]+)/confirm$',
|
||||
pretix.presale.views.order.OrderPaymentConfirm.as_view(),
|
||||
name='event.order.pay.confirm'),
|
||||
url(r'^order/(?P<order>[^/]+)/(?P<secret>[A-Za-z0-9]+)/pay/complete$',
|
||||
url(r'^order/(?P<order>[^/]+)/(?P<secret>[A-Za-z0-9]+)/pay/(?P<payment>[0-9]+)/complete$',
|
||||
pretix.presale.views.order.OrderPaymentComplete.as_view(),
|
||||
name='event.order.pay.complete'),
|
||||
url(r'^order/(?P<order>[^/]+)/(?P<secret>[A-Za-z0-9]+)/pay/change',
|
||||
|
||||
@@ -289,7 +289,6 @@ class EventIndex(EventViewMixin, CartMixin, TemplateView):
|
||||
|
||||
|
||||
class EventIcalDownload(EventViewMixin, View):
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
if not self.request.event:
|
||||
raise Http404(_('Unknown event code or not authorized to access this event.'))
|
||||
|
||||
@@ -5,7 +5,7 @@ from decimal import Decimal
|
||||
from django.contrib import messages
|
||||
from django.core.files import File
|
||||
from django.db import transaction
|
||||
from django.db.models import Sum
|
||||
from django.db.models import Exists, OuterRef, Q, Sum
|
||||
from django.http import FileResponse, Http404, JsonResponse
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.utils.decorators import method_decorator
|
||||
@@ -17,7 +17,7 @@ from django.views.generic import TemplateView, View
|
||||
|
||||
from pretix.base.models import CachedTicket, Invoice, Order, OrderPosition
|
||||
from pretix.base.models.orders import (
|
||||
CachedCombinedTicket, OrderFee, QuestionAnswer,
|
||||
CachedCombinedTicket, OrderFee, OrderPayment, QuestionAnswer,
|
||||
)
|
||||
from pretix.base.payment import PaymentException
|
||||
from pretix.base.services.invoices import (
|
||||
@@ -54,10 +54,6 @@ class OrderDetailMixin(NoSearchIndexViewMixin):
|
||||
else:
|
||||
return None
|
||||
|
||||
@cached_property
|
||||
def payment_provider(self):
|
||||
return self.request.event.get_payment_providers().get(self.order.payment_provider)
|
||||
|
||||
def get_order_url(self):
|
||||
return eventreverse(self.request.event, 'presale:event.order', kwargs={
|
||||
'order': self.order.code,
|
||||
@@ -131,24 +127,30 @@ class OrderDetails(EventViewMixin, OrderDetailMixin, CartMixin, TemplateView):
|
||||
}
|
||||
)
|
||||
|
||||
if self.order.status == Order.STATUS_PENDING and self.payment_provider:
|
||||
ctx['payment'] = self.payment_provider.order_pending_render(self.request, self.order)
|
||||
ctx['can_retry'] = (
|
||||
self.payment_provider.order_can_retry(self.order)
|
||||
and self.payment_provider.is_enabled
|
||||
and self.order._can_be_paid()
|
||||
)
|
||||
if self.order.status == Order.STATUS_PENDING:
|
||||
ctx['pending_sum'] = self.order.pending_sum
|
||||
|
||||
lp = self.order.payments.last()
|
||||
ctx['can_pay'] = False
|
||||
|
||||
ctx['can_change_method'] = False
|
||||
for provider in self.request.event.get_payment_providers().values():
|
||||
if (provider.identifier != self.order.payment_provider and provider.is_enabled
|
||||
and provider.order_change_allowed(self.order)):
|
||||
ctx['can_change_method'] = True
|
||||
if provider.is_enabled and provider.order_change_allowed(self.order):
|
||||
ctx['can_pay'] = True
|
||||
break
|
||||
|
||||
if lp and lp.state not in (OrderPayment.PAYMENT_STATE_CONFIRMED, OrderPayment.PAYMENT_STATE_REFUNDED):
|
||||
ctx['last_payment'] = self.order.payments.last()
|
||||
|
||||
pp = lp.payment_provider
|
||||
ctx['last_payment_info'] = pp.payment_pending_render(self.request, ctx['last_payment'])
|
||||
|
||||
if lp.state == OrderPayment.PAYMENT_STATE_PENDING and not pp.abort_pending_allowed:
|
||||
ctx['can_pay'] = False
|
||||
|
||||
ctx['can_pay'] = ctx['can_pay'] and self.order._can_be_paid()
|
||||
|
||||
elif self.order.status == Order.STATUS_PAID:
|
||||
ctx['payment'] = self.payment_provider.order_paid_render(self.request, self.order) if self.payment_provider else ''
|
||||
ctx['can_retry'] = False
|
||||
ctx['can_pay'] = False
|
||||
return ctx
|
||||
|
||||
|
||||
@@ -165,8 +167,8 @@ class OrderPaymentStart(EventViewMixin, OrderDetailMixin, TemplateView):
|
||||
if not self.order:
|
||||
raise Http404(_('Unknown order code or not authorized to access this order.'))
|
||||
if (self.order.status not in (Order.STATUS_PENDING, Order.STATUS_EXPIRED)
|
||||
or not self.payment_provider.order_can_retry(self.order)
|
||||
or not self.payment_provider.is_enabled):
|
||||
or self.payment.state != OrderPayment.PAYMENT_STATE_CREATED
|
||||
or not self.payment.payment_provider.is_enabled):
|
||||
messages.error(request, _('The payment for this order cannot be continued.'))
|
||||
return redirect(self.get_order_url())
|
||||
|
||||
@@ -177,7 +179,7 @@ class OrderPaymentStart(EventViewMixin, OrderDetailMixin, TemplateView):
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
resp = self.payment_provider.order_prepare(request, self.order)
|
||||
resp = self.payment.payment_provider.payment_prepare(request, self.payment)
|
||||
if 'payment_change_{}'.format(self.order.pk) in request.session:
|
||||
del request.session['payment_change_{}'.format(self.order.pk)]
|
||||
if isinstance(resp, str):
|
||||
@@ -191,17 +193,22 @@ class OrderPaymentStart(EventViewMixin, OrderDetailMixin, TemplateView):
|
||||
ctx = super().get_context_data(**kwargs)
|
||||
ctx['order'] = self.order
|
||||
ctx['form'] = self.form
|
||||
ctx['provider'] = self.payment_provider
|
||||
ctx['provider'] = self.payment.payment_provider
|
||||
return ctx
|
||||
|
||||
@cached_property
|
||||
def form(self):
|
||||
return self.payment_provider.payment_form_render(self.request)
|
||||
return self.payment.payment_provider.payment_form_render(self.request)
|
||||
|
||||
@cached_property
|
||||
def payment(self):
|
||||
return get_object_or_404(self.order.payments, pk=self.kwargs['payment'])
|
||||
|
||||
def get_confirm_url(self):
|
||||
return eventreverse(self.request.event, 'presale:event.order.pay.confirm', kwargs={
|
||||
'order': self.order.code,
|
||||
'secret': self.order.secret
|
||||
'secret': self.order.secret,
|
||||
'payment': self.payment.pk
|
||||
})
|
||||
|
||||
|
||||
@@ -214,23 +221,32 @@ class OrderPaymentConfirm(EventViewMixin, OrderDetailMixin, TemplateView):
|
||||
"""
|
||||
template_name = "pretixpresale/event/order_pay_confirm.html"
|
||||
|
||||
@cached_property
|
||||
def payment(self):
|
||||
return get_object_or_404(self.order.payments, pk=self.kwargs['payment'])
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
self.request = request
|
||||
if not self.order:
|
||||
raise Http404(_('Unknown order code or not authorized to access this order.'))
|
||||
can_do = self.payment_provider.order_can_retry(self.order) or 'payment_change_{}'.format(self.order.pk) in request.session
|
||||
if not can_do or not self.payment_provider.is_enabled:
|
||||
if self.payment.state != OrderPayment.PAYMENT_STATE_CREATED:
|
||||
messages.error(request, _('The payment for this order cannot be continued.'))
|
||||
return redirect(self.get_order_url())
|
||||
if (not self.payment_provider.payment_is_valid_session(request)
|
||||
or not self.payment_provider.is_enabled):
|
||||
if (not self.payment.payment_provider.payment_is_valid_session(request) or
|
||||
not self.payment.payment_provider.is_enabled):
|
||||
messages.error(request, _('The payment information you entered was incomplete.'))
|
||||
return redirect(self.get_payment_url())
|
||||
|
||||
term_last = self.order.payment_term_last
|
||||
if term_last and now() > term_last:
|
||||
messages.error(request, _('The payment is too late to be accepted.'))
|
||||
return redirect(self.get_order_url())
|
||||
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
try:
|
||||
resp = self.payment_provider.payment_perform(request, self.order)
|
||||
resp = self.payment.payment_provider.execute_payment(request, self.payment)
|
||||
except PaymentException as e:
|
||||
messages.error(request, str(e))
|
||||
return redirect(self.get_order_url())
|
||||
@@ -241,14 +257,16 @@ class OrderPaymentConfirm(EventViewMixin, OrderDetailMixin, TemplateView):
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super().get_context_data(**kwargs)
|
||||
ctx['order'] = self.order
|
||||
ctx['payment'] = self.payment_provider.checkout_confirm_render(self.request)
|
||||
ctx['payment_provider'] = self.payment_provider
|
||||
ctx['payment'] = self.payment
|
||||
ctx['payment_info'] = self.payment.payment_provider.checkout_confirm_render(self.request)
|
||||
ctx['payment_provider'] = self.payment.payment_provider
|
||||
return ctx
|
||||
|
||||
def get_payment_url(self):
|
||||
return eventreverse(self.request.event, 'presale:event.order.pay', kwargs={
|
||||
'order': self.order.code,
|
||||
'secret': self.order.secret
|
||||
'secret': self.order.secret,
|
||||
'payment': self.payment.pk
|
||||
})
|
||||
|
||||
|
||||
@@ -259,12 +277,20 @@ class OrderPaymentComplete(EventViewMixin, OrderDetailMixin, View):
|
||||
details and confirmed them during the order process and we don't need to show them again,
|
||||
we just need to perform the payment.
|
||||
"""
|
||||
|
||||
@cached_property
|
||||
def payment(self):
|
||||
return get_object_or_404(self.order.payments, pk=self.kwargs['payment'])
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
self.request = request
|
||||
if not self.order:
|
||||
raise Http404(_('Unknown order code or not authorized to access this order.'))
|
||||
if (not self.payment_provider.payment_is_valid_session(request) or
|
||||
not self.payment_provider.is_enabled):
|
||||
if self.payment.state != OrderPayment.PAYMENT_STATE_CREATED:
|
||||
messages.error(request, _('The payment for this order cannot be continued.'))
|
||||
return redirect(self.get_order_url())
|
||||
if (not self.payment.payment_provider.payment_is_valid_session(request) or
|
||||
not self.payment.payment_provider.is_enabled):
|
||||
messages.error(request, _('The payment information you entered was incomplete.'))
|
||||
return redirect(self.get_payment_url())
|
||||
|
||||
@@ -277,7 +303,7 @@ class OrderPaymentComplete(EventViewMixin, OrderDetailMixin, View):
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
try:
|
||||
resp = self.payment_provider.payment_perform(request, self.order)
|
||||
resp = self.payment.payment_provider.execute_payment(request, self.payment)
|
||||
except PaymentException as e:
|
||||
messages.error(request, str(e))
|
||||
return redirect(self.get_order_url())
|
||||
@@ -290,6 +316,7 @@ class OrderPaymentComplete(EventViewMixin, OrderDetailMixin, View):
|
||||
def get_payment_url(self):
|
||||
return eventreverse(self.request.event, 'presale:event.order.pay', kwargs={
|
||||
'order': self.order.code,
|
||||
'payment': self.payment.pk,
|
||||
'secret': self.order.secret
|
||||
})
|
||||
|
||||
@@ -311,83 +338,133 @@ class OrderPayChangeMethod(EventViewMixin, OrderDetailMixin, TemplateView):
|
||||
messages.error(request, _('The payment is too late to be accepted.'))
|
||||
return redirect(self.get_order_url())
|
||||
|
||||
if self.open_payment:
|
||||
pp = self.open_payment.payment_provider
|
||||
if self.open_payment.state == OrderPayment.PAYMENT_STATE_PENDING and not pp.abort_pending_allowed:
|
||||
messages.error(request, _('A payment is currently pending for this order.'))
|
||||
return redirect(self.get_order_url())
|
||||
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_payment_url(self):
|
||||
def get_payment_url(self, payment):
|
||||
return eventreverse(self.request.event, 'presale:event.order.pay', kwargs={
|
||||
'order': self.order.code,
|
||||
'secret': self.order.secret
|
||||
'secret': self.order.secret,
|
||||
'payment': payment.pk
|
||||
})
|
||||
|
||||
@cached_property
|
||||
def _total_order_value(self):
|
||||
def open_fees(self):
|
||||
e = OrderPayment.objects.filter(
|
||||
fee=OuterRef('pk'),
|
||||
state=OrderPayment.PAYMENT_STATE_CONFIRMED
|
||||
)
|
||||
return self.order.fees.annotate(has_p=Exists(e)).filter(
|
||||
Q(fee_type=OrderFee.FEE_TYPE_PAYMENT) & ~Q(has_p=True)
|
||||
)
|
||||
|
||||
@cached_property
|
||||
def open_payment(self):
|
||||
lp = self.order.payments.last()
|
||||
if lp and lp.state not in (OrderPayment.PAYMENT_STATE_CONFIRMED, OrderPayment.PAYMENT_STATE_REFUNDED):
|
||||
return lp
|
||||
return None
|
||||
|
||||
@cached_property
|
||||
def _position_sum(self):
|
||||
return self.order.positions.aggregate(sum=Sum('price'))['sum']
|
||||
|
||||
@cached_property
|
||||
def provider_forms(self):
|
||||
providers = []
|
||||
pending_sum = self.order.pending_sum
|
||||
for provider in self.request.event.get_payment_providers().values():
|
||||
if provider.identifier == self.order.payment_provider:
|
||||
continue
|
||||
if not provider.is_enabled or not provider.order_change_allowed(self.order):
|
||||
continue
|
||||
fee = provider.calculate_fee(self._total_order_value)
|
||||
current_fee = self.order.fees.filter(fee_type=OrderFee.FEE_TYPE_PAYMENT).aggregate(s=Sum('value'))['s'] or Decimal('0.00')
|
||||
current_fee = sum(f.value for f in self.open_fees) or Decimal('0.00')
|
||||
fee = provider.calculate_fee(pending_sum - current_fee)
|
||||
providers.append({
|
||||
'provider': provider,
|
||||
'fee': fee,
|
||||
'fee_diff': fee - current_fee,
|
||||
'fee_diff_abs': abs(fee - current_fee),
|
||||
'total': abs(self._total_order_value + fee),
|
||||
'total': abs(pending_sum + fee - current_fee),
|
||||
'form': provider.payment_form_render(self.request)
|
||||
})
|
||||
return providers
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
self.request = request
|
||||
oldtotal = self.order.total
|
||||
for p in self.provider_forms:
|
||||
if p['provider'].identifier == request.POST.get('payment', ''):
|
||||
request.session['payment'] = p['provider'].identifier
|
||||
request.session['payment_change_{}'.format(self.order.pk)] = '1'
|
||||
|
||||
new_fee = p['provider'].calculate_fee(self._total_order_value)
|
||||
fees = list(self.open_fees)
|
||||
if fees:
|
||||
fee = fees[0]
|
||||
if len(fees) > 1:
|
||||
for f in fees[1:]:
|
||||
f.delete()
|
||||
else:
|
||||
fee = OrderFee(fee_type=OrderFee.FEE_TYPE_PAYMENT, value=Decimal('0.00'), order=self.order)
|
||||
old_fee = fee.value
|
||||
|
||||
new_fee = p['provider'].calculate_fee(self.order.pending_sum - old_fee)
|
||||
if new_fee:
|
||||
fee = self.order.fees.get_or_create(fee_type=OrderFee.FEE_TYPE_PAYMENT, defaults={'value': 0})[0]
|
||||
old_fee = fee.value
|
||||
fee.value = new_fee
|
||||
fee.internal_type = p['provider'].identifier
|
||||
fee._calculate_tax()
|
||||
fee.save()
|
||||
else:
|
||||
try:
|
||||
fee = self.order.fees.get(fee_type=OrderFee.FEE_TYPE_PAYMENT)
|
||||
old_fee = fee.value
|
||||
if fee.pk:
|
||||
fee.delete()
|
||||
except OrderFee.DoesNotExist:
|
||||
old_fee = Decimal('0.00')
|
||||
else:
|
||||
fee = None
|
||||
|
||||
self.order.payment_provider = p['provider'].identifier
|
||||
self.order.total = self._total_order_value + (self.order.fees.aggregate(sum=Sum('value'))['sum'] or 0)
|
||||
if self.open_payment and self.open_payment.state in (OrderPayment.PAYMENT_STATE_PENDING,
|
||||
OrderPayment.PAYMENT_STATE_CREATED):
|
||||
self.open_payment.state = OrderPayment.PAYMENT_STATE_CANCELED
|
||||
self.open_payment.save()
|
||||
|
||||
resp = p['provider'].order_prepare(request, self.order)
|
||||
self.order.total = self._position_sum + (self.order.fees.aggregate(sum=Sum('value'))['sum'] or 0)
|
||||
newpayment = self.order.payments.create(
|
||||
state=OrderPayment.PAYMENT_STATE_CREATED,
|
||||
provider=p['provider'].identifier,
|
||||
amount=self.order.pending_sum,
|
||||
fee=fee
|
||||
)
|
||||
|
||||
resp = p['provider'].payment_prepare(request, newpayment)
|
||||
if resp:
|
||||
with transaction.atomic():
|
||||
self.order.log_action('pretix.event.order.payment.changed', {
|
||||
'old_fee': old_fee,
|
||||
'new_fee': new_fee,
|
||||
'old_provider': self.order.payment_provider,
|
||||
'new_provider': p['provider'].identifier
|
||||
})
|
||||
if self.open_payment and self.open_payment.provider != p['provider'].identifier:
|
||||
self.order.log_action('pretix.event.order.payment.changed', {
|
||||
'old_fee': old_fee,
|
||||
'new_fee': new_fee,
|
||||
'old_provider': self.open_payment.provider,
|
||||
'new_provider': p['provider'].identifier,
|
||||
'payment': newpayment.pk,
|
||||
'local_id': newpayment.local_id,
|
||||
})
|
||||
else:
|
||||
self.order.log_action('pretix.event.order.payment.started', {
|
||||
'fee': new_fee,
|
||||
'provider': p['provider'].identifier,
|
||||
'payment': newpayment.pk,
|
||||
'local_id': newpayment.local_id,
|
||||
})
|
||||
self.order.save()
|
||||
|
||||
i = self.order.invoices.filter(is_cancellation=False).last()
|
||||
if i:
|
||||
if i and self.order.total != oldtotal:
|
||||
generate_cancellation(i)
|
||||
generate_invoice(self.order)
|
||||
if isinstance(resp, str):
|
||||
return redirect(resp)
|
||||
elif resp is True:
|
||||
return redirect(self.get_confirm_url())
|
||||
return redirect(self.get_confirm_url(newpayment))
|
||||
else:
|
||||
return self.get(request, *args, **kwargs)
|
||||
messages.error(self.request, _("Please select a payment method."))
|
||||
@@ -399,10 +476,11 @@ class OrderPayChangeMethod(EventViewMixin, OrderDetailMixin, TemplateView):
|
||||
ctx['providers'] = self.provider_forms
|
||||
return ctx
|
||||
|
||||
def get_confirm_url(self):
|
||||
def get_confirm_url(self, payment):
|
||||
return eventreverse(self.request.event, 'presale:event.order.pay.confirm', kwargs={
|
||||
'order': self.order.code,
|
||||
'secret': self.order.secret
|
||||
'secret': self.order.secret,
|
||||
'payment': payment.pk
|
||||
})
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user