44. Extra adjustments before payment system
Before implementing the payment system, we need to make a few additional adjustments to ensure everything functions correctly. We will start by displaying the error messages we created earlier so that users can see any issues they encounter.
To achieve this, we will update the finish_order
view function to handle errors effectively. If an error occurs, the function will redirect the user back to the checkout page, passing along the order details and the associated error message. This will ensure that users receive feedback and can correct any issues before proceeding.
def finish_order(request, order_id) :
if request.method == "POST" :
error = None
data = request.POST.dict()
total = data.get("total")
order = Order.objects.get(id=order_id) #? used get because it is only one order
if float(total) != float(order.total_cost) : #? transformed to float to avoid comparisson errors
error = "conflicting_cost" #? in case the user tries to manipulate the html
if not "adress" in data :
error = "adress"
else :
id_adress = data.get("adress")
adress = Adres.objects.get(id=id_adress)
order.adress = adress
if not request.user.is_authenticated :
email = data.get("email")
try :
validate_email(email)
except ValidationError :
error = "email"
if not error :
clients = Client.objects.filter(email=email)
if clients:
order.client = clients[0]
else:
order.client.email = email
order.client.save()
if error :
addresses = Adres.objects.filter(client=order.client) #? filters all adresses associated with the client
context = {"error" : error, "order" : order, "addresses" : addresses}
return render(request,"checkout.html", context)
return redirect("checkout")
else :
return redirect("store")
Note: We also modified the address data collection, as the forms send the address ID through the request, not the address itself.
To ensure that the initial value of the error is set to None
, we will include the error
variable in the context of the checkout
view function and initialize it to None
. This value will only be updated if an error occurs during the order process.
context = {"order" : order, "addresses" : addresses, "error" : None}
Next, in the checkout.html
file, we need to display the associated error messages. We will use the error
context variable to show any errors that occur, providing users with feedback if something goes wrong during the checkout process.
<p>Total Quantity: {{ order.total_quantity }}</p>
{% if error %}
{% if error == "conflicting_cost" %}
<p>Invalid product total cost. Try again or return to the cart.</p>
{% endif %}
{% if error == "adress" %}
<p>Select a delivery adress to continue.</p>
{% endif %}
{% if error == "email" %}
<p>Fill in your email to continue.</p>
{% endif %}
{% endif %}
Next, we need to generate a transaction ID for each finalized order. This ID will be composed of the order ID and the date when the order was finalized. We can use Python's datetime
function to obtain the current date, which is represented as a large number (EPOCH time) that counts the seconds from a reference date around the year 1970.
To do this, at the start of the views.py
file, we need to import the datetime
function from Python's datetime
library:
from datetime import datetime
We will enhance the finish_order
view function by implementing functionality to generate a unique transaction ID for each order:
def finish_order(request, order_id) :
if request.method == "POST" :
error = None
data = request.POST.dict()
total = data.get("total")
order = Order.objects.get(id=order_id) #? used get because it is only one order
total = total.replace(",",".") #? in case you are using brazilian version
if float(total) != float(order.total_cost) : #? transformed to float to avoid comparisson errors
error = "conflicting_cost" #? in case the user tries to manipulate the html
if not "adress" in data :
error = "adress"
else :
id_adress = data.get("adress")
adress = Adres.objects.get(id=id_adress)
order.adress = adress
if not request.user.is_authenticated :
email = data.get("email")
try :
validate_email(email)
except ValidationError :
error = "email"
if not error :
clients = Client.objects.filter(email=email)
if clients:
order.client = clients[0]
else:
order.client.email = email
order.client.save()
id_transaction = f"{order.id}-{datetime.now().timestamp()}"
order.id_transaction = id_transaction
order.save()
if error :
addresses = Adres.objects.filter(client=order.client) #? filters all adresses associated with the client
context = {"error" : error, "order" : order, "addresses" : addresses}
return render(request,"checkout.html", context)
else :
#? make payment
return redirect("checkout")
else :
return redirect("store")
Note: In this updated segment, in case you are programming using the brazilian settings, we converted any ',' to a '.'.
In the updated implementation of the finish_order
view function, if a user attempts to complete an order without providing an email address or shipping address, the system will trigger an error message. Subsequently, the user will be redirected back to the same page to correct the missing information. This ensures that all required fields are filled before proceeding with order finalization.

Last updated