shop
Raz 8 months ago
parent 027ce2d9bc
commit 8365e548be
  1. 6
      padelclub_backend/settings.py
  2. 28
      shop/migrations/0012_order_payment_status_and_more.py
  3. 7
      shop/models.py
  4. 47
      shop/stripe_utils.py
  5. 168
      shop/templates/shop/cart.html
  6. 87
      shop/templates/shop/payment.html
  7. 20
      shop/templates/shop/payment_cancel.html
  8. 31
      shop/templates/shop/payment_success.html
  9. 7
      shop/urls.py
  10. 280
      shop/views.py
  11. 2
      tournaments/urls.py

@ -156,5 +156,11 @@ AUTHENTICATION_BACKENDS = [
CSRF_COOKIE_SECURE = True # if using HTTPS
# Stripe Settings
STRIPE_PUBLISHABLE_KEY = 'pk_test_51R4LrTPEZkECCx484C2KbmRpcO2ZkZb0NoNi8QJB4X3E5JFu3bvLk4JZQmz9grKbk6O40z3xI8DawHrGyUY0fOT600VEKC9ran' # Replace with your actual key
STRIPE_SECRET_KEY = 'sk_test_51R4LrTPEZkECCx48PkSbEYarhts7J7XNYpS1mJgows5z5dcv38l0G2tImvhXCjzvMgUH9ML0vLMOEPeyUBtYVf5H00Qvz8t3rE' # Replace with your actual key
STRIPE_WEBHOOK_SECRET = 'your_webhook_secret' # Optional for later
STRIPE_CURRENCY = 'eur' # Set to your preferred currency
from .settings_local import *
from .settings_app import *

@ -0,0 +1,28 @@
# Generated by Django 4.2.11 on 2025-03-19 12:45
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('shop', '0011_order_guest_user'),
]
operations = [
migrations.AddField(
model_name='order',
name='payment_status',
field=models.CharField(choices=[('UNPAID', 'Unpaid'), ('PAID', 'Paid'), ('FAILED', 'Failed')], default='UNPAID', max_length=20),
),
migrations.AddField(
model_name='order',
name='stripe_checkout_session_id',
field=models.CharField(blank=True, max_length=255, null=True),
),
migrations.AddField(
model_name='order',
name='stripe_payment_intent_id',
field=models.CharField(blank=True, max_length=255, null=True),
),
]

@ -86,6 +86,13 @@ class Order(models.Model):
status = models.CharField(max_length=20, choices=OrderStatus.choices, default=OrderStatus.PENDING)
total_price = models.DecimalField(max_digits=10, decimal_places=2, default=0.00)
guest_user = models.ForeignKey(GuestUser, on_delete=models.CASCADE, null=True, blank=True)
stripe_payment_intent_id = models.CharField(max_length=255, blank=True, null=True)
stripe_checkout_session_id = models.CharField(max_length=255, blank=True, null=True)
payment_status = models.CharField(max_length=20, default='UNPAID', choices=[
('UNPAID', 'Unpaid'),
('PAID', 'Paid'),
('FAILED', 'Failed'),
])
def __str__(self):
return f"Order #{self.id} - {self.status}"

@ -0,0 +1,47 @@
import stripe
from django.conf import settings
# Configure Stripe with your secret key
stripe.api_key = settings.STRIPE_SECRET_KEY
def create_payment_intent(amount, currency=settings.STRIPE_CURRENCY, metadata=None):
"""
Create a payment intent with Stripe
Args:
amount: Amount in cents (e.g., 1000 for 10.00)
currency: Currency code (default: settings.STRIPE_CURRENCY)
metadata: Additional info to attach to the payment intent
Returns:
The created payment intent object
"""
intent = stripe.PaymentIntent.create(
amount=amount,
currency=currency,
metadata=metadata or {},
)
return intent
def create_checkout_session(line_items, success_url, cancel_url, metadata=None):
"""
Create a Stripe Checkout Session for one-time payments
Args:
line_items: List of items to purchase
success_url: URL to redirect on successful payment
cancel_url: URL to redirect on canceled payment
metadata: Additional info to attach to the session
Returns:
The created checkout session
"""
session = stripe.checkout.Session.create(
payment_method_types=['card'],
line_items=line_items,
mode='payment',
success_url=success_url,
cancel_url=cancel_url,
metadata=metadata or {},
)
return session

@ -7,62 +7,130 @@
{% block content %}
<nav class="margin10">
<a href="{% url 'shop:product_list' %}">La Boutique</a>
<a href="{% url 'index' %}" class="orange">Accueil</a>
<a href="{% url 'clubs' %}" class="orange">Clubs</a>
{% if user.is_authenticated %}
<a href="{% url 'my-tournaments' %}" class="orange">Mes tournois</a>
<a href="{% url 'profile' %}">Mon compte</a>
{% else %}
<a href="{% url 'login' %}">Se connecter</a>
{% endif %}
<a href="{% url 'shop:product_list' %}">La Boutique</a>
<a href="{% url 'index' %}" class="orange">Accueil</a>
<a href="{% url 'clubs' %}" class="orange">Clubs</a>
{% if user.is_authenticated %}
<a href="{% url 'my-tournaments' %}" class="orange">Mes tournois</a>
<a href="{% url 'profile' %}">Mon compte</a>
{% else %}
<a href="{% url 'login' %}">Se connecter</a>
{% endif %}
</nav>
<div class="grid-x">
<div class="cell medium-6 large-6 my-block">
<h1 class="club my-block topmargin20">Votre panier</h1>
<div class="bubble">
{% if cart_items %}
<table class="cart-table">
<thead>
<tr>
<th>Produit</th>
<th>Couleur</th>
<th>Taille</th>
<th>Quantité</th>
<th class="price-column">Prix</th>
</tr>
</thead>
<tbody>
{% for item in cart_items %}
<tr class="{% cycle 'odd' 'even' %}">
<td>{{ item.product.title }}</td>
<td>{{ item.color.name }}</td>
<td>{{ item.size.name }}</td>
<td>{{ item.quantity }}</td>
<td class="price-column">{{ item.get_total_price }} €</td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<td colspan="3" class="total-label">Total:</td>
<td class="total-quantity">{{ cart_items.total_quantity }}</td>
<td class="price-column total-price">{{ total }} €</td>
</tr>
</tfoot>
</table>
<div class="cart-summary">
{% if cart_items %}
<a class="cancel-nav-button" href="{% url 'shop:clear_cart' %}">Vider le panier</a>
{% endif %}
<div class="cell medium-6 large-6 my-block">
<h1 class="club my-block topmargin20">Votre panier</h1>
<div class="bubble">
{% if cart_items %}
<table class="cart-table">
<thead>
<tr>
<th>Produit</th>
<th>Couleur</th>
<th>Taille</th>
<th>Quantité</th>
<th class="price-column">Prix</th>
</tr>
</thead>
<tbody>
{% for item in cart_items %}
<tr class="{% cycle 'odd' 'even' %}">
<td>{{ item.product.title }}</td>
<td>{{ item.color.name }}</td>
<td>{{ item.size.name }}</td>
<td>{{ item.quantity }}</td>
<td class="price-column">{{ item.get_total_price }} €</td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<td colspan="3" class="total-label">Total:</td>
<td class="total-quantity">{{ cart_items.total_quantity }}</td>
<td class="price-column total-price">{{ total }} €</td>
</tr>
</tfoot>
</table>
<a class="confirm-nav-button" href="{% url 'shop:checkout' %}">Passer la commande</a>
<div class="cart-summary">
{% if cart_items %}
<a class="cancel-nav-button" href="{% url 'shop:clear_cart' %}">Vider le panier</a>
{% endif %}
</div>
{% if user.is_authenticated %}
<!-- For authenticated users: Direct Stripe payment button -->
<button id="checkout-button" class="confirm-nav-button">Procéder au paiement</button>
{% else %}
<p>Votre panier est vide.</p>
<!-- For guest users: Regular checkout path -->
<a class="confirm-nav-button" href="{% url 'shop:checkout' %}">Passer la commande</a>
<div class="guest-checkout-notice">
<p>Connectez-vous pour un paiement plus rapide.</p>
<a href="{% url 'login' %}?next={% url 'shop:view_cart' %}">Se connecter</a>
</div>
{% endif %}
</div>
{% else %}
<p>Votre panier est vide.</p>
{% endif %}
</div>
</div>
</div>
{% if user.is_authenticated and cart_items %}
<!-- Stripe JavaScript for authenticated users -->
<script src="https://js.stripe.com/v3/"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
const checkoutButton = document.getElementById('checkout-button');
checkoutButton.addEventListener('click', function() {
// Show a loading indicator
checkoutButton.textContent = 'Chargement...';
checkoutButton.disabled = true;
// Create order and get checkout session
fetch('{% url "shop:create_checkout_session" %}', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': '{{ csrf_token }}'
},
credentials: 'same-origin',
})
.then(function(response) {
return response.json();
})
.then(function(session) {
if (session.error) {
// Handle error
alert(session.error);
checkoutButton.textContent = 'Procéder au paiement';
checkoutButton.disabled = false;
return;
}
// Initialize Stripe
const stripe = Stripe('{{ stripe_publishable_key }}');
// Redirect to Stripe Checkout
return stripe.redirectToCheckout({ sessionId: session.id });
})
.then(function(result) {
// If redirectToCheckout fails
if (result && result.error) {
alert(result.error.message);
checkoutButton.textContent = 'Procéder au paiement';
checkoutButton.disabled = false;
}
})
.catch(function(error) {
console.error('Error:', error);
alert('Une erreur est survenue. Veuillez réessayer.');
checkoutButton.textContent = 'Procéder au paiement';
checkoutButton.disabled = false;
});
});
});
</script>
{% endif %}
{% endblock %}

@ -0,0 +1,87 @@
{% extends 'tournaments/base.html' %}
{% block head_title %}Paiement{% endblock %}
{% block first_title %}La boutique Padel Club{% endblock %}
{% block second_title %}Paiement{% endblock %}
{% block content %}
<nav class="margin10">
<a href="{% url 'shop:product_list' %}">La Boutique</a>
<a href="{% url 'index' %}" class="orange">Accueil</a>
<a href="{% url 'clubs' %}" class="orange">Clubs</a>
{% if user.is_authenticated %}
<a href="{% url 'my-tournaments' %}" class="orange">Mes tournois</a>
<a href="{% url 'profile' %}">Mon compte</a>
{% else %}
<a href="{% url 'login' %}">Se connecter</a>
{% endif %}
</nav>
<div class="grid-x">
<div class="cell medium-6 large-6 my-block">
<h1 class="club my-block topmargin20">Paiement</h1>
<div class="bubble">
<h2>Résumé de votre commande</h2>
<!-- Display order items in a table -->
<table class="cart-table">
<thead>
<tr>
<th>Produit</th>
<th>Couleur</th>
<th>Taille</th>
<th>Quantité</th>
<th class="price-column">Prix</th>
</tr>
</thead>
<tbody>
{% for item in order_items %}
<tr class="{% cycle 'odd' 'even' %}">
<td>{{ item.product.title }}</td>
<td>{{ item.color.name|default:"N/A" }}</td>
<td>{{ item.size.name|default:"N/A" }}</td>
<td>{{ item.quantity }}</td>
<td class="price-column">{{ item.get_total_price }} €</td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<td colspan="3" class="total-label">Total:</td>
<td class="total-quantity">{{ order_items.count }}</td>
<td class="price-column total-price">{{ order.total_price }} €</td>
</tr>
</tfoot>
</table>
<!-- Stripe checkout button -->
<div id="payment-container">
<button id="checkout-button" class="confirm-nav-button">Procéder au paiement</button>
</div>
</div>
</div>
</div>
<!-- Stripe JavaScript -->
<script src="https://js.stripe.com/v3/"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Initialize Stripe
const stripe = Stripe('{{ stripe_publishable_key }}');
const checkoutButton = document.getElementById('checkout-button');
checkoutButton.addEventListener('click', function() {
// Redirect to Stripe Checkout
stripe.redirectToCheckout({
sessionId: '{{ checkout_session_id }}'
}).then(function(result) {
// If `redirectToCheckout` fails due to a browser or network
// error, display the localized error message to your customer
if (result.error) {
alert(result.error.message);
}
});
});
});
</script>
{% endblock %}

@ -0,0 +1,20 @@
<!-- padelclub_backend/shop/templates/shop/payment_cancel.html -->
{% extends 'tournaments/base.html' %}
{% block head_title %}Paiement annulé{% endblock %}
{% block content %}
<div class="grid-x">
<div class="cell medium-6 large-6 my-block">
<h1 class="club my-block topmargin20">Paiement annulé</h1>
<div class="bubble">
<h2>Le paiement a été annulé</h2>
<p>Votre commande n'a pas été finalisée car le paiement a été annulé.</p>
<div class="cart-summary">
<a class="confirm-nav-button" href="{% url 'shop:view_cart' %}">Retour au panier</a>
</div>
</div>
</div>
</div>
{% endblock %}

@ -1,11 +1,10 @@
{% extends 'tournaments/base.html' %}
{% block head_title %}Confirmation de commande{% endblock %}
{% block first_title %}Confirmation de commande{% endblock %}
{% block second_title %}Merci pour votre commande !{% endblock %}
{% block head_title %}Paiement réussi{% endblock %}
{% block first_title %}La boutique Padel Club{% endblock %}
{% block second_title %}Paiement réussi{% endblock %}
{% block content %}
<nav class="margin10">
<a href="{% url 'shop:product_list' %}">La Boutique</a>
<a href="{% url 'index' %}" class="orange">Accueil</a>
@ -17,11 +16,17 @@
<a href="{% url 'login' %}">Se connecter</a>
{% endif %}
</nav>
<div class="grid-x">
<div class="cell medium-6 large-6 my-block">
<h1 class="club my-block topmargin20">Détails de la commande</h1>
<h1 class="club my-block topmargin20">Paiement réussi</h1>
<div class="bubble">
{% if order_items %}
<h2>Merci pour votre commande !</h2>
<p>Votre paiement a été traité avec succès.</p>
<p>Numéro de commande: {{ order.id }}</p>
<!-- Order details -->
<h3>Détails de la commande</h3>
<table class="cart-table">
<thead>
<tr>
@ -36,8 +41,8 @@
{% for item in order_items %}
<tr class="{% cycle 'odd' 'even' %}">
<td>{{ item.product.title }}</td>
<td>{{ item.color.name }}</td>
<td>{{ item.size.name }}</td>
<td>{{ item.color.name|default:"N/A" }}</td>
<td>{{ item.size.name|default:"N/A" }}</td>
<td>{{ item.quantity }}</td>
<td class="price-column">{{ item.get_total_price }} €</td>
</tr>
@ -46,19 +51,15 @@
<tfoot>
<tr>
<td colspan="3" class="total-label">Total:</td>
<td class="total-quantity">{{ order_items.total_quantity }}</td>
<td class="total-quantity">{{ order_items.count }}</td>
<td class="price-column total-price">{{ total }} €</td>
</tr>
</tfoot>
</table>
<div class="order-summary">
<p>Votre commande a été passée avec succès !</p>
<a class="back-to-shop-button" href="{% url 'shop:product_list' %}">Retour à la boutique</a>
<div class="cart-summary">
<a class="confirm-nav-button" href="{% url 'shop:product_list' %}">Retour à la boutique</a>
</div>
{% else %}
<p>Aucun élément dans la commande.</p>
{% endif %}
</div>
</div>
</div>

@ -13,5 +13,10 @@ urlpatterns = [
path('cart/remove/<int:product_id>/', views.remove_from_cart_view, name='remove_from_cart'),
path('clear-cart/', views.clear_cart, name='clear_cart'),
path('checkout/', views.checkout, name='checkout'),
path('order/<int:order_id>/confirmation/', views.order_confirmation, name='order_confirmation'),
path('payment/<int:order_id>/', views.payment, name='payment'),
path('payment/success/<int:order_id>/', views.payment_success, name='payment_success'),
path('payment/cancel/<int:order_id>/', views.payment_cancel, name='payment_cancel'),
# path('webhook/stripe/', views.stripe_webhook, name='stripe_webhook'),
path('create-checkout-session/', views.create_checkout_session, name='create_checkout_session'),
]

@ -1,15 +1,86 @@
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from .models import Product, Order, OrderItem, GuestUser
from .models import Product, Order, OrderItem, GuestUser, OrderStatus
from django.db.models import Sum
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import login
from django.contrib.auth.decorators import login_required
from .forms import GuestCheckoutForm
import stripe
from django.conf import settings
from django.urls import reverse
from django.http import JsonResponse
from django.views.decorators.http import require_POST
from . import cart
# Create your views here.
# Shared helper methods
def _check_stripe_config():
"""Check if Stripe API keys are properly configured"""
return hasattr(settings, 'STRIPE_SECRET_KEY') and settings.STRIPE_SECRET_KEY
def _create_stripe_line_items(order_items):
"""Create line items for Stripe checkout from order items"""
line_items = []
for item in order_items:
item_price = int(float(item.price) * 100) # Convert to cents
line_items.append({
'price_data': {
'currency': 'eur',
'product_data': {
'name': item.product.title,
'description': f"Color: {item.color.name if item.color else 'N/A'}, Size: {item.size.name if item.size else 'N/A'}",
},
'unit_amount': item_price,
},
'quantity': item.quantity,
})
return line_items
def _create_stripe_checkout_session(request, order, line_items):
"""Create a Stripe checkout session for the order"""
# Create success and cancel URLs
success_url = request.build_absolute_uri(reverse('shop:payment_success', args=[order.id]))
cancel_url = request.build_absolute_uri(reverse('shop:payment_cancel', args=[order.id]))
# Create metadata to identify this order
metadata = {
'order_id': order.id,
}
# Add user info to metadata if available
if request.user.is_authenticated:
metadata['user_id'] = request.user.id
elif 'guest_email' in request.session:
metadata['guest_email'] = request.session.get('guest_email', '')
try:
# Initialize Stripe with your secret key
stripe.api_key = settings.STRIPE_SECRET_KEY
# Create session
checkout_session = stripe.checkout.Session.create(
payment_method_types=['card'],
line_items=line_items,
mode='payment',
success_url=success_url,
cancel_url=cancel_url,
metadata=metadata,
)
# Save the checkout session ID to the order
order.stripe_checkout_session_id = checkout_session.id
order.save()
return checkout_session
except Exception as e:
# Log error and re-raise
print(f"Stripe error: {str(e)}")
raise
# View functions
def product_list(request):
products = Product.objects.all()
cart_items = cart.get_cart_items(request)
@ -25,11 +96,18 @@ def view_cart(request):
cart_items = cart.get_cart_items(request)
total = cart.get_cart_total(request)
total_quantity = cart_items.aggregate(total_quantity=Sum('quantity'))['total_quantity']
return render(request, 'shop/cart.html', {
context = {
'cart_items': cart_items,
'total': total,
'total_quantity': total_quantity
})
'total_quantity': total_quantity,
}
# Add Stripe publishable key for authenticated users
if request.user.is_authenticated:
context['stripe_publishable_key'] = settings.STRIPE_PUBLISHABLE_KEY
return render(request, 'shop/cart.html', context)
def add_to_cart_view(request, product_id):
"""Add a product to the cart"""
@ -62,17 +140,27 @@ def clear_cart(request):
return redirect('shop:product_list')
def create_order(request):
"""Create an order from the current cart"""
cart_items = cart.get_cart_items(request)
# Check if cart is empty
if not cart_items.exists():
return None
total_price = sum(item.get_total_price() for item in cart_items)
# Check if total price is valid
if total_price <= 0:
return None
if request.user.is_authenticated:
# L'utilisateur est authentifié, créer la commande avec l'utilisateur
# Authenticated user order
order = Order.objects.create(
user=request.user,
total_price=total_price
)
else:
# L'utilisateur n'est pas authentifié, créer la commande avec l'utilisateur invité
# Guest user order
try:
guest_user = GuestUser.objects.get(email=request.session['guest_email'])
order = Order.objects.create(
@ -80,12 +168,12 @@ def create_order(request):
total_price=total_price
)
except (KeyError, GuestUser.DoesNotExist):
# Si l'utilisateur invité n'existe pas, créer une commande sans utilisateur
# No guest user information, create order without user
order = Order.objects.create(
total_price=total_price
)
# Create order items
for cart_item in cart_items:
OrderItem.objects.create(
order=order,
@ -96,53 +184,163 @@ def create_order(request):
price=cart_item.product.price
)
# Clear the cart after creating the order
cart.clear_cart(request)
# Note: Cart is not cleared here, only after successful payment
return order
def order_confirmation(request, order_id):
def checkout(request):
"""Handle checkout process for both authenticated and guest users"""
# Check if cart is empty
cart_items = cart.get_cart_items(request)
if not cart_items.exists():
messages.error(request, "Your cart is empty. Please add items before checkout.")
return redirect('shop:product_list')
if request.user.is_authenticated:
# Create order for authenticated user and go directly to payment
return _handle_authenticated_checkout(request)
# Handle guest checkout
if request.method == 'GET':
form = GuestCheckoutForm()
return render(request, 'shop/checkout.html', {'form': form})
elif request.method == 'POST':
return _handle_guest_checkout_post(request)
return redirect('shop:product_list')
def _handle_authenticated_checkout(request):
"""Helper function to handle checkout for authenticated users"""
order = create_order(request)
if not order:
messages.error(request, "There was an issue creating your order. Please try again.")
return redirect('shop:view_cart')
return redirect('shop:payment', order_id=order.id)
def _handle_guest_checkout_post(request):
"""Helper function to handle POST requests for guest checkout"""
form = GuestCheckoutForm(request.POST)
if form.is_valid():
# Create or get guest user
email = form.cleaned_data['email']
phone = form.cleaned_data['phone']
guest_user, created = GuestUser.objects.get_or_create(
email=email,
defaults={'phone': phone}
)
# Store email in session
request.session['guest_email'] = email
# Create order
order = create_order(request)
if not order:
messages.error(request, "There was an issue creating your order. Please try again.")
return redirect('shop:view_cart')
return redirect('shop:payment', order_id=order.id)
# Form invalid
return render(request, 'shop/checkout.html', {'form': form})
def payment(request, order_id):
"""Handle payment for an existing order"""
order = get_object_or_404(Order, id=order_id)
order_items = order.items.all()
# Check for valid order
if not order_items.exists() or order.total_price <= 0:
messages.error(request, "Cannot process an empty order.")
return redirect('shop:product_list')
# Log payment processing
print(f"Processing payment for order #{order_id}, total: {order.total_price}")
# Check Stripe configuration
if not _check_stripe_config():
messages.error(request, "Stripe API keys not configured properly.")
return redirect('shop:view_cart')
# Create line items
line_items = _create_stripe_line_items(order_items)
if not line_items:
messages.error(request, "Cannot create payment with no items.")
return redirect('shop:view_cart')
# Create checkout session
try:
checkout_session = _create_stripe_checkout_session(request, order, line_items)
checkout_session_id = checkout_session.id
except Exception as e:
messages.error(request, f"Payment processing error: {str(e)}")
return redirect('shop:view_cart')
# Render payment page
return render(request, 'shop/payment.html', {
'order': order,
'order_items': order_items,
'checkout_session_id': checkout_session_id,
'stripe_publishable_key': settings.STRIPE_PUBLISHABLE_KEY,
})
def payment_success(request, order_id):
"""Handle successful payment"""
order = get_object_or_404(Order, id=order_id)
# Clear cart after successful payment
cart.clear_cart(request)
# Update order status
order.status = OrderStatus.PAID
order.payment_status = 'PAID'
order.save()
# Get order items for template
order_items = order.items.all()
total = sum(item.get_total_price() for item in order_items)
return render(request, 'shop/order_confirmation.html', {
return render(request, 'shop/payment_success.html', {
'order': order,
'order_items': order_items,
'total': total
})
def checkout(request):
if request.user.is_authenticated:
# Créer la commande pour l'utilisateur authentifié
order = create_order(request)
def payment_cancel(request, order_id):
"""Handle cancelled payment"""
order = get_object_or_404(Order, id=order_id)
# Rediriger vers la confirmation de commande
return redirect('shop:order_confirmation', order.id)
# Update order status
order.status = OrderStatus.CANCELED
order.payment_status = 'FAILED'
order.save()
if request.method == 'GET':
form = GuestCheckoutForm()
return render(request, 'shop/checkout.html', {'form': form})
messages.warning(request, "Your payment was cancelled.")
return render(request, 'shop/payment_cancel.html', {'order': order})
elif request.method == 'POST':
# Gérer la soumission du formulaire ici
form = GuestCheckoutForm(request.POST)
if form.is_valid():
# Créer ou récupérer l'utilisateur invité
email = form.cleaned_data['email']
phone = form.cleaned_data['phone']
guest_user, created = GuestUser.objects.get_or_create(email=email, defaults={'phone': phone})
@require_POST
def create_checkout_session(request):
"""API endpoint to create a Stripe checkout session directly from cart"""
if not request.user.is_authenticated:
return JsonResponse({'error': 'User must be authenticated'}, status=403)
# Stocker l'e-mail de l'utilisateur invité dans la session
request.session['guest_email'] = email
# Create the order
order = create_order(request)
# Simuler le processus de paiement
# ...
if not order:
return JsonResponse({'error': 'Could not create order from cart'}, status=400)
# Créer la commande
order = create_order(request)
# Get order items
order_items = order.items.all()
# Rediriger vers la confirmation de commande
return redirect('shop:order_confirmation', order.id)
# Create line items
line_items = _create_stripe_line_items(order_items)
# Gérer les autres méthodes (par exemple, PUT, DELETE) si nécessaire
return redirect('shop:product_list')
# Create checkout session
try:
checkout_session = _create_stripe_checkout_session(request, order, line_items)
return JsonResponse({'id': checkout_session.id})
except Exception as e:
return JsonResponse({'error': str(e)}, status=400)

@ -77,8 +77,6 @@ urlpatterns = [
path('admin/users-export/', views.UserListExportView.as_view(), name='users_export'),
path('activation-success/', views.activation_success, name='activation_success'),
path('activation-failed/', views.activation_failed, name='activation_failed'),
path('shop/', include('shop.urls')),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Loading…
Cancel
Save