From 7f52d87eb3730eb1be35d20387598ee6df60aa8e Mon Sep 17 00:00:00 2001 From: Nika Alaverdashvili Date: Tue, 29 Oct 2024 17:51:30 +0400 Subject: [PATCH] fix: update stripe webhook for better handling payment status. --- payments/views.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/payments/views.py b/payments/views.py index a6b1b4c..d96906c 100755 --- a/payments/views.py +++ b/payments/views.py @@ -103,32 +103,42 @@ def post(self, request): def stripe_webhook(request): """ Handle Stripe webhook events. + + This view function listens for incoming webhook events from Stripe, verifies + the event signature, and updates the Payment object status based on the event type. + When a `checkout.session.completed` event is received, it retrieves the associated + Payment object using the `stripe_session_id`. If the payment status is "paid", + the Payment object's status is set to `COMPLETED`. If the payment status is "canceled", + the Payment object's status is set to `CANCELED`. + + Returns: + HttpResponse: A response with status 200 for successful processing, + or appropriate error status if there are issues. """ payload = request.body sig_header = request.META.get("HTTP_STRIPE_SIGNATURE") event = None - # Retrieve the Stripe webhook secret directly from the environment endpoint_secret = os.getenv("STRIPE_WEBHOOK_SECRET") try: # Verify the event by Stripe's signature event = stripe.Webhook.construct_event(payload, sig_header, endpoint_secret) except (ValueError, stripe.error.SignatureVerificationError): - # Invalid payload or signature verification failed return HttpResponse(status=400, content="Invalid signature") if event["type"] == "checkout.session.completed": session = event["data"]["object"] - # Retrieve the Payment object and update its status try: payment = Payment.objects.get(stripe_session_id=session["id"]) - payment.status = Payment.Status.COMPLETED + + if session["payment_status"] == "paid": + payment.status = Payment.Status.COMPLETED + elif session["payment_status"] == "canceled": + payment.status = Payment.Status.CANCELED payment.save() except Payment.DoesNotExist: - # Payment object not found return HttpResponse(status=404, content="Payment object not found") - # Return a 200 response to acknowledge receipt of the event return HttpResponse(status=200)