We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
'lines__product' is an invalid parameter to prefetch_related()
### What I'm trying to achieve
See order details page in the storefront.

### Steps to reproduce the problem
1. Create a digital product in the dashboard (no shipping required).
2. Log in as a customer and buy this product.
3. Once the order is created, go to order details page in the storefront. I've accessed it from my order confirmation email.

### What I expected to happen
See order details page in the storefront.

### What happened instead/how it failed
The following error happened:

```
Cannot find 'product' on OrderLine object, 'lines__product' is an invalid parameter to prefetch_related()
```

I don't know why why it works for other orders that I have in database (created by `populatedb`).

Seems that the problem is this line : https://github.com/mirumee/saleor/blob/master/saleor/order/views.py#L29

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `saleor/order/views.py`
Content:
```
1 import logging
2 
3 from django.conf import settings
4 from django.contrib import auth, messages
5 from django.contrib.auth.decorators import login_required
6 from django.db import transaction
7 from django.http import Http404, HttpResponseForbidden
8 from django.shortcuts import get_object_or_404, redirect
9 from django.template.response import TemplateResponse
10 from django.urls import reverse
11 from django.utils.translation import pgettext_lazy
12 from django.views.decorators.csrf import csrf_exempt
13 from payments import PaymentStatus, RedirectNeeded
14 
15 from . import FulfillmentStatus, OrderStatus
16 from ..account.forms import LoginForm
17 from ..account.models import User
18 from ..core.utils import get_client_ip
19 from .forms import (
20     OrderNoteForm, PasswordForm, PaymentDeleteForm, PaymentMethodsForm)
21 from .models import Order, OrderNote, Payment
22 from .utils import attach_order_to_user, check_order_status
23 
24 logger = logging.getLogger(__name__)
25 
26 
27 def details(request, token):
28     orders = Order.objects.confirmed().prefetch_related(
29         'lines__product', 'fulfillments', 'fulfillments__lines',
30         'fulfillments__lines__order_line')
31     orders = orders.select_related(
32         'billing_address', 'shipping_address', 'user')
33     order = get_object_or_404(orders, token=token)
34     notes = order.notes.filter(is_public=True)
35     ctx = {'order': order, 'notes': notes}
36     if order.status == OrderStatus.UNFULFILLED:
37         user = request.user if request.user.is_authenticated else None
38         note = OrderNote(order=order, user=user)
39         note_form = OrderNoteForm(request.POST or None, instance=note)
40         ctx.update({'note_form': note_form})
41         if request.method == 'POST':
42             if note_form.is_valid():
43                 note_form.save()
44                 return redirect('order:details', token=order.token)
45     fulfillments = order.fulfillments.filter(
46         status=FulfillmentStatus.FULFILLED)
47     ctx.update({'fulfillments': fulfillments})
48     return TemplateResponse(request, 'order/details.html', ctx)
49 
50 
51 def payment(request, token):
52     orders = Order.objects.confirmed().filter(billing_address__isnull=False)
53     orders = Order.objects.prefetch_related('lines__variant')
54     orders = orders.select_related(
55         'billing_address', 'shipping_address', 'user')
56     order = get_object_or_404(orders, token=token)
57     payments = order.payments.all()
58     form_data = request.POST or None
59     try:
60         waiting_payment = order.payments.get(status=PaymentStatus.WAITING)
61     except Payment.DoesNotExist:
62         waiting_payment = None
63         waiting_payment_form = None
64     else:
65         form_data = None
66         waiting_payment_form = PaymentDeleteForm(
67             None, order=order, initial={'payment_id': waiting_payment.id})
68     if order.is_fully_paid() or not order.billing_address:
69         form_data = None
70     payment_form = None
71     if not order.is_pre_authorized():
72         payment_form = PaymentMethodsForm(form_data)
73         # FIXME: redirect if there is only one payment method
74         if payment_form.is_valid():
75             payment_method = payment_form.cleaned_data['method']
76             return redirect(
77                 'order:payment', token=order.token, variant=payment_method)
78     ctx = {
79         'order': order, 'payment_form': payment_form, 'payments': payments,
80         'waiting_payment': waiting_payment,
81         'waiting_payment_form': waiting_payment_form}
82     return TemplateResponse(request, 'order/payment.html', ctx)
83 
84 
85 @check_order_status
86 def start_payment(request, order, variant):
87     waiting_payments = order.payments.filter(
88         status=PaymentStatus.WAITING).exists()
89     if waiting_payments:
90         return redirect('order:payment', token=order.token)
91     billing = order.billing_address
92     total = order.total
93     defaults = {
94         'total': total.gross.amount,
95         'tax': total.tax.amount,
96         'currency': total.currency,
97         'delivery': order.shipping_price.gross.amount,
98         'billing_first_name': billing.first_name,
99         'billing_last_name': billing.last_name,
100         'billing_address_1': billing.street_address_1,
101         'billing_address_2': billing.street_address_2,
102         'billing_city': billing.city,
103         'billing_postcode': billing.postal_code,
104         'billing_country_code': billing.country.code,
105         'billing_email': order.user_email,
106         'description': pgettext_lazy(
107             'Payment description', 'Order %(order_number)s') % {
108                 'order_number': order},
109         'billing_country_area': billing.country_area,
110         'customer_ip_address': get_client_ip(request)}
111     variant_choices = settings.CHECKOUT_PAYMENT_CHOICES
112     if variant not in [code for code, dummy_name in variant_choices]:
113         raise Http404('%r is not a valid payment variant' % (variant,))
114     with transaction.atomic():
115         payment, dummy_created = Payment.objects.get_or_create(
116             variant=variant, status=PaymentStatus.WAITING, order=order,
117             defaults=defaults)
118         try:
119             form = payment.get_form(data=request.POST or None)
120         except RedirectNeeded as redirect_to:
121             return redirect(str(redirect_to))
122         except Exception:
123             logger.exception('Error communicating with the payment gateway')
124             msg = pgettext_lazy(
125                 'Payment gateway error',
126                 'Oops, it looks like we were unable to contact the selected '
127                 'payment service')
128             messages.error(request, msg)
129             payment.change_status(PaymentStatus.ERROR)
130             return redirect('order:payment', token=order.token)
131     template = 'order/payment/%s.html' % variant
132     ctx = {'form': form, 'payment': payment}
133     return TemplateResponse(
134         request, [template, 'order/payment/default.html'], ctx)
135 
136 
137 @check_order_status
138 def cancel_payment(request, order):
139     form = PaymentDeleteForm(request.POST or None, order=order)
140     if form.is_valid():
141         with transaction.atomic():
142             form.save()
143         return redirect('order:payment', token=order.token)
144     return HttpResponseForbidden()
145 
146 
147 @csrf_exempt
148 def payment_success(request, token):
149     """Receive request from payment gateway after paying for an order.
150 
151     Redirects user to payment success.
152     All post data and query strings are dropped.
153     """
154     url = reverse('order:checkout-success', kwargs={'token': token})
155     return redirect(url)
156 
157 
158 def checkout_success(request, token):
159     """Redirect user after placing an order.
160 
161     Anonymous users are redirected to the checkout success page.
162     Registered users are redirected to order details page and the order
163     is attached to their account.
164     """
165     order = get_object_or_404(Order, token=token)
166     email = order.user_email
167     ctx = {'email': email, 'order': order}
168     if request.user.is_authenticated:
169         return TemplateResponse(request, 'order/checkout_success.html', ctx)
170     form_data = request.POST.copy()
171     if form_data:
172         form_data.update({'email': email})
173     register_form = PasswordForm(form_data or None)
174     if register_form.is_valid():
175         register_form.save()
176         password = register_form.cleaned_data.get('password')
177         user = auth.authenticate(
178             request=request, email=email, password=password)
179         auth.login(request, user)
180         attach_order_to_user(order, user)
181         return redirect('order:details', token=token)
182     user_exists = User.objects.filter(email=email).exists()
183     login_form = LoginForm(
184         initial={'username': email}) if user_exists else None
185     ctx.update({'form': register_form, 'login_form': login_form})
186     return TemplateResponse(
187         request, 'order/checkout_success_anonymous.html', ctx)
188 
189 
190 @login_required
191 def connect_order_with_user(request, token):
192     """Connect newly created order to an authenticated user."""
193     try:
194         order = Order.objects.get(user_email=request.user.email, token=token)
195     except Order.DoesNotExist:
196         order = None
197     if not order:
198         msg = pgettext_lazy(
199             'Connect order with user warning message',
200             "We couldn't assign the order to your account as the email"
201             " addresses don't match")
202         messages.warning(request, msg)
203         return redirect('account:details')
204     attach_order_to_user(order, request.user)
205     msg = pgettext_lazy(
206         'storefront message',
207         'The order is now assigned to your account')
208     messages.success(request, msg)
209     return redirect('order:details', token=order.token)
210
```
--- 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/saleor/order/views.py b/saleor/order/views.py
--- a/saleor/order/views.py
+++ b/saleor/order/views.py
@@ -26,7 +26,7 @@
 
 def details(request, token):
     orders = Order.objects.confirmed().prefetch_related(
-        'lines__product', 'fulfillments', 'fulfillments__lines',
+        'lines__variant', 'fulfillments', 'fulfillments__lines',
         'fulfillments__lines__order_line')
     orders = orders.select_related(
         'billing_address', 'shipping_address', 'user')

{"golden_diff": "diff --git a/saleor/order/views.py b/saleor/order/views.py\n--- a/saleor/order/views.py\n+++ b/saleor/order/views.py\n@@ -26,7 +26,7 @@\n \n def details(request, token):\n     orders = Order.objects.confirmed().prefetch_related(\n-        'lines__product', 'fulfillments', 'fulfillments__lines',\n+        'lines__variant', 'fulfillments', 'fulfillments__lines',\n         'fulfillments__lines__order_line')\n     orders = orders.select_related(\n         'billing_address', 'shipping_address', 'user')\n", "issue": "'lines__product' is an invalid parameter to prefetch_related()\n### What I'm trying to achieve\r\nSee order details page in the storefront.\r\n\r\n### Steps to reproduce the problem\r\n1. Create a digital product in the dashboard (no shipping required).\r\n2. Log in as a customer and buy this product.\r\n3. Once the order is created, go to order details page in the storefront. I've accessed it from my order confirmation email.\r\n\r\n### What I expected to happen\r\nSee order details page in the storefront.\r\n\r\n### What happened instead/how it failed\r\nThe following error happened:\r\n\r\n```\r\nCannot find 'product' on OrderLine object, 'lines__product' is an invalid parameter to prefetch_related()\r\n```\r\n\r\nI don't know why why it works for other orders that I have in database (created by `populatedb`).\r\n\r\nSeems that the problem is this line : https://github.com/mirumee/saleor/blob/master/saleor/order/views.py#L29\n", "before_files": [{"content": "import logging\n\nfrom django.conf import settings\nfrom django.contrib import auth, messages\nfrom django.contrib.auth.decorators import login_required\nfrom django.db import transaction\nfrom django.http import Http404, HttpResponseForbidden\nfrom django.shortcuts import get_object_or_404, redirect\nfrom django.template.response import TemplateResponse\nfrom django.urls import reverse\nfrom django.utils.translation import pgettext_lazy\nfrom django.views.decorators.csrf import csrf_exempt\nfrom payments import PaymentStatus, RedirectNeeded\n\nfrom . import FulfillmentStatus, OrderStatus\nfrom ..account.forms import LoginForm\nfrom ..account.models import User\nfrom ..core.utils import get_client_ip\nfrom .forms import (\n    OrderNoteForm, PasswordForm, PaymentDeleteForm, PaymentMethodsForm)\nfrom .models import Order, OrderNote, Payment\nfrom .utils import attach_order_to_user, check_order_status\n\nlogger = logging.getLogger(__name__)\n\n\ndef details(request, token):\n    orders = Order.objects.confirmed().prefetch_related(\n        'lines__product', 'fulfillments', 'fulfillments__lines',\n        'fulfillments__lines__order_line')\n    orders = orders.select_related(\n        'billing_address', 'shipping_address', 'user')\n    order = get_object_or_404(orders, token=token)\n    notes = order.notes.filter(is_public=True)\n    ctx = {'order': order, 'notes': notes}\n    if order.status == OrderStatus.UNFULFILLED:\n        user = request.user if request.user.is_authenticated else None\n        note = OrderNote(order=order, user=user)\n        note_form = OrderNoteForm(request.POST or None, instance=note)\n        ctx.update({'note_form': note_form})\n        if request.method == 'POST':\n            if note_form.is_valid():\n                note_form.save()\n                return redirect('order:details', token=order.token)\n    fulfillments = order.fulfillments.filter(\n        status=FulfillmentStatus.FULFILLED)\n    ctx.update({'fulfillments': fulfillments})\n    return TemplateResponse(request, 'order/details.html', ctx)\n\n\ndef payment(request, token):\n    orders = Order.objects.confirmed().filter(billing_address__isnull=False)\n    orders = Order.objects.prefetch_related('lines__variant')\n    orders = orders.select_related(\n        'billing_address', 'shipping_address', 'user')\n    order = get_object_or_404(orders, token=token)\n    payments = order.payments.all()\n    form_data = request.POST or None\n    try:\n        waiting_payment = order.payments.get(status=PaymentStatus.WAITING)\n    except Payment.DoesNotExist:\n        waiting_payment = None\n        waiting_payment_form = None\n    else:\n        form_data = None\n        waiting_payment_form = PaymentDeleteForm(\n            None, order=order, initial={'payment_id': waiting_payment.id})\n    if order.is_fully_paid() or not order.billing_address:\n        form_data = None\n    payment_form = None\n    if not order.is_pre_authorized():\n        payment_form = PaymentMethodsForm(form_data)\n        # FIXME: redirect if there is only one payment method\n        if payment_form.is_valid():\n            payment_method = payment_form.cleaned_data['method']\n            return redirect(\n                'order:payment', token=order.token, variant=payment_method)\n    ctx = {\n        'order': order, 'payment_form': payment_form, 'payments': payments,\n        'waiting_payment': waiting_payment,\n        'waiting_payment_form': waiting_payment_form}\n    return TemplateResponse(request, 'order/payment.html', ctx)\n\n\n@check_order_status\ndef start_payment(request, order, variant):\n    waiting_payments = order.payments.filter(\n        status=PaymentStatus.WAITING).exists()\n    if waiting_payments:\n        return redirect('order:payment', token=order.token)\n    billing = order.billing_address\n    total = order.total\n    defaults = {\n        'total': total.gross.amount,\n        'tax': total.tax.amount,\n        'currency': total.currency,\n        'delivery': order.shipping_price.gross.amount,\n        'billing_first_name': billing.first_name,\n        'billing_last_name': billing.last_name,\n        'billing_address_1': billing.street_address_1,\n        'billing_address_2': billing.street_address_2,\n        'billing_city': billing.city,\n        'billing_postcode': billing.postal_code,\n        'billing_country_code': billing.country.code,\n        'billing_email': order.user_email,\n        'description': pgettext_lazy(\n            'Payment description', 'Order %(order_number)s') % {\n                'order_number': order},\n        'billing_country_area': billing.country_area,\n        'customer_ip_address': get_client_ip(request)}\n    variant_choices = settings.CHECKOUT_PAYMENT_CHOICES\n    if variant not in [code for code, dummy_name in variant_choices]:\n        raise Http404('%r is not a valid payment variant' % (variant,))\n    with transaction.atomic():\n        payment, dummy_created = Payment.objects.get_or_create(\n            variant=variant, status=PaymentStatus.WAITING, order=order,\n            defaults=defaults)\n        try:\n            form = payment.get_form(data=request.POST or None)\n        except RedirectNeeded as redirect_to:\n            return redirect(str(redirect_to))\n        except Exception:\n            logger.exception('Error communicating with the payment gateway')\n            msg = pgettext_lazy(\n                'Payment gateway error',\n                'Oops, it looks like we were unable to contact the selected '\n                'payment service')\n            messages.error(request, msg)\n            payment.change_status(PaymentStatus.ERROR)\n            return redirect('order:payment', token=order.token)\n    template = 'order/payment/%s.html' % variant\n    ctx = {'form': form, 'payment': payment}\n    return TemplateResponse(\n        request, [template, 'order/payment/default.html'], ctx)\n\n\n@check_order_status\ndef cancel_payment(request, order):\n    form = PaymentDeleteForm(request.POST or None, order=order)\n    if form.is_valid():\n        with transaction.atomic():\n            form.save()\n        return redirect('order:payment', token=order.token)\n    return HttpResponseForbidden()\n\n\n@csrf_exempt\ndef payment_success(request, token):\n    \"\"\"Receive request from payment gateway after paying for an order.\n\n    Redirects user to payment success.\n    All post data and query strings are dropped.\n    \"\"\"\n    url = reverse('order:checkout-success', kwargs={'token': token})\n    return redirect(url)\n\n\ndef checkout_success(request, token):\n    \"\"\"Redirect user after placing an order.\n\n    Anonymous users are redirected to the checkout success page.\n    Registered users are redirected to order details page and the order\n    is attached to their account.\n    \"\"\"\n    order = get_object_or_404(Order, token=token)\n    email = order.user_email\n    ctx = {'email': email, 'order': order}\n    if request.user.is_authenticated:\n        return TemplateResponse(request, 'order/checkout_success.html', ctx)\n    form_data = request.POST.copy()\n    if form_data:\n        form_data.update({'email': email})\n    register_form = PasswordForm(form_data or None)\n    if register_form.is_valid():\n        register_form.save()\n        password = register_form.cleaned_data.get('password')\n        user = auth.authenticate(\n            request=request, email=email, password=password)\n        auth.login(request, user)\n        attach_order_to_user(order, user)\n        return redirect('order:details', token=token)\n    user_exists = User.objects.filter(email=email).exists()\n    login_form = LoginForm(\n        initial={'username': email}) if user_exists else None\n    ctx.update({'form': register_form, 'login_form': login_form})\n    return TemplateResponse(\n        request, 'order/checkout_success_anonymous.html', ctx)\n\n\n@login_required\ndef connect_order_with_user(request, token):\n    \"\"\"Connect newly created order to an authenticated user.\"\"\"\n    try:\n        order = Order.objects.get(user_email=request.user.email, token=token)\n    except Order.DoesNotExist:\n        order = None\n    if not order:\n        msg = pgettext_lazy(\n            'Connect order with user warning message',\n            \"We couldn't assign the order to your account as the email\"\n            \" addresses don't match\")\n        messages.warning(request, msg)\n        return redirect('account:details')\n    attach_order_to_user(order, request.user)\n    msg = pgettext_lazy(\n        'storefront message',\n        'The order is now assigned to your account')\n    messages.success(request, msg)\n    return redirect('order:details', token=order.token)\n", "path": "saleor/order/views.py"}], "after_files": [{"content": "import logging\n\nfrom django.conf import settings\nfrom django.contrib import auth, messages\nfrom django.contrib.auth.decorators import login_required\nfrom django.db import transaction\nfrom django.http import Http404, HttpResponseForbidden\nfrom django.shortcuts import get_object_or_404, redirect\nfrom django.template.response import TemplateResponse\nfrom django.urls import reverse\nfrom django.utils.translation import pgettext_lazy\nfrom django.views.decorators.csrf import csrf_exempt\nfrom payments import PaymentStatus, RedirectNeeded\n\nfrom . import FulfillmentStatus, OrderStatus\nfrom ..account.forms import LoginForm\nfrom ..account.models import User\nfrom ..core.utils import get_client_ip\nfrom .forms import (\n    OrderNoteForm, PasswordForm, PaymentDeleteForm, PaymentMethodsForm)\nfrom .models import Order, OrderNote, Payment\nfrom .utils import attach_order_to_user, check_order_status\n\nlogger = logging.getLogger(__name__)\n\n\ndef details(request, token):\n    orders = Order.objects.confirmed().prefetch_related(\n        'lines__variant', 'fulfillments', 'fulfillments__lines',\n        'fulfillments__lines__order_line')\n    orders = orders.select_related(\n        'billing_address', 'shipping_address', 'user')\n    order = get_object_or_404(orders, token=token)\n    notes = order.notes.filter(is_public=True)\n    ctx = {'order': order, 'notes': notes}\n    if order.status == OrderStatus.UNFULFILLED:\n        user = request.user if request.user.is_authenticated else None\n        note = OrderNote(order=order, user=user)\n        note_form = OrderNoteForm(request.POST or None, instance=note)\n        ctx.update({'note_form': note_form})\n        if request.method == 'POST':\n            if note_form.is_valid():\n                note_form.save()\n                return redirect('order:details', token=order.token)\n    fulfillments = order.fulfillments.filter(\n        status=FulfillmentStatus.FULFILLED)\n    ctx.update({'fulfillments': fulfillments})\n    return TemplateResponse(request, 'order/details.html', ctx)\n\n\ndef payment(request, token):\n    orders = Order.objects.confirmed().filter(billing_address__isnull=False)\n    orders = Order.objects.prefetch_related('lines__variant')\n    orders = orders.select_related(\n        'billing_address', 'shipping_address', 'user')\n    order = get_object_or_404(orders, token=token)\n    payments = order.payments.all()\n    form_data = request.POST or None\n    try:\n        waiting_payment = order.payments.get(status=PaymentStatus.WAITING)\n    except Payment.DoesNotExist:\n        waiting_payment = None\n        waiting_payment_form = None\n    else:\n        form_data = None\n        waiting_payment_form = PaymentDeleteForm(\n            None, order=order, initial={'payment_id': waiting_payment.id})\n    if order.is_fully_paid() or not order.billing_address:\n        form_data = None\n    payment_form = None\n    if not order.is_pre_authorized():\n        payment_form = PaymentMethodsForm(form_data)\n        # FIXME: redirect if there is only one payment method\n        if payment_form.is_valid():\n            payment_method = payment_form.cleaned_data['method']\n            return redirect(\n                'order:payment', token=order.token, variant=payment_method)\n    ctx = {\n        'order': order, 'payment_form': payment_form, 'payments': payments,\n        'waiting_payment': waiting_payment,\n        'waiting_payment_form': waiting_payment_form}\n    return TemplateResponse(request, 'order/payment.html', ctx)\n\n\n@check_order_status\ndef start_payment(request, order, variant):\n    waiting_payments = order.payments.filter(\n        status=PaymentStatus.WAITING).exists()\n    if waiting_payments:\n        return redirect('order:payment', token=order.token)\n    billing = order.billing_address\n    total = order.total\n    defaults = {\n        'total': total.gross.amount,\n        'tax': total.tax.amount,\n        'currency': total.currency,\n        'delivery': order.shipping_price.gross.amount,\n        'billing_first_name': billing.first_name,\n        'billing_last_name': billing.last_name,\n        'billing_address_1': billing.street_address_1,\n        'billing_address_2': billing.street_address_2,\n        'billing_city': billing.city,\n        'billing_postcode': billing.postal_code,\n        'billing_country_code': billing.country.code,\n        'billing_email': order.user_email,\n        'description': pgettext_lazy(\n            'Payment description', 'Order %(order_number)s') % {\n                'order_number': order},\n        'billing_country_area': billing.country_area,\n        'customer_ip_address': get_client_ip(request)}\n    variant_choices = settings.CHECKOUT_PAYMENT_CHOICES\n    if variant not in [code for code, dummy_name in variant_choices]:\n        raise Http404('%r is not a valid payment variant' % (variant,))\n    with transaction.atomic():\n        payment, dummy_created = Payment.objects.get_or_create(\n            variant=variant, status=PaymentStatus.WAITING, order=order,\n            defaults=defaults)\n        try:\n            form = payment.get_form(data=request.POST or None)\n        except RedirectNeeded as redirect_to:\n            return redirect(str(redirect_to))\n        except Exception:\n            logger.exception('Error communicating with the payment gateway')\n            msg = pgettext_lazy(\n                'Payment gateway error',\n                'Oops, it looks like we were unable to contact the selected '\n                'payment service')\n            messages.error(request, msg)\n            payment.change_status(PaymentStatus.ERROR)\n            return redirect('order:payment', token=order.token)\n    template = 'order/payment/%s.html' % variant\n    ctx = {'form': form, 'payment': payment}\n    return TemplateResponse(\n        request, [template, 'order/payment/default.html'], ctx)\n\n\n@check_order_status\ndef cancel_payment(request, order):\n    form = PaymentDeleteForm(request.POST or None, order=order)\n    if form.is_valid():\n        with transaction.atomic():\n            form.save()\n        return redirect('order:payment', token=order.token)\n    return HttpResponseForbidden()\n\n\n@csrf_exempt\ndef payment_success(request, token):\n    \"\"\"Receive request from payment gateway after paying for an order.\n\n    Redirects user to payment success.\n    All post data and query strings are dropped.\n    \"\"\"\n    url = reverse('order:checkout-success', kwargs={'token': token})\n    return redirect(url)\n\n\ndef checkout_success(request, token):\n    \"\"\"Redirect user after placing an order.\n\n    Anonymous users are redirected to the checkout success page.\n    Registered users are redirected to order details page and the order\n    is attached to their account.\n    \"\"\"\n    order = get_object_or_404(Order, token=token)\n    email = order.user_email\n    ctx = {'email': email, 'order': order}\n    if request.user.is_authenticated:\n        return TemplateResponse(request, 'order/checkout_success.html', ctx)\n    form_data = request.POST.copy()\n    if form_data:\n        form_data.update({'email': email})\n    register_form = PasswordForm(form_data or None)\n    if register_form.is_valid():\n        register_form.save()\n        password = register_form.cleaned_data.get('password')\n        user = auth.authenticate(\n            request=request, email=email, password=password)\n        auth.login(request, user)\n        attach_order_to_user(order, user)\n        return redirect('order:details', token=token)\n    user_exists = User.objects.filter(email=email).exists()\n    login_form = LoginForm(\n        initial={'username': email}) if user_exists else None\n    ctx.update({'form': register_form, 'login_form': login_form})\n    return TemplateResponse(\n        request, 'order/checkout_success_anonymous.html', ctx)\n\n\n@login_required\ndef connect_order_with_user(request, token):\n    \"\"\"Connect newly created order to an authenticated user.\"\"\"\n    try:\n        order = Order.objects.get(user_email=request.user.email, token=token)\n    except Order.DoesNotExist:\n        order = None\n    if not order:\n        msg = pgettext_lazy(\n            'Connect order with user warning message',\n            \"We couldn't assign the order to your account as the email\"\n            \" addresses don't match\")\n        messages.warning(request, msg)\n        return redirect('account:details')\n    attach_order_to_user(order, request.user)\n    msg = pgettext_lazy(\n        'storefront message',\n        'The order is now assigned to your account')\n    messages.success(request, msg)\n    return redirect('order:details', token=order.token)\n", "path": "saleor/order/views.py"}]}