#alex-z_webhooks
1 messages ยท Page 1 of 1 (latest)
๐ 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. Thank you for your patience!
โฑ๏ธ We automatically close idle threads, which makes them read-only. Make sure you stick around to chat in realtime! If this thread is closed and you have another question you'll need to start a new thread.
๐ 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/1214133007011553301
๐ Have more to share? You can add more detail below, including code, screenshots, videos, etc.
idE1psY8mFbWRsInZwKiPK91z3c2 is not a stripe ID, can you share with me the event ID (starts with evt_) so that I can check your integration ?
yes
"evt_1OqXCAIXM48CCWLO8Jm8pu0A"
app.post(
"/webhook/stripe",
express.raw({ type: "application/json" }),
async (req: express.Request, res: express.Response) => {
const sig = req.headers["stripe-signature"];
console.log("bodyParser.raw() output:", req.body); // This log is already good
console.log("Headers:", req.headers); // Log all headers
console.log("stripe-signature:", req.headers["stripe-signature"]); // Log for specific inspection
console.log("Raw body (first 30 bytes):", req.body.slice(0, 30).toString()); // Inspect if any changes occurred
let event: Stripe.Event;
try {
// const requestBodyBuffer = Buffer.from(req.body);
event = stripe.webhooks.constructEvent(
req.body,
sig,
webhookSecret // Ensure this is set in your environment
);
OK, did you use the webhook secret that you obtained from Dashboard, or from the output of stripe listen ?
app.use(
(
req: express.Request,
res: express.Response,
next: express.NextFunction
): void => {
if (req.originalUrl.startsWith("/webhook/stripe")) {
console.log("originalREq:", req.body);
bodyParser.raw({ type: "application/json" })(req, res, () => {
console.log("bodyParser.raw() output:", req.body); // Log here
next();
});
} else {
express.json()(req, res, next);
}
}
);
Dashboard
There were two endpoints with the same URL.
with stripe listen and trigger, locally, it's working
That means you are using the secret generated from stripe listen
the secret is the problem?
the we_ one?
the ones from the Dashboard yes
to be clear the webhookSecret needs to be the one you copy from the dashboard (not the same one as what stripe-cli prints) in case that's the issue
beyond that, when you say // This log is already good what does it look like? can you share the exact output of that line?
it also feels wrong that you're able to do slice on req.body since that implies it's an array(like an array of bytes), when it should be a string.
there's a demo/working implementation of it for Express at https://github.com/stripe/stripe-node/tree/master/examples/webhook-signing if that helps
yeah that is wrong, it can not be a Buffer
i have 2 secrets
stripe webhook secret
with whsec
and stripe secret key
with sk_test
can i share it with you, to confirm?
the only one that's relevant is the whsec_xxx
you don't need to share them. The endpointSecret should be the whsec_xxx from the Dashboard page for the endpoint
but as I said, the problem here really is what you pass to constructEvent is a Buffer and not a string of the HTTP body(UTF8)
i changed to this: app.use(
(
req: express.Request,
res: express.Response,
next: express.NextFunction
): void => {
if (req.originalUrl.startsWith("/webhook/stripe")) {
next();
} else {
express.json()(req, res, next);
}
}
);
const sig = req.headers["stripe-signature"];
let event: Stripe.Event;
console.log("webhook secret", webhookSecret);
try {
// const requestBodyBuffer = Buffer.from(req.body);
event = stripe.webhooks.constructEvent(
req.body,
sig,
webhookSecret // Ensure this is set in your environment
);
do i need to do something for utf8?
not specifically no
redeploying again, env variable was different after logging. checking again. fingers crossed and thank you for your help
webhook secret is ok: api] [2024-03-04 09:20:47] [error] Error processing webhook StripeSignatureVerificationError: Webhook payload must be provided as a string or a Buffer (https://nodejs.org/api/buffer.html) instance representing the raw request body.Payload was provided as a parsed JavaScript object instead.
[ocartedespre-api] [2024-03-04 09:20:47] Signature verification is impossible without access to the original signed material.
[ocartedespre-api] [2024-03-04 09:20:47]
[ocartedespre-api] [2024-03-04 09:20:47] Learn more about webhook signing and explore webhook integration examples for various frameworks at https://github.com/stripe/stripe-node#webhook-signing
[ocartedespre-api] [2024-03-04 09:20:47]
[ocartedespre-api] [2024-03-04 09:20:47] at Layer.handle [as handle_request] (/home/node/api/node_modules/.pnpm/express@4.18.3/node_modules/express/lib/router/layer.js:95:5) {
[ocartedespre-api] [2024-03-04 09:20:47] type: 'StripeSignatureVerificationError',
[ocartedespre-api] [2024-03-04 09:20:47] raw: {
[ocartedespre-api] [2024-03-04 09:20:47] message: 'Webhook payload must be provided as a string or a Buffer (https://nodejs.org/api/buffer.html) instance representing the raw request body.Payload was provided as a parsed JavaScript object
yeah the error message kind of says what is wrong
usually what we recommend is you start by deploying and using https://github.com/stripe/stripe-node/tree/master/examples/webhook-signing/express to get that working and then you add your own code back in