#arhamfawad
1 messages · Page 1 of 1 (latest)
It sounds like somewhere you're pulling out only the request body, instead of passing in the entire unmodified webhook request. Are you able to step through your code and check to see where that's happening?
I have shared my code as well
You can see in thread
should I share here as well
I have seen it line by line the body seems to me perfect and its been 10 days since I have been tagged in this issue please help
You need to pass in just body as a string or a raw HTTP request. There's an example of how to do that in the code here: https://stripe.com/docs/webhooks#verify-official-libraries
Try passing in request.body or request.body.toString()
This is my code :
// functions/index.js
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const dotenv = require('dotenv');
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
const express = require('express');
const cors = require('cors')({origin: true});
dotenv.config();
admin.initializeApp();
const app = express();
// Middleware to parse JSON
app.use(cors);
app.use(express.static('public'));
app.use(express.urlencoded({extended: true}));
app.use('/webhook', express.raw({type: 'application/json'}));
app.use(express.json());
app.post('/webhook', async (request, response) => {
const sig = request.headers['stripe-signature'];
console.log('Hello World Sign');
console.log(request.body);
console.log(typeof request.body);
console.log('Hello World Sign');
// Verify the Stripe signature
let event;
try {
event = stripe.webhooks.constructEvent(
request.body,
sig,
process.env.STRIPE_SECRET_SIGNATURE,
);
} catch (err) {
console.error('Webhook Error I Just Found:', err.message);
response.status(400).send(Webhook Error: ${err.message});
return;
}
if (event.type === 'checkout.session.completed') {
const session = event.data.object;
// Extract relevant information
const customerEmail = session.customer_details.email;
// Fetch user by email
console.log(User ${customerEmail} marked as paid.);
response.status(200).end();
} else {
console.error(User not found with email: ${customerEmail});
response.status(404).end();
}
} else {
response.status(200).end();
}
});
exports.app = functions.https.onRequest(app);
I'm using stripe payment link for payment and then webhook for handling the rest of the functionality
I have seen the link you shared 1000 times the same code is not working when only on request.body ? Why is that is it due to the test mode credentials ?
there's a little minor thing that I'm missing
The error message is very explicit in what's going wrong. you need to change your code in your try block from request.body to request.body.read or cast it as a string. Stripe needs it to be either a buffer or a string in order to verify the webhook signature.
okay Now I have changed the code to this :
event = stripe.webhooks.constructEvent(
request.body.toString(),
sig,
process.env.STRIPE_SECRET_SIGNATURE,
);
lets try
No luck getting the same error
Now I'm getting this error :
Webhook Error I Just Found: No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe?
please help me
okay, so that's a different error
Have you confirmed you're using the right Webhook Secret? You use process.env.STRIPE_SECRET_SIGNATURE, but I obviously can't see what that actually is in your environment variables. It should look something like this --> whsec_abc123
yes I am using the right one
I have also logged it out in firebase cloud functions logs
Although Its a test mode credentials
Hey bro any thing that can help ?
Please be patient. I'm juggling a number of threads other than this one.
So, to confirm, you manually went to your dashboard here: https://dashboard.stripe.com/webhooks, and selected the webhook enpoiont, then you clicked reveal to see the Webhook Secret and compared that manually to the one that's stored as an evnironment variable called STRIPE_SECRET_SIGNATURE
It's likely that there's an encoding issue. Can you try setting this in your code?
express.raw({type: 'application/json'}),
Use the code here as reference: https://stripe.com/docs/webhooks#verify-official-libraries
In this code that I shared above : #1198037676138434590 message
You can see I have used this line : app.use('/webhook', express.raw({type: 'application/json'}));
You need to make sure it's in this line:
app.post('/webhook', async (request, response) => {
Anyway, I'm afraid I have to go for the day, as Discord closed at 3:30, but feel free to check back with us on Monday if you're still having issues.
could you please answer this one more thing ?
before signing out ?
should I keep my code like this :
1:
event = stripe.webhooks.constructEvent(
request.body,
sig,
process.env.STRIPE_SECRET_SIGNATURE,
);
2:
event = stripe.webhooks.constructEvent(
request.body.toString(),
sig,
process.env.STRIPE_SECRET_SIGNATURE,
);
1 or 2 what should I pass ?
I'd stick with 1 and do a console.log(); of each of those variables (sig, request.body, and STRIPE_SECRET_SIGNATURE) to make sure they all match with what is supposed to be there.
lastly, the data you sign might be different from the data Stripe signed. Often, this means that you're using a framework that tried to be helpful and parsed the Event data as JSON. Because of this, when you calculate your own signature, you do this on a string that is not exactly the same. For example the order of properties might have changed or the indentation would be different. For the signatures to match, you need to calculate it on the exact same raw string as Stripe did. For this, you need to ensure that they get the raw body of the HTTP request that Stripe sent you, without any interference by their code or framework in the middle.
That's all I can say for now until you dig in and try some of my above recommendations.