diff --git a/src/pretix/base/payment.py b/src/pretix/base/payment.py index 1a4e92c295..af9754098f 100644 --- a/src/pretix/base/payment.py +++ b/src/pretix/base/payment.py @@ -50,6 +50,16 @@ class BasePaymentProvider: def __str__(self): return self.identifier + @property + def is_implicit(self) -> bool: + """ + Returns whether or whether not this payment provider is an "implicit" payment provider that will + *always* and unconditionally be used if is_allowed() returns True and does not require any input. + This is intended to be used by the FreePaymentProvider, which skips the payment choice page. + By default, this returns ``False``. Please do not set this if you don't know exactly what you are doing. + """ + return False + @property def is_meta(self) -> bool: """ @@ -552,6 +562,10 @@ class PaymentException(Exception): class FreeOrderProvider(BasePaymentProvider): + @property + def is_implicit(self) -> bool: + return True + @property def is_enabled(self) -> bool: return True diff --git a/src/pretix/presale/checkoutflow.py b/src/pretix/presale/checkoutflow.py index 474a765110..cb0fb2f77d 100644 --- a/src/pretix/presale/checkoutflow.py +++ b/src/pretix/presale/checkoutflow.py @@ -487,9 +487,13 @@ class PaymentStep(QuestionsViewMixin, CartMixin, TemplateFlowStep): def is_applicable(self, request): self.request = request - if self._total_order_value == 0: - self.cart_session['payment'] = 'free' - return False + + for p in self.request.event.get_payment_providers().values(): + if p.is_implicit: + if p.is_allowed(request): + self.cart_session['payment'] = p.identifier + return False + return True