diff --git a/src/pretix/plugins/paypal/signals.py b/src/pretix/plugins/paypal/signals.py index 3af96299f9..e2afc0ca5c 100644 --- a/src/pretix/plugins/paypal/signals.py +++ b/src/pretix/plugins/paypal/signals.py @@ -48,6 +48,8 @@ def pretixcontrol_action_display(sender, action, request, **kwargs): template = get_template('pretixplugins/paypal/action_refund.html') elif action.action_type == 'pretix.plugins.paypal.overpaid': template = get_template('pretixplugins/paypal/action_overpaid.html') + elif action.action_type == 'pretix.plugins.paypal.double': + template = get_template('pretixplugins/paypal/action_double.html') ctx = {'data': data, 'event': sender, 'action': action} return template.render(ctx, request) diff --git a/src/pretix/plugins/paypal/templates/pretixplugins/paypal/action_double.html b/src/pretix/plugins/paypal/templates/pretixplugins/paypal/action_double.html new file mode 100644 index 0000000000..a63444bf34 --- /dev/null +++ b/src/pretix/plugins/paypal/templates/pretixplugins/paypal/action_double.html @@ -0,0 +1,9 @@ +{% load i18n %} + +
+ {% url "control:event.order" organizer=event.organizer.slug event=event.slug code=data.order as ourl %} + {% blocktrans trimmed with payment=data.payment order=""|add:data.order|add:""|safe %} + The PayPal transaction {{ payment }} has succeeded, but the order {{ order }} has already been paid by other + means. Please double check and refund the money via PayPal's interface. + {% endblocktrans %} +
diff --git a/src/pretix/plugins/paypal/views.py b/src/pretix/plugins/paypal/views.py index 4e2c1a1319..62ddbc657f 100644 --- a/src/pretix/plugins/paypal/views.py +++ b/src/pretix/plugins/paypal/views.py @@ -161,6 +161,14 @@ def webhook(request, *args, **kwargs): 'sale': sale['id'] }) ) + elif order.status not in (Order.STATUS_PENDING, Order.STATUS_EXPIRED) and sale['state'] == 'completed' and \ + order.payment_provider != "paypal": + RequiredAction.objects.create( + event=event, action_type='pretix.plugins.paypal.double', data=json.dumps({ + 'order': order.code, + 'payment': sale['parent_payment'] + }) + ) elif order.status in (Order.STATUS_PENDING, Order.STATUS_EXPIRED) and sale['state'] == 'completed': try: mark_order_paid(order, user=None) diff --git a/src/pretix/plugins/stripe/signals.py b/src/pretix/plugins/stripe/signals.py index fc95a6a9cc..b135149b2f 100644 --- a/src/pretix/plugins/stripe/signals.py +++ b/src/pretix/plugins/stripe/signals.py @@ -84,6 +84,8 @@ def pretixcontrol_action_display(sender, action, request, **kwargs): template = get_template('pretixplugins/stripe/action_refund.html') elif action.action_type == 'pretix.plugins.stripe.overpaid': template = get_template('pretixplugins/stripe/action_overpaid.html') + elif action.action_type == 'pretix.plugins.stripe.double': + template = get_template('pretixplugins/stripe/action_double.html') ctx = {'data': data, 'event': sender, 'action': action} return template.render(ctx, request) diff --git a/src/pretix/plugins/stripe/templates/pretixplugins/stripe/action_double.html b/src/pretix/plugins/stripe/templates/pretixplugins/stripe/action_double.html new file mode 100644 index 0000000000..e0ceaf8d2b --- /dev/null +++ b/src/pretix/plugins/stripe/templates/pretixplugins/stripe/action_double.html @@ -0,0 +1,9 @@ +{% load i18n %} + ++ {% url "control:event.order" organizer=event.organizer.slug event=event.slug code=data.order as ourl %} + {% blocktrans trimmed with charge=data.charge stripe_href="href='https://dashboard.stripe.com/payments/"|add:data.charge|add:"' target='_blank'"|safe order=""|add:data.order|add:""|safe %} + The Stripe transaction {{ charge }} has succeeded, but the order {{ order }} has + already been paid by other means. Please double-check and refund the money via Stripe's interface. + {% endblocktrans %} +
diff --git a/src/pretix/plugins/stripe/views.py b/src/pretix/plugins/stripe/views.py index 30ebdc58aa..cf352084ac 100644 --- a/src/pretix/plugins/stripe/views.py +++ b/src/pretix/plugins/stripe/views.py @@ -199,6 +199,15 @@ def charge_webhook(event, event_json, charge_id): 'charge': charge_id }) ) + elif order.status == Order.STATUS_PAID and not order.payment_provider.startswith('stripe') and charge['status'] == 'succeeded' and not is_refund: + RequiredAction.objects.create( + event=event, + action_type='pretix.plugins.stripe.double', + data=json.dumps({ + 'order': order.code, + 'charge': charge.id + }) + ) elif order.status in (Order.STATUS_PENDING, Order.STATUS_EXPIRED) and charge['status'] == 'succeeded' and not is_refund: try: mark_order_paid(order, user=None)