Yacine Rouizi
Yacine Rouizi

Reputation: 1460

Stripe's webhook with django says: stripe.error.SignatureVerificationError

I use the same code as in the stripe tutorial:

def webhook(request):
    payload = request.body
    sig_header = request.META['HTTP_STRIPE_SIGNATURE']
    event = None

    try:
        event = stripe.Webhook.construct_event(
            payload, sig_header, endpoint_secret
        )
    except ValueError as e:
        raise(e)
        return HttpResponse(status=400)
    except stripe.error.SignatureVerificationError as e:
        raise(e)
        return HttpResponse(status=400)

    # ...

but when I try to test the webhook with the stripe CLI (stripe trigger payment_intent.created) I have this error:

Internal Server Error: /payment/webhook/
Traceback (most recent call last):
  File "/home/rouizi/django-ecommerce/venv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/home/rouizi/django-ecommerce/venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/rouizi/django-ecommerce/venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/rouizi/django-ecommerce/venv/lib/python3.6/site-packages/django/views/decorators/http.py", line 40, in inner
    return func(request, *args, **kwargs)
  File "/home/rouizi/django-ecommerce/venv/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/rouizi/django-ecommerce/payment/views.py", line 99, in webhook
    raise(e)
  File "/home/rouizi/django-ecommerce/payment/views.py", line 88, in webhook
    payload, sig_header, endpoint_secret
  File "/home/rouizi/django-ecommerce/venv/lib/python3.6/site-packages/stripe/webhook.py", line 23, in construct_event
    WebhookSignature.verify_header(payload, sig_header, secret, tolerance)
  File "/home/rouizi/django-ecommerce/venv/lib/python3.6/site-packages/stripe/webhook.py", line 78, in verify_header
    payload,
stripe.error.SignatureVerificationError: No signatures found matching the expected signature for payload

I tried to decode the payload like this:

payload = request.body.decode('utf-8')

but I still have the same error.

Any ideas where the error may come from ?

Upvotes: 8

Views: 5105

Answers (6)

Xcode
Xcode

Reputation: 11

For anyone who had to go through this similar issues. I followed the following steps to resolve it, Step 1:

payload = request.body.decode('utf-8')

Step 2: The webhook_endpoint_secret provided is not what you're going to use to verify the endpoint, you have to use the signing_secret of the dashboard. I'm still in testing, but i don't know if this is the same for live mode.

Upvotes: 0

sp_omer
sp_omer

Reputation: 331

It turns out, that when creating webhook in test mode it gives you webhook secret same as for the CLI.

You need to use this secret as webhook secret as stated in other comments. enter image description here

Upvotes: 9

Mark Mishyn
Mark Mishyn

Reputation: 4151

For me the issue was resolved by decoding request.data.

payload = request.body.decode('utf-8')

I've just decided to note it as a separate answer, maybe someone missed this line in the question description.

Upvotes: 9

Constantine Kurbatov
Constantine Kurbatov

Reputation: 905

In a test mode and in a live mode — all three keys are different:

# web_app/settings.py
## STRIPE LIVE
STRIPE_ENDPOINT_SECRET = 'whsec_******'
STRIPE_PUBLISHABLE_KEY =  'pk_live_*******'
STRIPE_SECRET_KEY = 'sk_live_******'

Hence, I would suggest you to check if you used the correct ENDPOINT secret that is also different for the Live mode, even if the webhook url is the same as for the Test mode:

enter image description here

Upvotes: 3

zakiakhmad
zakiakhmad

Reputation: 823

In my case, the problem solved after I re-created the endpoint secret.

stripe.error.SignatureVerificationError

The exception, no longer raised. It turned out, that the endpoint secret was set to be expired. So you may double check the endpoint secret.

Upvotes: 0

Nolan H
Nolan H

Reputation: 7459

It's important that you're passing the raw request body into construct_event and that nothing has parsed or modified it earlier in your stack.

An important difference from the example you reference is how the header and body are accessed. You also do not show where your endpoint_secret is coming from. Have you checked to make sure all inputs are what you expect?

If you have, try recreating the signature manually using the steps documented.

Upvotes: 0

Related Questions