Files
vontor-cz/backend/thirdparty/stripe/views.py
David Bruno Vontor ebab304b75 Add carrier field to Refund model and update Stripe views
Introduces a OneToOneField for carrier in the Refund model to support future integration and refactoring. Adds and updates TODO comments for email template usage, error handling in Stripe webhooks, and clarifies logic placement in Stripe models.
2025-11-21 15:15:47 +01:00

80 lines
2.6 KiB
Python

from django.views.decorators.csrf import csrf_exempt
from django.conf import settings
from django.http import HttpResponse
from rest_framework import generics
from rest_framework.response import Response
from rest_framework.views import APIView
from drf_spectacular.utils import extend_schema
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 StripeWebhook(APIView):
@extend_schema(
tags=["stripe"],
)
def post(self, request):
payload = request.body
sig_header = request.META['HTTP_STRIPE_SIGNATURE']
try:
#build stripe event (api call)
event = stripe.Webhook.construct_event(
payload, sig_header, os.getenv("STRIPE_WEBHOOK_SECRET")
)
except ValueError as e:
# TODO: doupravit error handling, dodělat v modelu možnost pro uložení chyby a status ERROR
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)
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()
logger.info(f"Transaction {stripe_transaction.id} marked as paid.")
else:
logger.warning(f"No transaction found for session ID: {session.id}")
# 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()
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.")