#mindfulrecruitai
1 messages · Page 1 of 1 (latest)
You may need to exempt your webhook route from CSRF, yes: https://docs.stripe.com/webhooks#csrf-protection
I am getting a 403 response from the webhook even though I have csrf_exempt decorator on the webhook
[13/Feb/2024 18:53:35] "POST / HTTP/1.1" 403 2870
Can you review any server logs for that response? Is your endpoint publicly accessible and can accept POST requests?
I'm using ngrok to tunnel
it's a local development server
I see the "POST / HTTP/1.1" 403 2870 response in my terminal
the response on the Stripe developer page for the webhook mentions csrf
<div id="summary">
<h1>Forbidden <span>(403)</span></h1>
<p>CSRF verification failed. Request aborted.</p>
<p>You are seeing this message because this site requires a CSRF cookie when submitting forms. This cookie is required for security reasons, to ensure that your browser is not being hijacked by third parties.</p>
<p>If you have configured your browser to disable cookies, please re-enable them, at least for this site, or for “same-origin” requests.</p>
</div>
<div id="info">
<h2>Help</h2>
<p>Reason given for failure:</p>
<pre>
CSRF cookie not set.
</pre>
Right, so your server is returning that response to Stripe. Can you share your code for how you're exempting these kinds of requests from CSRF?
@csrf_exempt
def stripe_webhook(request):
payload = request.body
sig_header = request.META['HTTP_STRIPE_SIGNATURE']
event = None
try:
event = stripe.Webhook.construct_event(
payload, sig_header, settings.STRIPE_WEBHOOK_SECRET
)
except ValueError as e:
# Invalid payload
return HttpResponse(status=400)
except stripe.error.SignatureVerificationError as e:
# Invalid signature
return HttpResponse(status=400)
This looks like it might be a Django configuration issue.
Can you try looking at your view function and see if adding csrf_protect helps? https://stackoverflow.com/questions/42118431/forbidden-403-csrf-verification-failed-request-aborted-using-django
I replaced csrf_exempt with csrf_protect on the webhook function but that didn't help
Hi 👋
I'm stepping in because I use Django in my own integration.
It looks like you are following the code snippet we provide here: https://docs.stripe.com/webhooks#example-endpoint
yes that's correct
This should work. This is what I have running
@csrf_exempt
def webhook2(request):
endpoint_secret = settings.STRIPE_ENDPOINT_SECRET
payload = request.body # Need to get the raw body, not json()
# Validating webhook payload vai Stripe signature
sig_header = request.headers.get('Stripe-Signature', None)
try:
event = stripe.Webhook.construct_event(
payload, sig_header, endpoint_secret
)
You are using ngrok to tunnel to your local dev environment, you said.
What happens if you use stripe listen to forward the events to your local machine?
I ran stripe listen in the cli
I see this in the cli:
checkout.session.completed
[evt_1OjWWhHih0ZoNuRgqPWDkXpT]
There should be more to the line than that
Specifically you should also get an HTTP status code
In the line underneath the event notification
I don't see that in the cli
For instance I always have stripe listen running on my machine and the latest events shows the following line
<-- [200] POST http://localhost:8000/webhook2/ [evt_3OjRbpIlCeH6bP8R1FZ1G05V]
You have to leave it running.
but when I look in the webhook attempts log it says that the attempt failed
what is the full command you are running in the terminal and do you leave it running?
Okay well that won't work. It needs to be in a terminal window on your local dev machine
ahh okay
The point is to forward the events via Stripe's own tunnel to your local machine
sorry I'm a mechanical engineer by profession
No worries! Webhooks are a confusing topic for everyone
i'll run it in a new terminal then on my machine
The speific command is stripe listen --forward-to http://localhost:[port]/[route]
ahh okay thank you so much
I'm now seeing this in the terminal:
2024-02-13 19:55:33 --> customer.subscription.deleted [evt_1OjWl8Hih0ZoNuRg0ifLLeKo]
2024-02-13 19:55:33 [ERROR] Failed to POST: Post "http://localhost:4242/stripe_webhooks": dial tcp [::1]:4242: connect: connection refused
Okay. Hmmm...
So you are not even making a connection with your Django server. Is it possible you need to add a trailing slash to the URL?
this is my url for the webhook
path('webhooks/stripe/', views.stripe_webhook, name='stripe_webhook'),
I just tried a new checkout session and get this in terminal:
2024-02-13 19:58:17 --> checkout.session.completed [evt_1OjWnmHih0ZoNuRgtd1DOVWD]
2024-02-13 19:58:17 --> invoice.finalized [evt_1OjWnlHih0ZoNuRgJfqCiqn7]
2024-02-13 19:58:17 [ERROR] Failed to POST: Post "http://localhost:4242/stripe_webhooks": dial tcp [::1]:4242: connect: connection refused
2024-02-13 19:58:17 [ERROR] Failed to POST: Post "http://localhost:4242/stripe_webhooks": dial tcp [::1]:4242: connect: connection refused
Yeah the url you are providing is not being connected to by the CLI.
Can you try adding a simple response at the top of the function to test the URL in your browser?
Like this:
@csrf_exempt
def stripe_webhook(request):
return JsonResponse({"foo": "bar"})
Then attempt to navigate to the URL you are using? To verify it maps correctly
yes let me try
just to confirm should my port be 4242? for the stripe listen --forward-to http://localhost:[port]/[route] terminal command?
I go to http://127.0.0.1:8000/subscribe/
to subscribe a user
Hi @tulip sable I"m taking over this thread
sounds good
Is your local webhook endpoint currently running at port 4242?
how can I check?
You might want to check you django app configuration and see what port it is running in;
I'm using port 8000
that's default for django
2024-02-13 20:17:18 --> invoice.payment_succeeded [evt_1OjX6BHih0ZoNuRgnSZ8rAn2]
2024-02-13 20:17:18 <-- [200] POST http://localhost:8000/stripe_webhooks [evt_1OjX6AHih0ZoNuRg3JrT9WhK]
2024-02-13 20:17:18 <-- [200] POST http://localhost:8000/stripe_webhooks [evt_1OjX6BHih0ZoNuRgnSZ8rAn2]
2024-02-13 20:17:18 --> checkout.session.completed [evt_1OjX6BHih0ZoNuRgPSZrtdSW]
2024-02-13 20:17:19 <-- [500] POST http://localhost:8000/stripe_webhooks [evt_1OjX6BHih0ZoNuRgPSZrtdSW]
this is what I now get in the terminal
Ok, then you should run stripe listen --forward-to http://localhost:8000/stripe_webhooks