#n0rlant1s-webhook-signature

1 messages ยท Page 1 of 1 (latest)

visual sageBOT
vernal roost
#

n0rlant1s-webhook-signature

amber oasis
#

This is the first part of my code where this is erroring:

@router.post('/webhook', response_model=Any)
async def webhook_received(
    *,
    db: Session = Depends(deps.get_db),
    request: Request
):
    # Auth: assumes webhook signing is configured.
    # Nominally, Stripe also accepts non-signed webhooks.
    signature = request.headers.get('stripe-signature')
    request_data = await request.json()
    raw_data = await request.body()

    try:
        event = stripe.Webhook.construct_event(payload=raw_data, sig_header=signature, secret=STRIPE_WEBHOOK_KEY)
        data = event['data']
    except Exception as e:
        sentry_sdk.capture_exception(e)
        return Response(status_code=500)

    event_type = event['type']
    data_object = data['object']
vernal roost
#

Hello! There are 2 things that can cause this problem

  1. Using the wrong webhook secret: not realizing that you have a different secret between the Stripe CLI locally and the real endpoint in the Dashboard for example
  2. Not passing the raw body that we give you. This is crucial as the signature verification only works on the exact payload we send you. If you tamper with it (or parts of your framework/code do) then it breaks signature verification
amber oasis
#

My webhook secret begins with whsec_wf -- that's correct right?

#

The raw body I have looks like this:

b'{\n  "id": "evt_1LuI11C5XIuIJMyhD47AGbH1",\n  "object": "event",\n  "api_version": "2020-08-27",\n  "created": 1666108058,\n  "data": {\n    "object": {\n      "id": "ii_1LuI0yC5XIuIJMyh7auqdHkU",\n      "object": "invoiceitem",\n      "amount": -2844,\n      "currency": "usd",\n      "customer": "cus_MFyjhTrMNpJCxa",\n      "date": 1666108056,\n      "description": "Unused time on Starter Plan after 18 Oct 2022",\n      "discountable": false,\n      "discounts": [\n\n      ],\n      "invoice": "in_1LuI0yC5XIuIJMyh9Bntl0zh",\n      "livemode": true,\n      "metadata": {\n      },\n      "period": {\n        "end": 1668734408,\n        "start": 1666108056\n      },\n      "plan": {\n        "id": "price_1LXQv6C5XIuIJMyhCDyk9TIh",\n        "object": "plan",\n        "active": true,\n        "aggregate_usage": null,\n        "amount": 2900,\n        "amount_decimal": "2900",\n        "billing_scheme": "per_unit",\n        "created": 1660660744,\n        "currency": "usd",\n        "interval": "month",\n    ...
```  -- it's expected in bytes right?
#

this is what I'm sending in payload=raw_data

vernal roost
#

yes the webhook secret starts with whsec_xxxx but you need to make sure it's exactly the secret you see in the Dashboard. And if you are certain you have the right one then it's the second issue and that's what you need to debug.
This is unfortunately really painful for developers because it could be "anything" in their stack that tampers with the data. What you can do is compare the raw payload you get between locally and the server

amber oasis
#

That's my confusion: It's all the exact same unfortunately -- but thanks for giving me some pointers ๐Ÿ™‚

vernal roost
#

so you get the same Event id evt_123 on both localhost and your server and the raw payload is exactly the same?

amber oasis
#

An example evt_[...] on my local is evt_1LuIA2C5XIuIJMyhqKbeyLCk, while it is evt_1LuI11C5XIuIJMyhW0dmvqFq on my prod.

#

Both are subscription updates

#

One subtle difference however: Description is null on prod, while non-null on local. Not sure why

#

Nevermind ๐Ÿ™‚ Found one in prod

vernal roost
#

the content of the property is not relevant. But my point is that you'd want to get the exact same Event to compare the raw payload

amber oasis
#

Ok it finally worked, but I didn't change anything significant at all -- just tried it a bunch of times. Also: I have a bunch of payments in prod that I would like to refund (I was testing this in prod) without hurting my payment reputation or for it to be flagged. Should I contact support to do it?

vernal roost
#

So strange that it suddenly worked

#

You should never test in production ever. Card networks don't like that, it's in our terms of services and docs

#

but if you have already, just refund, it won't hurt your reputation, but avoid doing this again

amber oasis
#

Yeah super strange -- I genuinely changed nothing ๐Ÿฅฒ Will remember re: testing in prod. Thank you!