diff --git a/src/pretix/base/payment.py b/src/pretix/base/payment.py index 135216aa46..7940794ebe 100644 --- a/src/pretix/base/payment.py +++ b/src/pretix/base/payment.py @@ -330,17 +330,22 @@ class BasePaymentProvider: payment method. This returns ``False`` by default which is no guarantee that aborting a pending payment can never happen, it just hides the frontend button to avoid users accidentally committing double payments. + If the decision doesn't depend on the specific payment, then only implementing + ``abort_pending_allowed`` is enough, ``payment_abort_pending_allowed(payment: OrderPayment)`` + is expected to take this into account. + As a consumer only evaluate ``payment_abort_pending_allowed(payment: OrderPayment)`` + to check if aborting this pending payment is possible. """ return False - def abort_pending_payment_allowed(self, payment) -> bool: + def payment_abort_pending_allowed(self, payment: OrderPayment) -> bool: """ - Whether this specific payment can be aborted in pending state or not. - If both ``abort_pending_allowed`` and ``abort_pending_payment_allowed`` are True, - then the frontend button will be shown to users. - This returns ``True`` by default, which makes implementing this method optional. + Whether or not a user can abort a payment in pending state to switch to another + payment method. This returns ``self.abort_pending_allowed`` by default which is + no guarantee that aborting a pending payment can never happen, it just hides the + frontend button to avoid users accidentally committing double payments. """ - return True + return True and self.abort_pending_allowed @property def requires_invoice_immediately(self): @@ -1030,7 +1035,7 @@ class BasePaymentProvider: """ if payment.state == OrderPayment.PAYMENT_STATE_PENDING: - if not (self.abort_pending_allowed and self.abort_pending_payment_allowed(payment)): + if not self.payment_abort_pending_allowed(payment): raise PaymentException(_( "This payment is already being processed and can not be canceled any more." )) diff --git a/src/pretix/plugins/paypal2/payment.py b/src/pretix/plugins/paypal2/payment.py index 4ce6333141..51080ab4f3 100644 --- a/src/pretix/plugins/paypal2/payment.py +++ b/src/pretix/plugins/paypal2/payment.py @@ -540,11 +540,7 @@ class PaypalMethod(BasePaymentProvider): 'XPF': 0, })) - @property - def abort_pending_allowed(self): - return True - - def abort_pending_payment_allowed(self, payment) -> bool: + def payment_abort_pending_allowed(self, payment) -> bool: if not self.settings.get('allow_retries_during_compliance_hold', as_type=bool, default=True): return False diff --git a/src/pretix/presale/views/order.py b/src/pretix/presale/views/order.py index cc37f8a279..391131fc49 100644 --- a/src/pretix/presale/views/order.py +++ b/src/pretix/presale/views/order.py @@ -349,8 +349,7 @@ class OrderDetails(EventViewMixin, OrderDetailMixin, CartMixin, TicketPageMixin, pp = lp.payment_provider ctx['last_payment_info'] = pp.payment_pending_render(self.request, ctx['last_payment']) - abort_pending_payment_allowed = pp.abort_pending_allowed and pp.abort_pending_payment_allowed(lp) - if lp.state == OrderPayment.PAYMENT_STATE_PENDING and not abort_pending_payment_allowed: + if lp.state == OrderPayment.PAYMENT_STATE_PENDING and not pp.payment_abort_pending_allowed(lp): ctx['can_pay'] = False ctx['can_pay'] = ctx['can_pay'] and self.order._can_be_paid() is True @@ -612,9 +611,8 @@ class OrderPayChangeMethod(EventViewMixin, OrderDetailMixin, TemplateView): if self.open_payment: pp = self.open_payment.payment_provider - abort_pending_payment_allowed = pp.abort_pending_allowed and pp.abort_pending_payment_allowed( - self.open_payment) - if self.open_payment.state == OrderPayment.PAYMENT_STATE_PENDING and not abort_pending_payment_allowed: + if self.open_payment.state == OrderPayment.PAYMENT_STATE_PENDING and not pp.payment_abort_pending_allowed( + self.open_payment): messages.error(request, _('A payment is currently pending for this order.')) return redirect(self.get_order_url()) @@ -1721,9 +1719,7 @@ class OrderChangeMixin: if totaldiff > Decimal('0.00') and self.order.status == Order.STATUS_PENDING: for p in self.order.payments.filter(state=OrderPayment.PAYMENT_STATE_PENDING): - abort_pending_payment_allowed = p.payment_provider.abort_pending_allowed and p.payment_provider.abort_pending_payment_allowed( - p) - if not abort_pending_payment_allowed: + if not p.payment_provider.payment_abort_pending_allowed(p): raise OrderError(_('You may not change your order in a way that requires additional payment while ' 'we are processing your current payment. Please check back after your current ' 'payment has been accepted.'))