diff --git a/src/pretix/plugins/paypal2/views.py b/src/pretix/plugins/paypal2/views.py index 54a6f333f..c83b7a559 100644 --- a/src/pretix/plugins/paypal2/views.py +++ b/src/pretix/plugins/paypal2/views.py @@ -428,7 +428,7 @@ def webhook(request, *args, **kwargs): payment.order.log_action('pretix.plugins.paypal.event', data={ 'event': event_json, - 'sale': sale, + 'sale': sale.dict(), }) if payment.state == OrderPayment.PAYMENT_STATE_CONFIRMED and sale['status'] in ('PARTIALLY_REFUNDED', 'REFUNDED', 'COMPLETED'): @@ -473,7 +473,8 @@ def webhook(request, *args, **kwargs): elif payment.state in (OrderPayment.PAYMENT_STATE_PENDING, OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_CANCELED, OrderPayment.PAYMENT_STATE_FAILED) \ and sale['status'] == 'COMPLETED': - capture_completed = True + any_captures = False + all_captures_completed = True for purchaseunit in sale['purchase_units']: for capture in purchaseunit['payments']['captures']: try: @@ -483,10 +484,12 @@ def webhook(request, *args, **kwargs): pass if capture['status'] not in ('COMPLETED', 'REFUNDED', 'PARTIALLY_REFUNDED'): - capture_completed = False - if capture_completed: + all_captures_completed = False + else: + any_captures = True + if any_captures and all_captures_completed: try: - payment.info = json.dumps(sale) + payment.info = json.dumps(sale.dict()) payment.save(update_fields=['info']) payment.confirm() except Quota.QuotaExceededException: diff --git a/src/tests/plugins/paypal2/test_webhook.py b/src/tests/plugins/paypal2/test_webhook.py index 190151e59..41e78c9ba 100644 --- a/src/tests/plugins/paypal2/test_webhook.py +++ b/src/tests/plugins/paypal2/test_webhook.py @@ -26,6 +26,7 @@ from decimal import Decimal import pytest from django.utils.timezone import now from django_scopes import scopes_disabled +from paypalhttp.http_response import Result from pretix.base.models import ( Event, Order, OrderPayment, OrderRefund, Organizer, Team, User, @@ -262,7 +263,7 @@ def init_api(self): @pytest.mark.django_db def test_webhook_all_good(env, client, monkeypatch): order = env[1] - pp_order = get_test_order() + pp_order = Result(get_test_order()) monkeypatch.setattr("paypalcheckoutsdk.orders.OrdersGetRequest", lambda *args: pp_order) monkeypatch.setattr("pretix.plugins.paypal2.payment.PaypalMethod.init_api", init_api) @@ -406,7 +407,7 @@ def test_webhook_mark_paid(env, client, monkeypatch): with scopes_disabled(): order.payments.update(state=OrderPayment.PAYMENT_STATE_PENDING) - pp_order = get_test_order() + pp_order = Result(get_test_order()) monkeypatch.setattr("paypalcheckoutsdk.orders.OrdersGetRequest", lambda *args: pp_order) monkeypatch.setattr("pretix.plugins.paypal2.payment.PaypalMethod.init_api", init_api) with scopes_disabled(): @@ -503,8 +504,8 @@ def test_webhook_mark_paid(env, client, monkeypatch): @pytest.mark.django_db def test_webhook_refund1(env, client, monkeypatch): order = env[1] - pp_order = get_test_order() - pp_refund = get_test_refund() + pp_order = Result(get_test_order()) + pp_refund = Result(get_test_refund()) monkeypatch.setattr("paypalcheckoutsdk.orders.OrdersGetRequest", lambda *args: pp_order) monkeypatch.setattr("paypalcheckoutsdk.payments.RefundsGetRequest", lambda *args: pp_refund) @@ -597,8 +598,8 @@ def test_webhook_refund1(env, client, monkeypatch): @pytest.mark.django_db def test_webhook_refund2(env, client, monkeypatch): order = env[1] - pp_order = get_test_order() - pp_refund = get_test_refund() + pp_order = Result(get_test_order()) + pp_refund = Result(get_test_refund()) monkeypatch.setattr("paypalcheckoutsdk.orders.OrdersGetRequest", lambda *args: pp_order) monkeypatch.setattr("paypalcheckoutsdk.payments.RefundsGetRequest", lambda *args: pp_refund)