#louis-tam_api

1 messages ยท Page 1 of 1 (latest)

valid badgeBOT
terse muralBOT
#

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.

valid badgeBOT
#

๐Ÿ‘‹ 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.

sweet pond
#

Hello

fleet shore
#

hi bismarck

sweet pond
#

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?

fleet shore
#

express for backend

sweet pond
#

Okay are you using express.json()?

fleet shore
#

yes ibelive so app.use(
express.json({
limit: "10mb",
})
);

sweet pond
#

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.
    }
  });
fleet shore
#

ok let megive that a shot

#

still doesn't work

sweet pond
#

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?

fleet shore
#

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'

GitHub

Node.js library for the Stripe API. . Contribute to stripe/stripe-node development by creating an account on GitHub.

#

i thought bodyParser took care of the json issue

sweet pond
#

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

fleet shore
#

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] }

sweet pond
#

Yep that won't work

#

Can you share your full webhook handler code?

fleet shore
#

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();

}
);

sweet pond
#

Try express.raw({type: 'application/json'}) instead of bodyParser

fleet shore
#

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] },

GitHub

Node.js library for the Stripe API. . Contribute to stripe/stripe-node development by creating an account on GitHub.

sweet pond
#

Can you show me your express/route initialization code as well?

valid badgeBOT
#

๐Ÿง‘โ€๐Ÿ’ป 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 foo contains the value bar.

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)
fleet shore
#

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)

sweet pond
#

What about how stripeRoutes is initialized?

#

And where are you calling express.json()?

#

Usually that is the real culprit with Express

fleet shore
#

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}.);
});

sweet pond
#

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

fleet shore
#

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!