#kevinx9999_webhooks
1 messages · Page 1 of 1 (latest)
👋 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/1315876940669915188
📝 Have more to share? Add more details, code, screenshots, videos, etc. below.
Hello River, hope all is well
This is the error message returned from your server:
Webhook 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.Learn more about webhook signing and explore webhook integration examples for various frameworks at https://docs.stripe.com/webhooks/signature
First time using webhook in Express server, based on the template provided by Stripe below, it doesn't construct event successfully
Could you share your code of webhook implementation?
I can log the sig
app.post(
"/stripewebhook",
express.raw({ type: "application/json" }),
(request, response) => {
console.log("🚀 ~ Raw body:", request.body.toString());
const sig = request.headers["stripe-signature"];
let event;
console.log("🚀 ~ sig:", sig);
try {
event = stripe.webhooks.constructEvent(request.body, sig, endpointSecret);
console.log("🚀 ~ endpointSecret:", endpointSecret);
console.log("🚀 ~ Successfully constructed event:", event);
} catch (err) {
response.status(400).send(`Webhook Error: ${err.message}`);
return;
}
// Handle the event
switch (event.type) {
case "checkout.session.completed":
const checkoutSession = event.data.object;
// "period_end": 1733797714,
// "period_start": 1733797714,
// paid": true,
// "status": "paid",
const email = checkoutSession.client_reference_id;
console.log("🚀 ~ email:", email);
console.log("🚀 ~ checkoutSession:", checkoutSession);
break;
case "charge.succeeded":
const charge = event.data.object;
console.log("🚀 ~ charge:", charge);
break;
// ... handle other event types
default:
console.log(`Unhandled event type ${event.type}`);
}
// Return a 200 response to acknowledge receipt of the event
response.send();
}
);
Does your node middleware configure parsing all the requests to JSON somewhere? For example, if you have app.use(express.json()); prior to your webhook route
yes
// Middleware
app.use(cors()); // Enable CORS for cross-origin requests
app.use(express.json()); // Parse JSON bodies
app.use(express.urlencoded({ extended: true }));
The order of app.use(express.json()) matters. Can you put this after your webhook route?
If you have app.use(express.json()); prior to your route, this will parse the requests in all JSON, not in raw form before reaching to your webhook function
you mean the webhook does NOT USE this middleware?
Webhook will use middleware. The problem here is that app.use(express.json()) will change the request body that no longer maintain its raw form before reaching your webhook route
Not necessary. I'll try to re-arrange order of the code, so that app.use(express.json()) is not executed first before your webhook route
just tested it and it worked, thanks, since we are here, just one more question
for checkout sessions, what's the difference between charge.succeeded vs invoice.payment_succeeded
which one should I monitor to confirm the payment is successful
subscription
For subscription, I'd recommend monitoring invoice.paid event: https://docs.stripe.com/billing/subscriptions/event-destinations#active-subscriptions
Charge related events is the payment attempt on the invoice of a subscription.
To monitor the successful payment on a subscription, invoice.paid event should be used.