50. Finalizing order payment

Now, we will complete the configuration and integration of the payment system into our website.

First, in the api_mercadopago.py file, we will add functionality to automatically redirect the user to the website after finishing the purchase, eliminating the need for them to manually click the "Return to Site" button.

api_mercadopago.py
# Create items in the preference. preference = personalized charge for clients
    preference_data = {
        "items": items,
        "auto_return": "all", #? auto-return to site after payment  
        "back_urls": { #? links that will be loaded in each payment cenario
            "success": link,
            "failure": link,
            "pending": link,
        },
    }

Now, we will update our finalize_payment view function to utilize the data obtained from the request.

views.py
def finalize_payment(request) :
    data = request.GET.dict()
    status = data.get("status")
    payment_id = data.get("preference_id")
    if status == "approved" :
        payment = Payment.objects.get(payment_id=payment_id) #? getting the already existing payment
        payment.aproved = True
        order = payment.order
        order.finished = True
        order.end_date = datetime.now()
        order.save()
        payment.save()
        if request.user.is_authenticated :
            return redirect("my_orders") #? show finished orders
        else :
            return redirect("order_aproved", order.id)
    else :
        return redirect("checkout")

Hereโ€™s a breakdown of the finalize_payment function:

  • Function Definition:

    • def finalize_payment(request): Defines a Django view function to handle the finalization of a payment.

  • Extract Data from Request:

    • data = request.GET.dict(): Retrieves all query parameters from the GET request and converts them to a dictionary.

    • status = data.get("status"): Extracts the payment status from the dictionary.

    • payment_id = data.get("preference_id"): Extracts the payment ID from the dictionary.

  • Check Payment Status:

    • if status == "approved": Checks if the payment status is "approved".

  • Update Payment and Order:

    • payment = Payment.objects.get(payment_id=payment_id): Retrieves the existing Payment object using the payment ID.

    • payment.approved = True: Updates the approved attribute of the payment to True.

    • order = payment.order: Retrieves the associated Order object from the payment.

    • order.finished = True: Marks the order as finished.

    • order.end_date = datetime.now(): Sets the order's end date to the current datetime.

    • order.save(): Saves the updated order to the database.

    • payment.save(): Saves the updated payment to the database.

  • Redirect Based on User Authentication:

    • if request.user.is_authenticated:

      • return redirect("my_orders"): If the user is authenticated, redirects to a view that shows finished orders.

    • else:

      • return redirect("order_aproved", order.id): If the user is not authenticated, redirects to an order approval page with the order ID.

  • Handle Non-Approved Status:

    • else: If the payment status is not "approved":

      • return redirect("checkout"): Redirects to the checkout page.

We will also create another view function called order_approved, where users will be redirected to a page that confirms their purchase was successfully completed and displays the order ID.

views.py
def order_aproved(request, order_id) :
    order = Order.objects.get(id=order_id) #? getting the order by its id
    context = {"order" : order}
    return render(request, "order_aproved.html", context)

Remember to add the new order_approved view function to the URL patterns in the urls.py file.

urls.py
path('orderaproved/<int:order_id>/',order_aproved, name="order_aproved"),

Now, we will create an HTML file named order_approved.html for the page that users are redirected to, confirming their order ID and that the order was approved.

Create this file inside the templates folder, as it pertains to the site itself and is not related to the user account system.

order_aproved.html
{% extends 'base.html' %}
{% load static %}

{% block body %}

<h3>
    Your order was aproved
</h3>
<a href="{% url 'store' %}">Make a new purchase</a>

<h3>You have just recieved a email with all the details of the order</h3>
<div style="display: flex;">
    <p>Date: {{ order.end_date }}</p>
    <p>Order ID: {{ order.id }}</p>
    <p>Transaction ID: {{ order.id_transaction }}</p>
    <p>Total Price: {{ order.total_cost }}</p>
    <p>Adress: {{ order.adress.zip_code }}, {{ order.adress.city }}-{{ order.adress.state }}</p>

    {% for item in order.items %}
        <img src= "{{ item.itemstock.product.image.url }}" width="50" height="75">
        <p>Product: {{ item.itemstock.product.name }}</p>
        <p>Quantity: {{item.quantity }}</p>
        <p>Total price: {{item.total_price }}</p>
    {% endfor %}
</div>
<hr>

{% endblock %}

Now, when a user makes a purchase without being logged into our website, they will be automatically redirected to the order_approved page after the payment process is completed. This page will display their order ID and confirm that the purchase was successful.

If not logged in, you will be redirected to the order confirmation page.
If logged in, your order will be automatically saved to the "My Orders" page.

Last updated