#_xxsquanchyxx_
1 messages · Page 1 of 1 (latest)
What is await buffer(req) doing?
You need the raw request body as the first argument to constructEvent
req.body
Not the full request, but the body only
it is requesting the body
ohh
hold on lemme try real quikc
nope no luck still the same
i do the req.body, but still the same
im trying to get the, checkout.session.completed
I'm not sure what those cookie errors are, how does that arise? Seems unrelated to signarue checking
Is anything else in your stack modifying the request/body?
can you kindly elaborate?
do you meant this?
const session = await stripe.checkout.sessions.create({
shipping_address_collection: { allowed_countries: ['MY'] },
billing_address_collection: 'auto',
shipping_options: [
{ shipping_rate: 'shr_1MgTAFCFZEbJKzZHfT4bP7b7' },
],
line_items: [
{
price_data: {
currency: 'myr',
product_data: {
name: product.productName,
images: [product.productImage],
},
unit_amount: product.productPrice * 100
},
adjustable_quantity: {
enabled: true,
minimum: 1
},
quantity: product.productQuantity,
}
],
client_reference_id: `${cartId}-${productId}`,
customer_email: email,
mode: 'payment',
success_url: `${req.headers.origin}/profile/`,
cancel_url: `${req.headers.origin}/canceled`,
})
it works locally before i deploy it
That's the session creation
I mean the webhook request, and how your handler fits in to the rest of your code
for example in Express, often middleware is used to parse json request body data
which breaks this, because the body data is mutated
uhh
async function webhookHandler(req: NextApiRequest, res: NextApiResponse) {
const requestBuffer = await buffer(req.body);
const signature = req.headers['stripe-signature']!;
let event;
try {
event = stripe.webhooks.constructEvent(requestBuffer, signature, webhookSecret)
// make switch case, if session completed, push to sale
// if payment intent succeeded, remove product from cart
const session = event.data.object as Stripe.Checkout.Session
if (event.type === 'checkout.session.completed') {
const { line_items } = await stripe.checkout.sessions.retrieve(session.id, {
expand: ['line_items']
})
let quantity: any;
line_items?.data.map((item) => {
quantity = item.quantity
// console.log("line items", line_items?.data.map((item) => { quantity: item.quantity }
});
const client_reference_id = session.client_reference_id
console.log(quantity)
let saleCartId;
// some firebase code here
res.status(200).json({ received: true })
} catch (err: any) {
console.log(`❌ Error message: ${err.message}`)
res.status(400).send(`Webhook Error: ${err.message}`)
return
}
}
I beleive these are some useful information?
What calls/uses webhookHandler?
ohh okay okay
basically only this
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
res.setHeader('Access-Control-Allow-Origin', 'https://techmatch-fyp.netlify.app');
res.setHeader('Access-Control-Allow-Methods', 'POST');
if (req.method == "POST") {
const { email, product, cartId, productId } = req.body;
const session = await stripe.checkout.sessions.create({
shipping_address_collection: { allowed_countries: ['MY'] },
billing_address_collection: 'auto',
shipping_options: [
{ shipping_rate: 'shr_1MgTAFCFZEbJKzZHfT4bP7b7' },
],
line_items: [
{
price_data: {
currency: 'myr',
product_data: {
name: product.productName,
images: [product.productImage],
},
unit_amount: product.productPrice * 100
},
adjustable_quantity: {
enabled: true,
minimum: 1
},
quantity: product.productQuantity,
}
],
client_reference_id: `${cartId}-${productId}`,
customer_email: email,
mode: 'payment',
success_url: `${req.headers.origin}/profile/`,
cancel_url: `${req.headers.origin}/canceled`,
})
res.status(200).json(session)
} else {
res.setHeader('Allow', 'POST')
res.status(405).end('Method Not Allowed')
}
}
the webhook would run right after the checkout
This seems to be your session creation again, but I don't see how you configure webhookHandler within the rest of your app/code
How does that end up being invoked when a request comes in?
But, leaving that aside, if you log req.body or try passing that in to constructEvent directly, what happens?
basically, when i checkout a product, then, the webhookHandler would be invoked, after i click on Pay buttton
lemem try
webhookHandler would be invoked
By what? How does that request get routed to that handler?
basically
when i clicked on this button, the prebuilt stripe checkout page PAY button
the webhookhandler would be invoked
Yes, but how
i have no idea 😢
You have an endpoint configured in your dashboard for https://somedomain.com/stripe-webhooks
Stripe sends an event notification POST request to that URI
then your server receives it and does [something] to pass the request down to webhookHandler
What we need to know is what that [something] is
i see i see
lemme try it
undefined
❌ Error message: No webhook payload was provided.
undefined was the console log
for req.body
i don't get it why is that,
Ok, so something in your application/framework is wiping out the request body
I think I've seen this before with Next
see "handling webhooks"
Try this:
const rawBody = await request.text();
then pass rawBody to construct event
alright lemme try
here's an example: https://github.com/shadcn/taxonomy/blob/main/app/api/webhooks/stripe/route.ts#L9-L22
Great, glad to hear it!