parent
027ce2d9bc
commit
8365e548be
@ -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), |
||||||
|
), |
||||||
|
] |
||||||
@ -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 |
||||||
@ -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 %} |
||||||
Loading…
Reference in new issue