Major refactor of commerce and Stripe integration
Refactored commerce models to support refunds, invoices, and improved carrier/payment logic. Added new serializers and viewsets for products, categories, images, discount codes, and refunds. Introduced Stripe client integration and removed legacy Stripe admin/model code. Updated Dockerfile for PDF generation dependencies. Removed obsolete migration files and updated configuration app initialization. Added invoice template and tasks for order cleanup.
This commit is contained in:
100
backend/thirdparty/stripe/views.py
vendored
100
backend/thirdparty/stripe/views.py
vendored
@@ -6,73 +6,73 @@ from rest_framework import generics
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from drf_spectacular.utils import extend_schema
|
||||
|
||||
from .models import Order
|
||||
from .serializers import OrderSerializer
|
||||
import os
|
||||
import logging
|
||||
|
||||
from .models import StripeTransaction
|
||||
from commerce.models import Order, Payment
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
import stripe
|
||||
stripe.api_key = os.getenv("STRIPE_SECRET_KEY")
|
||||
|
||||
class CreateCheckoutSessionView(APIView):
|
||||
class StripeWebhook(APIView):
|
||||
@extend_schema(
|
||||
tags=["stripe"],
|
||||
)
|
||||
def post(self, request):
|
||||
serializer = OrderSerializer(data=request.data) #obecný serializer
|
||||
serializer.is_valid(raise_exception=True)
|
||||
payload = request.body
|
||||
sig_header = request.META['HTTP_STRIPE_SIGNATURE']
|
||||
|
||||
order = Order.objects.create(
|
||||
amount=serializer.validated_data["amount"],
|
||||
currency=serializer.validated_data.get("currency", "czk"),
|
||||
)
|
||||
try:
|
||||
#build stripe event
|
||||
event = stripe.Webhook.construct_event(
|
||||
payload, sig_header, os.getenv("STRIPE_WEBHOOK_SECRET")
|
||||
)
|
||||
|
||||
# Vytvoření Stripe Checkout Session
|
||||
session = stripe.checkout.Session.create(
|
||||
payment_method_types=["card"],
|
||||
line_items=[{
|
||||
"price_data": {
|
||||
"currency": order.currency,
|
||||
"product_data": {"name": f"Order {order.id}"},
|
||||
"unit_amount": int(order.amount * 100), # v centech
|
||||
},
|
||||
"quantity": 1,
|
||||
}],
|
||||
mode="payment",
|
||||
success_url=request.build_absolute_uri(f"/payment/success/{order.id}"),
|
||||
cancel_url=request.build_absolute_uri(f"/payment/cancel/{order.id}"),
|
||||
)
|
||||
except ValueError as e:
|
||||
logger.error(f"Invalid payload: {e}")
|
||||
return HttpResponse(status=400)
|
||||
|
||||
except stripe.error as e:
|
||||
# stripe error
|
||||
logger.error(f"Stripe error: {e}")
|
||||
return HttpResponse(status=400)
|
||||
|
||||
|
||||
order.stripe_session_id = session.id
|
||||
order.stripe_payment_intent = session.payment_intent
|
||||
order.save()
|
||||
|
||||
data = OrderSerializer(order).data
|
||||
data["checkout_url"] = session.url
|
||||
return Response(data)
|
||||
|
||||
session = event['data']['object']
|
||||
|
||||
|
||||
# ZAPLACENO
|
||||
if event['type'] == 'checkout.session.completed':
|
||||
|
||||
stripe_transaction = StripeTransaction.objects.get(stripe_session_id=session.id)
|
||||
|
||||
if stripe_transaction:
|
||||
stripe_transaction.paid()
|
||||
|
||||
@csrf_exempt
|
||||
def stripe_webhook(request):
|
||||
payload = request.body
|
||||
sig_header = request.META.get("HTTP_STRIPE_SIGNATURE")
|
||||
event = None
|
||||
logger.info(f"Transaction {stripe_transaction.id} marked as paid.")
|
||||
|
||||
try:
|
||||
event = stripe.Webhook.construct_event(
|
||||
payload, sig_header, settings.STRIPE_WEBHOOK_SECRET
|
||||
)
|
||||
except stripe.error.SignatureVerificationError:
|
||||
return HttpResponse(status=400)
|
||||
else:
|
||||
logger.warning(f"No transaction found for session ID: {session.id}")
|
||||
|
||||
if event["type"] == "checkout.session.completed":
|
||||
session = event["data"]["object"]
|
||||
order = Order.objects.filter(stripe_session_id=session.get("id")).first()
|
||||
if order:
|
||||
order.status = "paid"
|
||||
# EXPIRACE (zrušení objednávky) uživatel nezaplatil do 24 hodin!
|
||||
elif event['type'] == 'checkout.session.expired':
|
||||
order = Order.objects.get(payment=Payment.objects.get(stripe=StripeTransaction.objects.get(stripe_session_id=session.id)))
|
||||
order.status = Order.STATUS_CHOICES.CANCELLED
|
||||
order.save()
|
||||
|
||||
return HttpResponse(status=200)
|
||||
elif event['type'] == 'payment_intent.payment_failed':
|
||||
#nothing to do for now
|
||||
pass
|
||||
|
||||
# REFUND POTVRZEN
|
||||
elif event['type'] == 'payment_intent.refunded':
|
||||
session = event['data']['object']
|
||||
stripe_transaction = StripeTransaction.objects.get(stripe_payment_intent=session.id)
|
||||
|
||||
if stripe_transaction:
|
||||
stripe_transaction.refund_confirmed()
|
||||
|
||||
logger.info(f"Transaction {stripe_transaction.id} marked as refunded.")
|
||||
|
||||
Reference in New Issue
Block a user