diff --git a/src/pretix/base/services/orders.py b/src/pretix/base/services/orders.py index ee4b4756bd..313ec42fd2 100644 --- a/src/pretix/base/services/orders.py +++ b/src/pretix/base/services/orders.py @@ -46,7 +46,7 @@ from pretix.base.services.tasks import ProfiledTask from pretix.base.signals import ( allow_ticket_download, order_approved, order_canceled, order_changed, order_denied, order_expired, order_fee_calculation, order_placed, - periodic_task, + periodic_task, validate_order, ) from pretix.celery_app import app from pretix.helpers.models import modelcopy @@ -670,6 +670,9 @@ def _perform_order(event: str, payment_provider: str, position_ids: List[str], positions = CartPosition.objects.filter(id__in=position_ids, event=event) + validate_order.send(event, payment_provider=pprov, email=email, positions=positions, + locale=locale, invoice_address=addr, meta_info=meta_info) + lockfn = NoLockManager locked = False if positions.filter(Q(voucher__isnull=False) | Q(expires__lt=now() + timedelta(minutes=2))).exists(): diff --git a/src/pretix/base/signals.py b/src/pretix/base/signals.py index 54c3cd6778..da564554a9 100644 --- a/src/pretix/base/signals.py +++ b/src/pretix/base/signals.py @@ -240,6 +240,19 @@ subclass of pretix.base.exporter.BaseExporter As with all event-plugin signals, the ``sender`` keyword argument will contain the event. """ +validate_order = EventPluginSignal( + providing_args=["payment_provider", "positions", "email", "locale", "invoice_address", + "meta_info"] +) +""" +This signal is sent out when the user tries to confirm the order, before we actually create +the order. It allows you to inspect the cart positions. Your return value will be ignored, +but you can raise an OrderError with an appropriate exception message if you like to block +the order. We strongly discourage making changes to the order here. + +As with all event-plugin signals, the ``sender`` keyword argument will contain the event. +""" + validate_cart = EventPluginSignal( providing_args=["positions"] )