#theryanmark

1 messages · Page 1 of 1 (latest)

native kayakBOT
scenic roost
terse patrol
#

ok. good i'm on the right path. I am having an issue with my api calling your api. I have a node/express REST api and body parser is not seenging raw json to stripe. I have moved all endpoint functions to a separate controller file. but I am getting a 400 when testing the endpoint locally through stripe cli. my route looks like this:

#

const bp = require('body-parser');
router.post('/hook', bp.raw({type: 'application/json'}), paymentCtrl.stripeHook );

#

any suggestions?

scenic roost
#

Can you explain a bit about what you're trying to do? If you're just listening for webhooks, this is what I would use with Express and it works just fine:

`const express = require("express");
const app = express();

app.use(express.static("."));
app.use(express.json());

app.post("/hook", express.json({ type: "application/json" }), (req, res) => {
const event = req.body;
const event_object = event.data.object;

// Handle the event
switch (event.type) {
case "checkout.session.completed":
console.log(Checkout Session ${event_object.id} was successful!);
break;
default:
// Unexpected event type
console.log(
Unhandled event type ${event.type}. Are you sure this event was supposed to go to this endpoint?
);
}

// Return a 200 response to acknowledge receipt of the event
res.send();
});`

terse patrol
#

ya so I just moved the (req, res) function to a seperate file.

#

but i am usig this code for thee base of the fuction

scenic roost
#

You may want to redact your secret test API key from that message so that you don't get any trolls blowing up your test account

terse patrol
#

haha good call ty

scenic roost
#

When you say you get a 400 error, do you mean that the Stripe CLI listener shows a 400 when you try to forward webhooks to your local endpoint? If so, can you show me what the console is saying?

terse patrol
#

I have iit in an env var in the actual code. i forgot you guys fill it in automatically.

scenic roost
#

Yeah, that's an instance of Stripe maybe being a little too helpful, but that's another conversation entirely

terse patrol
scenic roost
#

Ahhh, okay. So are the webhooks even reaching the endpoint? Like, if you put a console.log("Made it to this line in the code"); in your code to check if the webhook handler is actually getting hit, does it log the message to console?

If not, do you maybe need your route to be /payment/hook instead of /hook?

terse patrol
#

ya it is hitting payment/hook because I have my top leveled points in the main app.js and then they each point to a child routes.js for children endpoints.

scenic roost
#

Okay, so then it's down to the webhook signature not matching then

terse patrol
#

the "are you passing raw" log is coming from the error msg in the function for the hook

scenic roost
#

Right, that makes sense

#

On this line:
const endpointSecret = 'whsec_...';

Do you have an actual Webhook Signing Secret in your code? (I noticed you pasted this, but figured it was worth checking)

#

Also, can you post the actual full code for your webhook handler?

#

Redacting the webhook signing secret, of course

#

If you console.log(sig); , does it contain anything?

terse patrol
#

yes

#

do you want to see it?

scenic roost
#

Yeah

#

Okay cool, thanks for that

terse patrol
#

👍

scenic roost
#

When you ran the command to forward events to your local endpoint, you should have been given a webhook secret. Sometimes that Webhook secret is different than the one shown in the dashboard. Can you go back through your command line history and confirm that the one give when you ran the command is the same as the whsec_ you pasted in your code?

terse patrol
#

yes cofirmed correct secret

scenic roost
#

What's the exact command that you ran?

terse patrol
#

stripe listen --forward-to localhost:5000/payment/hook

&&

stripe trigger checkout.session.completed

scenic roost
#

Hmmm...

terse patrol
#

🤔

scenic roost
#

Okay, so something somewhere has to be manipulating the header of the request. I would guess that the file where you export would be the place to look first. This is what you have:

exports.stripeHook = async (req, res, next) => { console.log(endpointSecret); const payload = req.body; const sig = req.headers['stripe-signature'];

This is what we recommend (https://stripe.com/docs/webhooks/signatures#verify-official-libraries) for getting the raw request header:

app.post('/webhook', express.raw({type: 'application/json'}), (request, response) => { const sig = request.headers['stripe-signature'];

Obviously we don't separate out into 2 separate files, so that has to be what's causing the error.

Verify the events that Stripe sends to your webhook endpoints.

terse patrol
#

so i moved the function up to the app.post level ad its the same issue...

scenic roost
#

What does that block look like now that you've moved it?

terse patrol
#

I think i have an issue with stripe.webhooks because I can't go to the definition I may have missed installing something

scenic roost
#

You said "I can't go to the definition". What do you mean?

Also is bp the variable where you imported express? Or is it the instantiation of an express app?

native kayakBOT
terse patrol
#

bp is the body parser. but I found the webhooks .js in the node_modules. so i think i was wrong.

#

did the logged siigature look correct?

dreamy sky
#

i'm a bit confused, did you share the logged signature somewhere?

terse patrol
#

ya i had. looks like it was removed.

#

i am getting it 5 times 1 for each 400 i am getting

dreamy sky
#

what do you mean by 5 times 1?

terse patrol
#

like its logged 5 times. I assume once for each 400 error I am getting

#

the other weird thing i just noticed is the payment is hitting my test dashboard. does that make sense?

dreamy sky
#

i still don't really understand what you mean by logged 5 times - however, in any case, a 400 error in this case refers to a signature verification issue and like my colleague mentioned, the usual issues are not using the raw request body or using the wrong webhook secret

terse patrol
#

ok. i did and i am still getting the same issue. so we know the secret is correct. is there a way to verify that the signature is raw?

dreamy sky
#

the request body you mean

#

when you log the request body, what do you get?

#

so after let event = request.body; when you log event, you get the json?

#

that's wrong then, you should be getting a buffer

dreamy sky
#

somewhere in your flow - possibly your server, could be changing / processing the request

#

cause if i print it from that downloaded sample with node, i get a buffer