So first what i want to say, is that none of the public questions on stackoverflow did not helped me with this error. I am running the Stripe CLI on my local machine like this : stripe listen --forward-to localhost:4242/webhook
, but weirdly when i try to proccess all the events inside i get the error :
No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe? https://github.com/stripe/stripe-node#webhook-signing
I have already tried using request.rawBody , but it didn't fix my issue. I am posting all of the code, so maybe someone will see what i can't and help me fixing it
router.js :
let express = require('express');
let router = express.Router();
let bodyParser = require('body-parser')
let postMong = require('./post')
require("dotenv").config()
router.use(express.json());
const YOUR_DOMAIN = 'http://localhost:4242';
const stripe = require('stripe')(process.env.PUBLIC_KEY);
router.post('/checkout/create-order', async (req, res) => {
const price = req.body.order.stripe_price || undefined,
product = req.body.order.stripe_product || undefined
const session = await stripe.checkout.sessions.create({
shipping_address_collection: {
allowed_countries: ['US', 'CA'],
},
shipping_options: [
{
shipping_rate_data: {
type: 'fixed_amount',
fixed_amount: {
amount: 2499,
currency: 'usd',
},
display_name: 'International Shipping',
// Delivers between 5-7 business days
delivery_estimate: {
minimum: {
unit: 'week',
value: 2,
},
}
}
},
],
line_items: [
{
price: price,
quantity: 1,
},
],
payment_method_types: ["card", 'us_bank_account'],
mode: 'payment',
success_url: `${YOUR_DOMAIN}/success.html`,
cancel_url: `${YOUR_DOMAIN}/index.html`,
});
res.json({url: session.url})
});
router.post('/posts/add', async (req,res)=>{
try{
const {author, id, name, picture, pixels, price, size, stripe_price, stripe_product} = req.body
const pos = await postMong.create( {author, id, name, picture, pixels, price, size, stripe_price, stripe_product})
res.json(pos)
} catch(e){
res.status(500).json(e)
}
})
router.get('/ideas', async (req,res)=>{
try{
const posts = await postMong.find()
return res.json(posts);
} catch(e){
reject(res.status(500).json(e))
}
})
const endpointSecret = 'whsec_****';
const fulfillOrder = (session) => {
// TODO: fill me in
console.log("Fulfilling order", session);
}
router.use(bodyParser.json());
router.post('/webhook', (request, response) => {
const payload = request.body;
const sig = request.headers['stripe-signature'];
let event;
try {
event = stripe.webhooks.constructEvent(request.rawBody, sig, endpointSecret);
console.log(event)
} catch (err) {
console.log(err.message)
return response.status(400).send(`Webhook Error: ${err.message}`);
}
// Handle the checkout.session.completed event
if (event.type === 'checkout.session.completed') {
const session = event.data.object;
// Fulfill the purchase...
fulfillOrder(session);
}
response.status(200);
});
module.exports = router
server.js :
const router = require("./router");
const account = require("./routerAccount");
const express = require('express');
const mongoose = require("mongoose")
const app = express();
const cors = require('cors')
var session = require('express-session');
require("dotenv").config()
const db_url = process.env.MONGO_URL
app.use(session({
cookie: {
httpOnly: true
},
rolling: true,
resave: true,
saveUninitialized: true,
secret: '~~~~~'
}));
app.set('view engine','ejs');
app.use(express.static('public'));
//app.use(express.json());
app.use(cors())
app.use('/', router)
app.use('/', account)
async function startApp(){
try{
await mongoose.connect(db_url, {
useUnifiedTopology: true,
useNewUrlParser:true
})
app.listen(4242, () => {console.log("server is working")})
} catch(e) {
console.log("some error appearead" e)
}
}
startApp()
CodePudding user response:
Normally when you see this error, it means that, either the HTTP request body Stripe sent to your webhook handler has been altered in some way or You may not be using the correct webhook secret.
The most likely reason it is throwing an exception is because your router is parsing body as JSON with router.use(express.json())
. constructEvent
requires the raw, unparsed body you receive from the request to verify the signature. To verify you have the raw body you can print it out and see if you get something like <Buffer 28 72 10..>
You can tell your router to keep the request body raw by setting something like this on your route router.use('/webhook', express.raw({type: "*/*"}))
CodePudding user response:
I found the solution for my problem. What i added is
app.use( "/webhook",express.raw({ type: "*/*" }))
in my server.js file.