DEV Community

Ubaid Ullah
Ubaid Ullah

Posted on Originally published at djangix.com

Verifying Stripe Webhooks in Django, Step by Step

Originally published on the Djangix blog: Verifying Stripe Webhooks in Django, Step by Step

If Stripe cannot reliably tell your Django app what happened to a payment, your app cannot reliably fulfil orders, grant access, or handle failures. Webhooks solve that — but only if you verify them. Your webhook endpoint is a public URL, so anyone who finds it can POST a fake “payment succeeded” event to it. Signature verification is how you prove an event really came from Stripe before you act on it.

Verification depends on the raw request body. Stripe signs the exact bytes it sent, so you must verify using those raw bytes together with your endpoint's signing secret and Stripe's Python library — not a re-serialised version of the data. If the signature does not match, reject the request and do not process the event.

Three pitfalls cause most failures. First, using the parsed JSON body instead of the raw bytes, which changes the payload and breaks the signature check. Second, using the wrong signing secret in production — each endpoint and environment has its own secret. Third, not returning a 200 response fast: do the verification and minimal handling quickly, and move slow work to a background task so Stripe does not time out and retry unnecessarily.

Full step-by-step version with complete code: Verifying Stripe Webhooks in Django, Step by Step

Top comments (0)