We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Food order can be changed after paying
### Describe the bug
If you order a pizza and pay it, you can still change the product. If you change the product through the api, the payment is not removed.

### How to reproduce
Steps to reproduce the behaviour:
1. Order a pizza
2. Pay with Thalia Pay
3. Change the order through the api
4. Get an expensive pizza for little money

### Expected behaviour
Either changing the order after paying is impossible, or it removes the payment. I think removing the payment (as the website currently seems to do) would be strange, and for event registration we've decided not to enable this.

### Screenshots
<img width="569" alt="image" src="https://user-images.githubusercontent.com/41264528/123456318-01d59880-d5e3-11eb-86c8-9217e4720988.png">

There are probably no food events any time soon, so a hotfix may not be needed, though it might be good to double-check that similar stuff is not possible with registrations.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `website/pizzas/api/v2/views.py`
Content:
```
1 from oauth2_provider.contrib.rest_framework import IsAuthenticatedOrTokenHasScope
2 from rest_framework.generics import (
3     ListAPIView,
4     RetrieveAPIView,
5     get_object_or_404,
6     CreateAPIView,
7     DestroyAPIView,
8     UpdateAPIView,
9 )
10 
11 from rest_framework import filters as framework_filters, status
12 from rest_framework.permissions import DjangoModelPermissionsOrAnonReadOnly
13 from rest_framework.response import Response
14 
15 from pizzas.api.v2 import filters
16 from pizzas.api.v2.serializers import (
17     ProductSerializer,
18     FoodOrderSerializer,
19     FoodOrderUpdateSerializer,
20     FoodOrderCreateSerializer,
21 )
22 from pizzas.api.v2.serializers.food_event import FoodEventSerializer
23 from pizzas.models import FoodEvent, Product, FoodOrder
24 from thaliawebsite.api.v2.permissions import IsAuthenticatedOrTokenHasScopeForMethod
25 
26 
27 class FoodEventListView(ListAPIView):
28     """Returns an overview of all food events."""
29 
30     serializer_class = FoodEventSerializer
31     queryset = FoodEvent.objects.all()
32     filter_backends = (
33         framework_filters.OrderingFilter,
34         filters.FoodEventDateFilterBackend,
35     )
36     ordering_fields = ("start", "end")
37     permission_classes = [
38         IsAuthenticatedOrTokenHasScope,
39         DjangoModelPermissionsOrAnonReadOnly,
40     ]
41     required_scopes = ["food:read"]
42 
43 
44 class FoodEventDetailView(RetrieveAPIView):
45     """Returns one single food event."""
46 
47     serializer_class = FoodEventSerializer
48     queryset = FoodEvent.objects.all()
49     permission_classes = [
50         IsAuthenticatedOrTokenHasScope,
51         DjangoModelPermissionsOrAnonReadOnly,
52     ]
53     required_scopes = ["food:read"]
54 
55 
56 class FoodEventProductsListView(ListAPIView):
57     """Returns an overview of all products."""
58 
59     serializer_class = ProductSerializer
60     queryset = Product.available_products.all()
61     filter_backends = (framework_filters.SearchFilter,)
62     search_fields = ("name",)
63     permission_classes = [
64         IsAuthenticatedOrTokenHasScope,
65         DjangoModelPermissionsOrAnonReadOnly,
66     ]
67     required_scopes = ["food:read"]
68 
69 
70 class FoodEventOrderDetailView(
71     RetrieveAPIView, CreateAPIView, UpdateAPIView, DestroyAPIView
72 ):
73     """Returns details of a food order."""
74 
75     permission_classes = [
76         IsAuthenticatedOrTokenHasScopeForMethod,
77         DjangoModelPermissionsOrAnonReadOnly,
78     ]
79     required_scopes_per_method = {
80         "GET": ["food:read"],
81         "POST": ["food:order"],
82         "PUT": ["food:order"],
83         "PATCH": ["food:order"],
84         "DELETE": ["food:order"],
85     }
86 
87     def get_serializer_class(self):
88         if self.request.method.lower() == "get":
89             return FoodOrderSerializer
90         if self.request.method.lower() == "post":
91             return FoodOrderCreateSerializer
92         return FoodOrderUpdateSerializer
93 
94     def get_queryset(self):
95         return FoodOrder.objects.filter(food_event=self.food_event)
96 
97     def get_object(self):
98         queryset = self.filter_queryset(self.get_queryset())
99         obj = get_object_or_404(queryset, member=self.request.member)
100 
101         # May raise a permission denied
102         self.check_object_permissions(self.request, obj)
103 
104         return obj
105 
106     def dispatch(self, request, *args, **kwargs):
107         self.food_event = get_object_or_404(FoodEvent, pk=self.kwargs.get("pk"))
108         return super().dispatch(request, *args, **kwargs)
109 
110     def update(self, request, *args, **kwargs):
111         super().update(request, *args, **kwargs)
112         instance = self.get_object()
113         return Response(
114             FoodOrderSerializer(instance, context=self.get_serializer_context()).data
115         )
116 
117     def create(self, request, *args, **kwargs):
118         serializer = self.get_serializer(data=request.data)
119         serializer.is_valid(raise_exception=True)
120         self.perform_create(serializer)
121         return Response(
122             FoodOrderSerializer(
123                 serializer.instance, context=self.get_serializer_context()
124             ).data,
125             status=status.HTTP_201_CREATED,
126         )
127
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/website/pizzas/api/v2/views.py b/website/pizzas/api/v2/views.py
--- a/website/pizzas/api/v2/views.py
+++ b/website/pizzas/api/v2/views.py
@@ -12,6 +12,8 @@
 from rest_framework.permissions import DjangoModelPermissionsOrAnonReadOnly
 from rest_framework.response import Response
 
+from payments.exceptions import PaymentError
+from payments.services import delete_payment
 from pizzas.api.v2 import filters
 from pizzas.api.v2.serializers import (
     ProductSerializer,
@@ -110,6 +112,18 @@
     def update(self, request, *args, **kwargs):
         super().update(request, *args, **kwargs)
         instance = self.get_object()
+
+        if instance.payment:
+            try:
+                delete_payment(
+                    instance, member=request.member, ignore_change_window=True
+                )
+            except PaymentError:
+                return Response(
+                    "Your order could not be updated because it was already paid.",
+                    status=status.HTTP_403_FORBIDDEN,
+                )
+
         return Response(
             FoodOrderSerializer(instance, context=self.get_serializer_context()).data
         )

{"golden_diff": "diff --git a/website/pizzas/api/v2/views.py b/website/pizzas/api/v2/views.py\n--- a/website/pizzas/api/v2/views.py\n+++ b/website/pizzas/api/v2/views.py\n@@ -12,6 +12,8 @@\n from rest_framework.permissions import DjangoModelPermissionsOrAnonReadOnly\n from rest_framework.response import Response\n \n+from payments.exceptions import PaymentError\n+from payments.services import delete_payment\n from pizzas.api.v2 import filters\n from pizzas.api.v2.serializers import (\n     ProductSerializer,\n@@ -110,6 +112,18 @@\n     def update(self, request, *args, **kwargs):\n         super().update(request, *args, **kwargs)\n         instance = self.get_object()\n+\n+        if instance.payment:\n+            try:\n+                delete_payment(\n+                    instance, member=request.member, ignore_change_window=True\n+                )\n+            except PaymentError:\n+                return Response(\n+                    \"Your order could not be updated because it was already paid.\",\n+                    status=status.HTTP_403_FORBIDDEN,\n+                )\n+\n         return Response(\n             FoodOrderSerializer(instance, context=self.get_serializer_context()).data\n         )\n", "issue": "Food order can be changed after paying\n### Describe the bug\r\nIf you order a pizza and pay it, you can still change the product. If you change the product through the api, the payment is not removed.\r\n\r\n### How to reproduce\r\nSteps to reproduce the behaviour:\r\n1. Order a pizza\r\n2. Pay with Thalia Pay\r\n3. Change the order through the api\r\n4. Get an expensive pizza for little money\r\n\r\n### Expected behaviour\r\nEither changing the order after paying is impossible, or it removes the payment. I think removing the payment (as the website currently seems to do) would be strange, and for event registration we've decided not to enable this.\r\n\r\n### Screenshots\r\n<img width=\"569\" alt=\"image\" src=\"https://user-images.githubusercontent.com/41264528/123456318-01d59880-d5e3-11eb-86c8-9217e4720988.png\">\r\n\r\nThere are probably no food events any time soon, so a hotfix may not be needed, though it might be good to double-check that similar stuff is not possible with registrations.\r\n\n", "before_files": [{"content": "from oauth2_provider.contrib.rest_framework import IsAuthenticatedOrTokenHasScope\nfrom rest_framework.generics import (\n    ListAPIView,\n    RetrieveAPIView,\n    get_object_or_404,\n    CreateAPIView,\n    DestroyAPIView,\n    UpdateAPIView,\n)\n\nfrom rest_framework import filters as framework_filters, status\nfrom rest_framework.permissions import DjangoModelPermissionsOrAnonReadOnly\nfrom rest_framework.response import Response\n\nfrom pizzas.api.v2 import filters\nfrom pizzas.api.v2.serializers import (\n    ProductSerializer,\n    FoodOrderSerializer,\n    FoodOrderUpdateSerializer,\n    FoodOrderCreateSerializer,\n)\nfrom pizzas.api.v2.serializers.food_event import FoodEventSerializer\nfrom pizzas.models import FoodEvent, Product, FoodOrder\nfrom thaliawebsite.api.v2.permissions import IsAuthenticatedOrTokenHasScopeForMethod\n\n\nclass FoodEventListView(ListAPIView):\n    \"\"\"Returns an overview of all food events.\"\"\"\n\n    serializer_class = FoodEventSerializer\n    queryset = FoodEvent.objects.all()\n    filter_backends = (\n        framework_filters.OrderingFilter,\n        filters.FoodEventDateFilterBackend,\n    )\n    ordering_fields = (\"start\", \"end\")\n    permission_classes = [\n        IsAuthenticatedOrTokenHasScope,\n        DjangoModelPermissionsOrAnonReadOnly,\n    ]\n    required_scopes = [\"food:read\"]\n\n\nclass FoodEventDetailView(RetrieveAPIView):\n    \"\"\"Returns one single food event.\"\"\"\n\n    serializer_class = FoodEventSerializer\n    queryset = FoodEvent.objects.all()\n    permission_classes = [\n        IsAuthenticatedOrTokenHasScope,\n        DjangoModelPermissionsOrAnonReadOnly,\n    ]\n    required_scopes = [\"food:read\"]\n\n\nclass FoodEventProductsListView(ListAPIView):\n    \"\"\"Returns an overview of all products.\"\"\"\n\n    serializer_class = ProductSerializer\n    queryset = Product.available_products.all()\n    filter_backends = (framework_filters.SearchFilter,)\n    search_fields = (\"name\",)\n    permission_classes = [\n        IsAuthenticatedOrTokenHasScope,\n        DjangoModelPermissionsOrAnonReadOnly,\n    ]\n    required_scopes = [\"food:read\"]\n\n\nclass FoodEventOrderDetailView(\n    RetrieveAPIView, CreateAPIView, UpdateAPIView, DestroyAPIView\n):\n    \"\"\"Returns details of a food order.\"\"\"\n\n    permission_classes = [\n        IsAuthenticatedOrTokenHasScopeForMethod,\n        DjangoModelPermissionsOrAnonReadOnly,\n    ]\n    required_scopes_per_method = {\n        \"GET\": [\"food:read\"],\n        \"POST\": [\"food:order\"],\n        \"PUT\": [\"food:order\"],\n        \"PATCH\": [\"food:order\"],\n        \"DELETE\": [\"food:order\"],\n    }\n\n    def get_serializer_class(self):\n        if self.request.method.lower() == \"get\":\n            return FoodOrderSerializer\n        if self.request.method.lower() == \"post\":\n            return FoodOrderCreateSerializer\n        return FoodOrderUpdateSerializer\n\n    def get_queryset(self):\n        return FoodOrder.objects.filter(food_event=self.food_event)\n\n    def get_object(self):\n        queryset = self.filter_queryset(self.get_queryset())\n        obj = get_object_or_404(queryset, member=self.request.member)\n\n        # May raise a permission denied\n        self.check_object_permissions(self.request, obj)\n\n        return obj\n\n    def dispatch(self, request, *args, **kwargs):\n        self.food_event = get_object_or_404(FoodEvent, pk=self.kwargs.get(\"pk\"))\n        return super().dispatch(request, *args, **kwargs)\n\n    def update(self, request, *args, **kwargs):\n        super().update(request, *args, **kwargs)\n        instance = self.get_object()\n        return Response(\n            FoodOrderSerializer(instance, context=self.get_serializer_context()).data\n        )\n\n    def create(self, request, *args, **kwargs):\n        serializer = self.get_serializer(data=request.data)\n        serializer.is_valid(raise_exception=True)\n        self.perform_create(serializer)\n        return Response(\n            FoodOrderSerializer(\n                serializer.instance, context=self.get_serializer_context()\n            ).data,\n            status=status.HTTP_201_CREATED,\n        )\n", "path": "website/pizzas/api/v2/views.py"}], "after_files": [{"content": "from oauth2_provider.contrib.rest_framework import IsAuthenticatedOrTokenHasScope\nfrom rest_framework.generics import (\n    ListAPIView,\n    RetrieveAPIView,\n    get_object_or_404,\n    CreateAPIView,\n    DestroyAPIView,\n    UpdateAPIView,\n)\n\nfrom rest_framework import filters as framework_filters, status\nfrom rest_framework.permissions import DjangoModelPermissionsOrAnonReadOnly\nfrom rest_framework.response import Response\n\nfrom payments.exceptions import PaymentError\nfrom payments.services import delete_payment\nfrom pizzas.api.v2 import filters\nfrom pizzas.api.v2.serializers import (\n    ProductSerializer,\n    FoodOrderSerializer,\n    FoodOrderUpdateSerializer,\n    FoodOrderCreateSerializer,\n)\nfrom pizzas.api.v2.serializers.food_event import FoodEventSerializer\nfrom pizzas.models import FoodEvent, Product, FoodOrder\nfrom thaliawebsite.api.v2.permissions import IsAuthenticatedOrTokenHasScopeForMethod\n\n\nclass FoodEventListView(ListAPIView):\n    \"\"\"Returns an overview of all food events.\"\"\"\n\n    serializer_class = FoodEventSerializer\n    queryset = FoodEvent.objects.all()\n    filter_backends = (\n        framework_filters.OrderingFilter,\n        filters.FoodEventDateFilterBackend,\n    )\n    ordering_fields = (\"start\", \"end\")\n    permission_classes = [\n        IsAuthenticatedOrTokenHasScope,\n        DjangoModelPermissionsOrAnonReadOnly,\n    ]\n    required_scopes = [\"food:read\"]\n\n\nclass FoodEventDetailView(RetrieveAPIView):\n    \"\"\"Returns one single food event.\"\"\"\n\n    serializer_class = FoodEventSerializer\n    queryset = FoodEvent.objects.all()\n    permission_classes = [\n        IsAuthenticatedOrTokenHasScope,\n        DjangoModelPermissionsOrAnonReadOnly,\n    ]\n    required_scopes = [\"food:read\"]\n\n\nclass FoodEventProductsListView(ListAPIView):\n    \"\"\"Returns an overview of all products.\"\"\"\n\n    serializer_class = ProductSerializer\n    queryset = Product.available_products.all()\n    filter_backends = (framework_filters.SearchFilter,)\n    search_fields = (\"name\",)\n    permission_classes = [\n        IsAuthenticatedOrTokenHasScope,\n        DjangoModelPermissionsOrAnonReadOnly,\n    ]\n    required_scopes = [\"food:read\"]\n\n\nclass FoodEventOrderDetailView(\n    RetrieveAPIView, CreateAPIView, UpdateAPIView, DestroyAPIView\n):\n    \"\"\"Returns details of a food order.\"\"\"\n\n    permission_classes = [\n        IsAuthenticatedOrTokenHasScopeForMethod,\n        DjangoModelPermissionsOrAnonReadOnly,\n    ]\n    required_scopes_per_method = {\n        \"GET\": [\"food:read\"],\n        \"POST\": [\"food:order\"],\n        \"PUT\": [\"food:order\"],\n        \"PATCH\": [\"food:order\"],\n        \"DELETE\": [\"food:order\"],\n    }\n\n    def get_serializer_class(self):\n        if self.request.method.lower() == \"get\":\n            return FoodOrderSerializer\n        if self.request.method.lower() == \"post\":\n            return FoodOrderCreateSerializer\n        return FoodOrderUpdateSerializer\n\n    def get_queryset(self):\n        return FoodOrder.objects.filter(food_event=self.food_event)\n\n    def get_object(self):\n        queryset = self.filter_queryset(self.get_queryset())\n        obj = get_object_or_404(queryset, member=self.request.member)\n\n        # May raise a permission denied\n        self.check_object_permissions(self.request, obj)\n\n        return obj\n\n    def dispatch(self, request, *args, **kwargs):\n        self.food_event = get_object_or_404(FoodEvent, pk=self.kwargs.get(\"pk\"))\n        return super().dispatch(request, *args, **kwargs)\n\n    def update(self, request, *args, **kwargs):\n        super().update(request, *args, **kwargs)\n        instance = self.get_object()\n\n        if instance.payment:\n            try:\n                delete_payment(\n                    instance, member=request.member, ignore_change_window=True\n                )\n            except PaymentError:\n                return Response(\n                    \"Your order could not be updated because it was already paid.\",\n                    status=status.HTTP_403_FORBIDDEN,\n                )\n\n        return Response(\n            FoodOrderSerializer(instance, context=self.get_serializer_context()).data\n        )\n\n    def create(self, request, *args, **kwargs):\n        serializer = self.get_serializer(data=request.data)\n        serializer.is_valid(raise_exception=True)\n        self.perform_create(serializer)\n        return Response(\n            FoodOrderSerializer(\n                serializer.instance, context=self.get_serializer_context()\n            ).data,\n            status=status.HTTP_201_CREATED,\n        )\n", "path": "website/pizzas/api/v2/views.py"}]}