diff --git a/src/pretix/base/payment.py b/src/pretix/base/payment.py index e6d9129dfb..2d30f4e0dc 100644 --- a/src/pretix/base/payment.py +++ b/src/pretix/base/payment.py @@ -1,8 +1,12 @@ +from collections import OrderedDict from decimal import Decimal +from django import forms from django.forms import Form from django.template import Context from django.template.loader import get_template +from django.utils.translation import ugettext_lazy as _ +from pretix.base.forms import SettingsForm from pretix.base.settings import SettingsSandbox @@ -20,45 +24,74 @@ class BasePaymentProvider: return self.identifier @property - def is_enabled(self): + def is_enabled(self) -> bool: """ Returns, whether or whether not this payment provider is enabled. - By default, this is determined by the value of a setting. + By default, this is determined by the value of the ``_enabled`` setting. """ return self.settings.get('_enabled', as_type=bool) - def calculate_fee(self, price): + def calculate_fee(self, price: Decimal) -> Decimal: """ Calculate the fee for this payment provider which will be added to - the final price if the price before fees (but after taxes) is 'price'. + final price before fees (but after taxes). It should include any taxes. + The default implementation makes use of the setting ``_fee_abs`` for an + absolute fee and ``_fee_percent`` for a percentage. + + :param price: The total value without the payment method fee, after taxes. """ fee_abs = self.settings.get('_fee_abs', as_type=Decimal, default=0) fee_percent = self.settings.get('_fee_percent', as_type=Decimal, default=0) - return price * fee_percent / 100 + fee_abs + return Decimal(price * fee_percent / 100 + fee_abs) @property def verbose_name(self) -> str: """ - A human-readable name for this payment provider + A human-readable name for this payment provider. This should + be short but self-explaining. Good examples include 'Bank transfer' + and 'Credit card via Stripe'. """ raise NotImplementedError() # NOQA @property def identifier(self) -> str: """ - A unique identifier for this payment provider + A short and unique identifier for this payment provider. + This should only contain lowercase letters and in most + cases will be the same as your packagename. """ raise NotImplementedError() # NOQA @property def settings_form_fields(self) -> dict: """ + When the event's administrator administrator visits the event configuration + page, A dictionary. The keys should be (unprefixed) EventSetting keys, the values should be corresponding django form fields. We suggest returning a collections.OrderedDict object instead of a dict. """ - raise NotImplementedError() # NOQA + return OrderedDict([ + ('_enabled', + forms.ChoiceField( + label=_('Enable payment method'), + required=False, + choices=SettingsForm.BOOL_CHOICES, + )), + ('_fee_abs', + forms.DecimalField( + label=_('Additional fee'), + help_text=_('Absolute value'), + required=False + )), + ('_fee_percent', + forms.DecimalField( + label=_('Additional fee'), + help_text=_('Percentage'), + required=False + )), + ]) @property def checkout_form_fields(self) -> dict: diff --git a/src/pretix/control/views/event.py b/src/pretix/control/views/event.py index d69f5270ab..738308c862 100644 --- a/src/pretix/control/views/event.py +++ b/src/pretix/control/views/event.py @@ -129,25 +129,6 @@ class PaymentSettings(EventPermissionRequiredMixin, TemplateView, SingleObjectMi ) provider.form.fields = OrderedDict( [ - ('payment_%s__enabled' % provider.identifier, - forms.ChoiceField( - label=_('Enable payment method'), - required=False, - choices=SettingsForm.BOOL_CHOICES, - )), - ('payment_%s__fee_abs' % provider.identifier, - forms.DecimalField( - label=_('Additional fee'), - help_text=_('Absolute value'), - required=False - )), - ('payment_%s__fee_percent' % provider.identifier, - forms.DecimalField( - label=_('Additional fee'), - help_text=_('Percentage'), - required=False - )), - ] + [ ('payment_%s_%s' % (provider.identifier, k), v) for k, v in provider.settings_form_fields.items() ] diff --git a/src/pretix/plugins/banktransfer/payment.py b/src/pretix/plugins/banktransfer/payment.py index 8b57a0a3a3..781b4a7d47 100644 --- a/src/pretix/plugins/banktransfer/payment.py +++ b/src/pretix/plugins/banktransfer/payment.py @@ -10,14 +10,19 @@ from pretix.base.payment import BasePaymentProvider class BankTransfer(BasePaymentProvider): identifier = 'banktransfer' verbose_name = _('Bank transfer') - settings_form_fields = OrderedDict([ - ('bank_details', - forms.CharField( - widget=forms.Textarea, - label=_('Bank account details'), - required=False - )) - ]) + + @property + def settings_form_fields(self): + return OrderedDict( + list(super().settings_form_fields.items()) + [ + ('bank_details', + forms.CharField( + widget=forms.Textarea, + label=_('Bank account details'), + required=False + )) + ] + ) def checkout_form_render(self, request) -> str: template = get_template('pretixplugins/banktransfer/checkout_payment_form.html') diff --git a/src/pretix/plugins/paypal/payment.py b/src/pretix/plugins/paypal/payment.py index 81aa7133b1..b0731264c4 100644 --- a/src/pretix/plugins/paypal/payment.py +++ b/src/pretix/plugins/paypal/payment.py @@ -22,31 +22,36 @@ class Paypal(BasePaymentProvider): identifier = 'paypal' verbose_name = _('PayPal') - settings_form_fields = OrderedDict([ - ('endpoint', - forms.ChoiceField( - label=_('Endpoint'), - initial='live', - choices=( - ('live', 'Live'), - ('sandbox', 'Sandbox'), - ), - required=False - )), - ('client_id', - forms.CharField( - label=_('Client ID'), - required=False - )), - ('secret', - forms.CharField( - label=_('Secret'), - required=False - )) - ]) checkout_form_fields = OrderedDict([ ]) + @property + def settings_form_fields(self): + return OrderedDict( + list(super().settings_form_fields.items()) + [ + ('endpoint', + forms.ChoiceField( + label=_('Endpoint'), + initial='live', + choices=( + ('live', 'Live'), + ('sandbox', 'Sandbox'), + ), + required=False + )), + ('client_id', + forms.CharField( + label=_('Client ID'), + required=False + )), + ('secret', + forms.CharField( + label=_('Secret'), + required=False + )) + ] + ) + def init_api(self): paypalrestsdk.set_config( mode="sandbox" if "sandbox" in self.settings.get('endpoint') else 'live', diff --git a/src/pretix/plugins/stripe/payment.py b/src/pretix/plugins/stripe/payment.py index 245f79d358..95cbd65652 100644 --- a/src/pretix/plugins/stripe/payment.py +++ b/src/pretix/plugins/stripe/payment.py @@ -8,8 +8,6 @@ from pretix.base.payment import BasePaymentProvider class Stripe(BasePaymentProvider): identifier = 'stripe' verbose_name = _('Credit Card via Stripe') - settings_form_fields = OrderedDict([ - ]) checkout_form_fields = OrderedDict([ ('cc_number', forms.CharField(