134 lines
4.9 KiB
Python
134 lines
4.9 KiB
Python
from django.shortcuts import render, redirect, get_object_or_404
|
|
from django.contrib.auth.forms import UserCreationForm
|
|
from django.contrib.auth import login
|
|
from django.views.decorators.http import require_POST
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.conf import settings
|
|
import requests
|
|
import json
|
|
|
|
from .models import Product, Category, Cart, CartItem, Order, OrderItem
|
|
|
|
def index(request):
|
|
"""Render the new landing page."""
|
|
products = Product.objects.filter(is_available=True)
|
|
categories = Category.objects.all()
|
|
context = {
|
|
'products': products,
|
|
'categories': categories,
|
|
}
|
|
return render(request, "core/index.html", context)
|
|
|
|
def signup(request):
|
|
"""Handle user signup."""
|
|
if request.method == 'POST':
|
|
form = UserCreationForm(request.POST)
|
|
if form.is_valid():
|
|
user = form.save()
|
|
# You can log the user in directly if you want
|
|
# login(request, user)
|
|
return redirect('login')
|
|
else:
|
|
form = UserCreationForm()
|
|
return render(request, 'registration/signup.html', {'form': form})
|
|
|
|
def _get_cart(request):
|
|
if request.user.is_authenticated:
|
|
cart, created = Cart.objects.get_or_create(user=request.user)
|
|
else:
|
|
session_key = request.session.session_key
|
|
if not session_key:
|
|
request.session.create()
|
|
session_key = request.session.session_key
|
|
cart, created = Cart.objects.get_or_create(session_key=session_key)
|
|
return cart
|
|
|
|
@require_POST
|
|
def add_to_cart(request, product_id):
|
|
cart = _get_cart(request)
|
|
product = get_object_or_404(Product, id=product_id)
|
|
quantity = int(request.POST.get('quantity', 1))
|
|
|
|
cart_item, created = CartItem.objects.get_or_create(cart=cart, product=product)
|
|
if not created:
|
|
cart_item.quantity += quantity
|
|
else:
|
|
cart_item.quantity = quantity
|
|
cart_item.save()
|
|
|
|
return redirect('cart_detail')
|
|
|
|
def cart_detail(request):
|
|
cart = _get_cart(request)
|
|
return render(request, 'core/cart_detail.html', {'cart': cart})
|
|
|
|
@login_required
|
|
def checkout(request):
|
|
cart = _get_cart(request)
|
|
if not cart.items.all():
|
|
return redirect('index')
|
|
return render(request, 'core/cart_detail.html', {'cart': cart})
|
|
|
|
@login_required
|
|
def initiate_payment(request):
|
|
cart = _get_cart(request)
|
|
if not cart.items.all():
|
|
return redirect('index')
|
|
|
|
url = 'https://api.paystack.co/transaction/initialize'
|
|
headers = {
|
|
'Authorization': f'Bearer {settings.PAYSTACK_SECRET_KEY}',
|
|
'Content-Type': 'application/json',
|
|
}
|
|
data = {
|
|
"email": request.user.email,
|
|
"amount": cart.total_price_in_kobo,
|
|
"callback_.pyurl": request.build_absolute_uri(f"/verify-payment/"),
|
|
}
|
|
|
|
try:
|
|
response = requests.post(url, headers=headers, data=json.dumps(data))
|
|
response_data = response.json()
|
|
if response_data['status']:
|
|
# store the reference in the session, so we can retrieve it in the callback
|
|
request.session['payment_ref'] = response_data['data']['reference']
|
|
return redirect(response_data['data']['authorization_url'])
|
|
else:
|
|
return render(request, 'core/payment_failure.html', {'error': response_data['message']})
|
|
except requests.exceptions.RequestException as e:
|
|
return render(request, 'core/payment_failure.html', {'error': f"An error occurred: {e}"})
|
|
|
|
@login_required
|
|
def verify_payment(request):
|
|
ref = request.GET.get('reference')
|
|
if not ref:
|
|
# if the reference is not in the get request, check the session
|
|
ref = request.session.get('payment_ref')
|
|
if not ref:
|
|
return redirect('payment_failure')
|
|
|
|
url = f'https://api.paystack.co/transaction/verify/{ref}'
|
|
headers = {
|
|
'Authorization': f'Bearer {settings.PAYSTACK_SECRET_KEY}',
|
|
}
|
|
|
|
try:
|
|
response = requests.get(url, headers=headers)
|
|
response_data = response.json()
|
|
if response_data['status']:
|
|
if response_data['data']['status'] == 'success':
|
|
cart = _get_cart(request)
|
|
order = Order.objects.create(user=request.user, is_paid=True)
|
|
for item in cart.items.all():
|
|
OrderItem.objects.create(order=order, product=item.product, quantity=item.quantity)
|
|
cart.items.all().delete()
|
|
# clear the payment reference from the session
|
|
if 'payment_ref' in request.session:
|
|
del request.session['payment_ref']
|
|
return render(request, 'core/payment_success.html', {'order': order})
|
|
else:
|
|
return render(request, 'core/payment_failure.html')
|
|
else:
|
|
return render(request, 'core/payment_failure.html')
|
|
except requests.exceptions.RequestException as e:
|
|
return render(request, 'core/payment_failure.html', {'error': f"An error occurred: {e}"}) |