#paulC.webhook-payloads

1 messages ยท Page 1 of 1 (latest)

dense talon
opaque knoll
#

seems like the event is constructed , so a better questoni would be what does the req.body of the constructor req contain ?

#

Thanks so much , will look it up !

dense talon
#

For example, checkout.session.completed event will included the Checkout Session object related to the event

opaque knoll
#

I am asking because the req.body is empty in a webhook test mode , is it normal ?

dense talon
#

Shouldn't be, no. Test event payloads are identical to live ones

#

Assuming this is Node, you'll likely need to parse req.body

opaque knoll
#

Oh.. then could you please help me figure out what I am doing wrong ?

#

I am using app.use(express.urlencoded({extended: true}))

dense talon
opaque knoll
#

Yeah I am following that

#

This is how I am doing

#

const webHookStripe = async (req, res) => {
const sig = req.headers['stripe-signature'];

let event;
try {
    event = stripe.webhooks.constructEvent(req.body, sig, endpointSecret);
}
catch (err) {
    res.status(400).send(`Webhook Error: ${err.message}`);
}

switch (event.type) {
    case 'payment_intent.succeeded':
        const paymentIntent = event.data.object;
        //DB queries
        res.send(paymentIntent)
        break;
    default:
        console.log("payment was attempted")
}
console.log("BUZZINGA")
return res.json({ received: true });

}

#

router.post('/webhook', bodyParser.raw({type: 'application/json'}),webHookStripe)

#

Previously , I was parsing the req only with app.use(express.urlencoded({extended:true})) , but now I also tried like in your docs but bodyParse is deprecated and they encourage to use my initial method

#

bodyParser*

dense talon
#

Can you try the example I linked verbatim? express.json etc

#

Are the events definitely being forwarded to the endpoint? Are you using the CLI?

opaque knoll
#

Yes I am using it

dense talon
#

Can you share an event ID (evt_xxx) and I'll have a quick peek

opaque knoll
#

sure 1 sec let me trigger an event again

#

req_bp4vGyvj4ya3LQ

#

oh event

#

evt_3Juw7IA3jSMal6iv1PSfZXUH

#

Also , is super strange : sometimes the event triggers the webhook and subsequently I can see the console.log , but some other times it doesnt trigger.

dense talon
#

Checking now

#

Which log?

opaque knoll
#

in the terminal

dense talon
#

Yes, but which log in your code. There's 2

opaque knoll
#

A , none of them ๐Ÿ™‚

dense talon
#

sometimes the event triggers the webhook and subsequently I can see the console.log

opaque knoll
#

I can only see a log I put before the try catch and sometimes I can see that one , like this:

dense talon
#

Sounds like it's tripping up somewhere then. Can you log out event before the switch statement?

#

Could well be the signature signing

opaque knoll
#

const webHookStripe = async (req, res) => {
const sig = req.headers['stripe-signature'];
console.log("Here")
......

#

Sometimes I can see the Here log , but most of the time not

#

I have also addressed this issue with a colleague of your yesterday but still didnt find a solution that works all the time

#

yours*

dense talon
#

Yeah unfortunately the CLI is sometimes sporadic with events

opaque knoll
#

Yeah , because with cURL works all the time

dense talon
opaque knoll
#

Ah .. makes sense then

dense talon
#

Could just be that if you can hit the endpoint ok with cURL

#

Maybe host your webhook somewhere and run test events to that URL

opaque knoll
#

yeah I will do just that

#

yet , the req.body is still not parsed for some reason

dense talon
#

I'd try express.json() method instead of bodyParser

opaque knoll
#

as mentioned before , using the example in the docs with bodyParser doesnt work (is deprecated) and I am using app.use(express.urlencoded({extended: true}))

opaque knoll
dense talon
#

express.urlencoded() is for urlencoded payloads (which we do not use)

opaque knoll
#

yet logging req.body gives only { hello: '' }

dense talon
#

You need to format the -d parameters correctly:
curl -X POST http://localhost:8000/webhook -d '{"hello": "test"}'

#

I think

#

Hardly use cURL ๐Ÿ˜†

opaque knoll
dense talon
opaque knoll
dense talon
#

Yeah you can't really use Postman to replicate the events. Was more just a tip to interface with our API if you were messing about with cURL

#

Did the cURL JSON work as I suggested?

#

If so, I'd just deploy your handler somewhere and create a test webhook that points to it

opaque knoll
#

I see, could you please give me 5 mins to make some more reuqests , see how it goes ?

dense talon
#

Sure!

opaque knoll
#

I am probably missing something , but for the webhook events , dont we need a POST route ?

dense talon
#

You'd have to create that yourself. There's no default POST method for forwarding a fake event to your webhook

#

That's the job of the CLI, just frustrating that sometimes it's so sporadic

opaque knoll
#

I keep getting Webhook Error: Unable to extract timestamp and signatures from header

#

but it does hit it

#

always

dense talon
opaque knoll
#

Alright looking over it right now

dense talon
#

router.post('/webhook', bodyParser.raw({type: 'application/json'}),webHookStripe)

Was correct

#

Then: event = stripe.webhooks.constructEvent(req.body, sig, endpointSecret);

event variable is your event payload, assuming the signing signature is validated

#

SO you don't need to worry about req.body when you use constructEvent

#

(except for passing it as an argument) ๐Ÿ™ƒ

#

But it should be the raw body, not parsed as JSON or anything

opaque knoll
#

Okay so postman also triggers the webhoook

opaque knoll
#

But it still throws the error that event is undefined

dense talon
#

At which point/line?

opaque knoll
#

Here

#

event = stripe.webhooks.constructEvent(req.body, sig, endpointSecret);

#

Even tough the req.body , signature and the secret are logged correctly

dense talon
#

Eh, you declare event right above the try/catch block. Right?

opaque knoll
#

yes

#

let event

#

const webHookStripe = async (req, res) => {
const sig = req.headers['stripe-signature'];
console.log(sig)
console.log(endpointSecret)

let event;
try {
    event = stripe.webhooks.constructEvent(req.body, sig, endpointSecret);
    console.log(event)
}
catch (err) {
    res.status(400).send(`Webhook Error: ${err.message}`);
}

switch (event.type) {
    case 'payment_intent.succeeded':
        const paymentIntent = event.data.object;
        //DB queries
        res.send(paymentIntent)
        break;
    default:
        console.log("payment was attempted")
}

return res.json({ received: true });

}

dense talon
#

My assumption here is that constructEvent is failing. How are you hitting this endpoint? Via Postman?

#

Like I'm not sure the signing secret will work that way as you don't have a generated secret per se

opaque knoll
#

No , I got the cli to work . It seems like it always needs another terminal open to listen , with stripe listen --forward-to localhost:8000/webhook. Then , it reacts to every request

dense talon
#

And you're using the secret the CLI gives you?

opaque knoll
#

yes exactly

dense talon
#

I'd get it working without the signing stuff for now

opaque knoll
#

Do you mean that I should not encounter this in production ?

#

To just forget about it ?

dense talon
#

No, I'd just rip the constrcutEvent out and parse the JSON yourself. Get the webhook working as you need

#

Then reintroduce the signing secret

opaque knoll
#

alright let me give this a try please

#

Finally works !!

#

This is how I did it :

#

const webHookStripe = async (req, res) => {
const event=req.body

switch (event.type) {
    case 'payment_intent.succeeded':
        const paymentIntent = event.data.object;
        console.log("Payment Succeeded")
        //DB queries
        break;
    default:
        console.log("Payment was attempted")
}

return res.json({ received: true });

}

#

Thank you soo much ynnoj !