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

Viewed 2044

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 ?

5 Answers

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

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.

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

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.

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.

Related