#vaniapsk_webhooks-signature

1 messages ยท Page 1 of 1 (latest)

placid crescentBOT
#

๐Ÿ‘‹ Welcome to your new thread!

โฒ๏ธ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.

โฑ๏ธ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.

๐Ÿ”— This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1230292289864208456

๐Ÿ“ Have more to share? Add more details, code, screenshots, videos, etc. below.

slate shadowBOT
cosmic steppe
#

This is my endpoint:

@rvme.lib.decorators.route(
'/stripe/webhook',
methods=['POST'],
form_data=False,
auth=False
)
def webhook():
event = None
payload = request.data
sig_header = request.headers['STRIPE_SIGNATURE']

try:
    event = stripe.Webhook.construct_event(
        payload, sig_header, endpoint_secret
    )
    print('type', event['type'])
except ValueError as e:
    # Invalid payload
    print('Error parsing payload: {}'.format(str(e)))
    raise BadRequestError('Error parsing payload: {}'.format(str(e)))
except stripe.error.SignatureVerificationError as e:
    # Invalid signature
    print('Error verifying webhook signature: {}'.format(str(e)))
    raise BadRequestError('Error verifying webhook signature: {}'.format(str(e)))

...

#

This is the code to generate the header:

def generate_header(**kwargs):
timestamp = kwargs.get("timestamp", int(time.time()))
payload = kwargs.get("payload", DUMMY_WEBHOOK_PAYLOAD)
secret = kwargs.get("secret", DUMMY_WEBHOOK_SECRET)
scheme = kwargs.get("scheme", stripe.WebhookSignature.EXPECTED_SCHEME)
signature = kwargs.get("signature", None)
if signature is None:
payload_to_sign = "%d.%s" % (timestamp, payload)
signature = stripe.WebhookSignature._compute_signature(
payload_to_sign, secret
)
header = "t=%d,%s=%s" % (timestamp, scheme, signature)

result = stripe.WebhookSignature.verify_header(
    payload, header, DUMMY_WEBHOOK_SECRET
)  # returns true

try:
    event = stripe.Webhook.construct_event(
        payload, header, DUMMY_WEBHOOK_SECRET
    )
    print('event', event)  # event return the desired info
except Exception as e:
    print(e)

print('result', result)

return header
#

And this is the test request that is failing:
self.assert_request(
url='/stripe/webhook',
method='POST',
data=DUMMY_WEBHOOK_PAYLOAD,
headers={'Stripe-Signature': header},
assert_status=200,
auth=False
)

It returns a 400 instead: {"status_code": 400, "data": "Error verifying webhook signature: No signatures found matching the expected signature for payload"}

misty wraith
#

๐Ÿ‘‹ sorry that's a ton of code and I'm still barely understanding the issue right now. In the majority of cases, the "no signature" issue is because you are not passing the same exact payload that Stripe sent you.
You mentioned using "bytes" instead of a "literal string" which could be the issue.

I also don't really get what you're trying to do with unit tests and verifying this and why you need that

#

vaniapsk_webhooks-signature

cosmic steppe
#

Sorry about that.

I am implementing webhooks on my application, so in the case there is an error with a payout, then I can perform an action (like sending a user notification).

#

Out backend has a very good coverage, and I need to create tests that will ensure the actions are being performed, case there's a error with a payout.

#

I am open to other ideas on how I can implement the tests and get around the verification.

misty wraith
#

Hmmm so your ask is really how to avoid calling construct_event() to not verify the signature? Or something else?

cosmic steppe
#

Well, I just need to pass that. I don't realy want to avoid callid the contruct_event becas that is needed in the app

misty wraith
#

But it's not for your unit tests right? What you really want is the deserialized JSON into an Event object?

cosmic steppe
#

This is for my unit tests.
My manual tests through Stripe CLI works with no problem

misty wraith
#

yeah sorry I think we're saying different things. My recommendation is to skip signature verification entirely in that case and test the rest of your code after the Event is deserialized

cosmic steppe
#

I understand. Thanks

misty wraith
#

Sure, let me know if that doesn't work for you though

slate shadowBOT