#louis-tam_api
1 messages ยท Page 1 of 1 (latest)
Below are links to other discussions we've had with you in the past week in case you want to review that information. If your question is related to one of these previous discussions, please provide a comprehensive summary of the current state and what you need help with now. We help many users simultaneously, so a summary allows us to resolve your issue as soon as possible.
- louis-tam_api, 40 minutes ago, 20 messages
๐ 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/1245459158879178877
๐ Have more to share? Add more details, code, screenshots, videos, etc. below.
Hello
hi bismarck
Looks like you are having a signature verification issue
Seems like you aren't actually passing in the raw body of the request
What framework are you using?
express for backend
Okay are you using express.json()?
yes ibelive so app.use(
express.json({
limit: "10mb",
})
);
Gotcha, this is manipulating the raw body of the request. So in that case you want to do something like:
app.use((req, res, next) => {
if (req.originalUrl === '/webhook') {
next(); // Do nothing with the body because I need it in a raw state.
} else {
express.json()(req, res, next); // ONLY do express.json() if the received request is NOT a WebHook from Stripe.
}
});
Can you share an event ID? Did you log out the error message? Did you log out the payload that you are passing?
Are you using the CLI-provided Webhook secret here?
the err message is '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. \n' +
[1] 'Signature verification is impossible without access to the original signed material. \n' +
[1] '\n' +
[1] 'Learn more about webhook signing and explore webhook integration examples for various frameworks at https://github.com/stripe/stripe-node#webhook-signing\n'
i thought bodyParser took care of the json issue
No you need the raw body
Add a log right before you call constructEvent() where you log out your payload. If that is anything but buffer (which looks like binary) then you don't have the raw body and your signature verification is going to fail
ok i ran this in the try block try {
console.log(payload)
event = stripe.webhooks.constructEvent(payload, sig, endpointSecret);
console.log("GREAT SUCCESS", event);
} catch (err) {
return response.status(400).send(Webhook Error: ${err.message});
} and got htis for pyaload{
[1] id: 'evt_1PLsUdE9bJZH5kiQAZBq0yVs',
[1] object: 'event',
[1] api_version: '2022-11-15',
[1] created: 1717012143,
[1] data: {
[1] object: {
[1] id: 'txr_1PLsUdE9bJZH5kiQ8UTRxyTf',
[1] object: 'tax_rate',
[1] active: true,
[1] country: null,
[1] created: 1717012143,
[1] description: 'Harmonized Sales Tax for Ontario',
[1] display_name: 'Ontario HST',
[1] effective_percentage: 13,
[1] inclusive: false,
[1] jurisdiction: 'CA',
[1] jurisdiction_level: null,
[1] livemode: false,
[1] metadata: {},
[1] percentage: 13,
[1] state: null,
[1] tax_type: null
[1] }
[1] },
[1] livemode: false,
[1] pending_webhooks: 2,
[1] request: {
[1] id: 'req_RLL11HchXPmKIw',
[1] idempotency_key: 'stripe-node-retry-aee2161c-9eb8-4293-b458-b629bcbdba8b'
[1] },
[1] type: 'tax_rate.created'
[1] }
stripeRoutes.post(
"/webhook",
bodyParser.raw({ type: "application/json" }),
(request, response) => {
const payload = request.body;
const sig = request.headers["stripe-signature"];
let event;
try {
console.log(payload)
event = stripe.webhooks.constructEvent(payload, sig, endpointSecret);
console.log("GREAT SUCCESS", event);
} catch (err) {
return response.status(400).send(`Webhook Error: ${err.message}`);
}
// if (event.type === "checkout.session.completed") {
// const session = event.data.object;
// console.log("Checkout session completed:", session.id);
// } else {
// console.log("Received event of type:", event.type);
// }
response.status(200).end();
}
);
Try express.raw({type: 'application/json'}) instead of bodyParser
err is giving me this now raw: {
[1] 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 instead. \n' +
[1] 'Signature verification is impossible without access to the original signed material. \n' +
[1] '\n' +
[1] 'Learn more about webhook signing and explore webhook integration examples for various frameworks at https://github.com/stripe/stripe-node#webhook-signing\n'
[1] },
Can you show me your express/route initialization code as well?
๐งโ๐ป How to format code on Discord
Inline code: wrap in single backticks (`)
This:
The variable `foo` contains the value `bar`.
Will turn into this:
The variable
foocontains the valuebar.
Code blocks: wrap in three backticks (```)
Also, you can specify the language after the first three backticks to get syntax highlighting.
This:
```javascript
function foo() {
return 'bar';
}
```
Will turn into this:
function foo() {
return 'bar';
}```
Notes about **code blocks**:
- Specifying the language is optional (e.g., you can omit `javascript` in the example above)
- If you don't specify the language you won't get syntax highlighting
- When you're inside a code block (after you type \`\`\`) the `Return`/`Enter` key will add a new line instead of sending your message
- Once you end the code block `Return`/`Enter` works normally again
You can [read more about message formatting on Discord's website.](https://support.discord.com/hc/en-us/articles/210298617)
app.use("/api/products", productRoutes);
app.use("/api/brands", brandRoutes);
app.use("/api/users", userRoutes);
app.use("/api/order", orderRoutes);
app.use("/api/stripe", stripeRoutes);
app.use("/", stripeRoutes)
What about how stripeRoutes is initialized?
And where are you calling express.json()?
Usually that is the real culprit with Express
im calling express.json in my index.js import dotenv from "dotenv";
import connectToDatabase from "./database.js";
import express from "express";
import path from "path";
import cors from "cors";import bodyParser from "body-parser";
// import Stripe from "stripe";
//ROUTES
import productRoutes from "./routes/productRoutes.js";
import userRoutes from "./routes/userRoutes.js";
import brandRoutes from "./routes/brandRoutes.js";
import orderRoutes from "./routes/orderRoutes.js";
import stripeRoutes from "./routes/stripeRoutes.js";
dotenv.config();
connectToDatabase();
const app = express();
app.use(cors({ origin: ['http://example1.com', 'http://localhost:3000/checkout'] }));
const port = process.env.PORT || 5000;
app.use(
express.json({
limit: "10mb",
})
);
//names after/api/ must match mongoDB collection names
app.use("/api/products", productRoutes);
app.use("/api/brands", brandRoutes);
app.use("/api/users", userRoutes);
app.use("/api/order", orderRoutes);
app.use("/api/stripe", stripeRoutes);
app.use("/", stripeRoutes)
const __dirname = path.resolve();
app.use("/uploads", express.static(path.join(__dirname, "/uploads")));
if (process.env.NODE_ENV == "production") {
app.use(express.static(path.join(__dirname, "/client/build")));
app.get("*", (req, res) =>
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"))
);
}
app.listen(port, () => {
console.log(Server runs on port ${port}.);
});
Yep so above you are still running express.json() on all of your routes
I indicated above that you need to skip that for your webhook route
sorry i changed it back after i ran it. it gave the same result when i ran app.use((req, res, next) => {
if (req.originalUrl === '/webhook') {
next(); // Do nothing with the body because I need it in a raw state.
} else {
express.json()(req, res, next); // ONLY do express.json() if the received request is NOT a WebHook from Stripe.
}
});
let me try again
IT WORKS NOW!
thanks!