# Stripe webhooks on Flask

Flask does not parse the body unless you ask, which makes this the simplest framework on the list. The trap is habit: calling `request.json` or `request.get_json()` anywhere before verification. Use `request.get_data()`.

## The setup

```
from flask import Flask, request, abort
import stripe
import os

app = Flask(__name__)
SIGNING_VALUE = os.environ['STRIPE_WEBHOOK_SIGNING_VALUE']


@app.route('/webhooks/stripe', methods=['POST'])
def stripe_webhook():
    payload = request.get_data()
    sig = request.headers.get('Stripe-Signature')
    try:
        event = stripe.Webhook.construct_event(payload, sig, SIGNING_VALUE)
    except (ValueError, stripe.error.SignatureVerificationError):
        abort(400, 'bad signature')
    # switch on event['type'] ...
    return {'received': True}, 200
```

## Notes

- `request.get_data()` returns the raw bytes; pass them straight through.
- Do not call `request.get_json()` first, even for logging. Once parsed, the byte match is gone.
- Behind a proxy, make sure the proxy forwards the body untouched (no compression transforms on the webhook path).