diff --git a/src/pretix/base/payment.py b/src/pretix/base/payment.py
index eedd7bdc5..195f075e6 100644
--- a/src/pretix/base/payment.py
+++ b/src/pretix/base/payment.py
@@ -1,7 +1,7 @@
from collections import OrderedDict
from datetime import date
from decimal import Decimal
-from typing import Any, Dict
+from typing import Any, Dict, Union
import pytz
from django import forms
@@ -266,7 +266,7 @@ class BasePaymentProvider:
"""
raise NotImplementedError() # NOQA
- def checkout_prepare(self, request: HttpRequest, cart: Dict[str, Any]) -> "bool|str":
+ def checkout_prepare(self, request: HttpRequest, cart: Dict[str, Any]) -> Union[bool, str]:
"""
Will be called after the user selects this provider as his payment method.
If you provided a form to the user to enter payment data, this method should
@@ -394,14 +394,14 @@ class BasePaymentProvider:
"""
return False
- def retry_prepare(self, request: HttpRequest, order: Order) -> "bool|str":
+ def retry_prepare(self, request: HttpRequest, order: Order) -> Union[bool, str]:
"""
Deprecated, use order_prepare instead
"""
raise DeprecationWarning('retry_prepare is deprecated, use order_prepare instead')
return self.order_prepare(request, order)
- def order_prepare(self, request: HttpRequest, order: Order) -> "bool|str":
+ def order_prepare(self, request: HttpRequest, order: Order) -> Union[bool, str]:
"""
Will be called if the user retries to pay an unpaid order (after the user filled in
e.g. the form returned by :py:meth:`payment_form`) or if the user changes the payment
@@ -409,6 +409,10 @@ class BasePaymentProvider:
It should return and report errors the same way as :py:meth:`checkout_prepare`, but
receives an ``Order`` object instead of a cart object.
+
+ Note: The ``Order`` object given to this method might be different from the version
+ stored in the database as it's total will already contain the payment fee for the
+ new payment method.
"""
form = self.payment_form(request)
if form.is_valid():
@@ -458,7 +462,7 @@ class BasePaymentProvider:
return '
%s
' % _('The money can not be automatically refunded, '
'please transfer the money back manually.')
- def order_control_refund_perform(self, request: HttpRequest, order: Order) -> "bool|str":
+ def order_control_refund_perform(self, request: HttpRequest, order: Order) -> Union[bool, str]:
"""
Will be called if the event administrator confirms the refund.
@@ -523,7 +527,7 @@ class FreeOrderProvider(BasePaymentProvider):
def order_control_refund_render(self, order: Order) -> str:
return ''
- def order_control_refund_perform(self, request: HttpRequest, order: Order) -> "bool|str":
+ def order_control_refund_perform(self, request: HttpRequest, order: Order) -> Union[bool, str]:
"""
Will be called if the event administrator confirms the refund.
diff --git a/src/pretix/plugins/paypal/views.py b/src/pretix/plugins/paypal/views.py
index a18583a54..3f6dc4d5d 100644
--- a/src/pretix/plugins/paypal/views.py
+++ b/src/pretix/plugins/paypal/views.py
@@ -57,7 +57,19 @@ def success(request, *args, **kwargs):
@event_view(require_live=False)
def abort(request, *args, **kwargs):
messages.error(request, _('It looks like you canceled the PayPal payment'))
- return redirect(eventreverse(request.event, 'presale:event.checkout', kwargs={'step': 'payment'}))
+
+ if request.session.get('payment_paypal_order'):
+ order = Order.objects.get(pk=request.session.get('payment_paypal_order'))
+ else:
+ order = None
+
+ if order:
+ return redirect(eventreverse(request.event, 'presale:event.order', kwargs={
+ 'order': order.code,
+ 'secret': order.secret
+ }) + ('?paid=yes' if order.status == Order.STATUS_PAID else ''))
+ else:
+ return redirect(eventreverse(request.event, 'presale:event.checkout', kwargs={'step': 'payment'}))
@csrf_exempt
diff --git a/src/pretix/presale/views/order.py b/src/pretix/presale/views/order.py
index 80011b30f..a3a447e9f 100644
--- a/src/pretix/presale/views/order.py
+++ b/src/pretix/presale/views/order.py
@@ -320,20 +320,21 @@ class OrderPayChangeMethod(EventViewMixin, OrderDetailMixin, TemplateView):
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)
+ self.order.payment_provider = p['provider'].identifier
+ self.order.payment_fee = new_fee
+ self.order.total = self._total_order_value + new_fee
+ self.order._calculate_tax()
+
resp = p['provider'].order_prepare(request, self.order)
if resp:
with transaction.atomic():
- new_fee = p['provider'].calculate_fee(self._total_order_value)
self.order.log_action('pretix.event.order.payment.changed', {
'old_fee': self.order.payment_fee,
'new_fee': new_fee,
'old_provider': self.order.payment_provider,
'new_provider': p['provider'].identifier
})
- self.order.payment_provider = p['provider'].identifier
- self.order.payment_fee = new_fee
- self.order.total = self._total_order_value + new_fee
- self.order._calculate_tax()
self.order.save()
i = self.order.invoices.filter(is_cancellation=False).last()