stripe webhook error when hosted on vercel
Unanswered
Blanc de Hotot posted this in #help-forum
Blanc de HototOP
I'm building a simple e-commerce with next.js that only creates an order in a postgres database from a charge.succeeded event webhook from stripe.
When I setup a local listener it is working. It forwards to "stripe listen --forward-to localhost:3000/webhooks/stripe".
But when I deoloy the app to vercel. And it gets this URL: "https://rosahimmel-ecommerce.vercel.app" I get a 400 error from a webhook I setup in stripe with the endpoint URL: "https://rosahimmel-ecommerce.vercel.app/webhooks/stripe"
Seems like the route.tsx doesn't get run at all on the vercel deployment. (the webhook status in stripe is first pending then error).
Ive been stuck with this so many days now and I have no idea what to do please help me!
When I setup a local listener it is working. It forwards to "stripe listen --forward-to localhost:3000/webhooks/stripe".
But when I deoloy the app to vercel. And it gets this URL: "https://rosahimmel-ecommerce.vercel.app" I get a 400 error from a webhook I setup in stripe with the endpoint URL: "https://rosahimmel-ecommerce.vercel.app/webhooks/stripe"
Seems like the route.tsx doesn't get run at all on the vercel deployment. (the webhook status in stripe is first pending then error).
Ive been stuck with this so many days now and I have no idea what to do please help me!
26 Replies
Blanc de HototOP
Added info:
When I use stripe listen and forward to "https://rosahimmel-ecommerce.vercel.app/webhooks/stripe" the route gets triggered.
When I use stripe listen and forward to "https://rosahimmel-ecommerce.vercel.app/webhooks/stripe" the route gets triggered.
Giant panda
can you please post the code here? With nextjs, you need to get raw body and then construct event
Blanc de HototOP
but its working when I run the deployment locally. should I still assume the poblem could be in the route.tsx?
Giant panda
any specific error message you are seeing?
Blanc de HototOP
import db from "@/db/db";
import { NextRequest, NextResponse } from "next/server";
import Stripe from "stripe";
import { Resend } from "resend";
import PurchaseReceiptEmail from "@/lib/emails/PurchaseReceipt";
import { WebhookProduct } from "@/types";
console.log("Hello, world!");
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY as string);
const resend = new Resend(process.env.RESEND_API_KEY as string);
export type ExtendedWebhookProduct = WebhookProduct & {
quantity: number;
};
export async function POST(request: NextRequest) {
console.log("Received stripe webhook");
let event;
try {
event = stripe.webhooks.constructEvent(
await request.text(),
request.headers.get("stripe-signature") as string,
process.env.STRIPE_WEBHOOK_SECRET as string
);
} catch (error) {
console.error("Error verifying webhook signature", error);
return new NextResponse("Webhook error", { status: 400 });
}
if (event.type === "charge.succeeded") {
console.log("Charge succeeded");
const charge = event.data.object as Stripe.Charge;
const email = charge.billing_details.email;
const priceInCents = charge.amount;
const name = charge.billing_details.name;
const shippingDetails = charge.shipping;
// Parse metadata
const productIds: string[] = JSON.parse(charge.metadata.productIds || "[]");
const quantities: number[] = JSON.parse(charge.metadata.quantities || "[]");
const deliveryMethod = charge.metadata.deliveryMethod;
if (!email || !name || !shippingDetails) {
return new NextResponse("Bad requestz", { status: 400 });
}@Giant panda any specific error message you are seeing?
Blanc de HototOP
From stripe:
Delivery attempt
Aug 24, 2024, 1:05:54 PM
400
Learn how to troubleshoot HTTP status codes starting with 4xx or 5xx
Response body
Webhook error
Request body
{
"id":
"evt_3PrHmiDqIfBTbdfJ2YdUDBUX",
"object":
"event",
"api_version":
"2020-08-27",
"created":
1724497551,
"data": {
"object": {… 41 items},
},
"livemode":
false,
"pending_webhooks":
3,
"request": {
"id":
"req_JmuEY1tOZaEKt2",
"idempotency_key":
"dd74b3fc-e4ca-4599-963b-465289c4560b",
},
"type":
"payment_intent.succeeded",
}
Delivery attempt
Aug 24, 2024, 1:05:54 PM
400
Learn how to troubleshoot HTTP status codes starting with 4xx or 5xx
Response body
Webhook error
Request body
{
"id":
"evt_3PrHmiDqIfBTbdfJ2YdUDBUX",
"object":
"event",
"api_version":
"2020-08-27",
"created":
1724497551,
"data": {
"object": {… 41 items},
},
"livemode":
false,
"pending_webhooks":
3,
"request": {
"id":
"req_JmuEY1tOZaEKt2",
"idempotency_key":
"dd74b3fc-e4ca-4599-963b-465289c4560b",
},
"type":
"payment_intent.succeeded",
}
Maybe the route is running but vercel doesn't give me the console.log("Received stripe webhook");
I was thinking the route wasn't triggered at all.
I was thinking the route wasn't triggered at all.
Giant panda
if this is not logging - console.log("Received stripe webhook");, it may be due to caching
Blanc de HototOP
Aug 24, 2024, 1:21:56 PM
400
Learn how to troubleshoot HTTP status codes starting with 4xx or 5xx
Response body
Webhook error
This this because it cant find the URL destination of the webhook or because the route is responding with a 400?
400
Learn how to troubleshoot HTTP status codes starting with 4xx or 5xx
Response body
Webhook error
This this because it cant find the URL destination of the webhook or because the route is responding with a 400?
From this?
try {
event = stripe.webhooks.constructEvent(
await request.text(),
request.headers.get("stripe-signature") as string,
process.env.STRIPE_WEBHOOK_SECRET as string
);
} catch (error) {
console.error("Error verifying webhook signature", error);
return new NextResponse("Webhook error", { status: 400 });
}Giant panda
looks like 400
We need to find out why console.log is not showing in vercel log
Blanc de HototOP
this is what vercel gives me for each incoming webhook
Giant panda
it is printing that in log
Blanc de HototOP
yes
Error verifying webhook signature N [Error]: No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe?
If a webhook request is being forwarded by a third-party tool, ensure that the exact request body, including JSON formatting and new line style, is preserved.
If a webhook request is being forwarded by a third-party tool, ensure that the exact request body, including JSON formatting and new line style, is preserved.
I just trigger when payment.intent successful.
Maybe it doesnt get the stuff because the charge isnt done
Giant panda
may be check secret variable
Blanc de HototOP
yes probably this is due to API key issues
Giant panda
yes
sometimes we use test variable provided in example. that's invalid secret. So you need to copy from stripe settings again
specifically "stripe webhook secret "
Blanc de HototOP
Will look into it closer later, at least vercel triggers logs now, seems like at least the webhook gets triggered. Probably env. problems. THanks a lot so far sir.
Giant panda
no worries