Issue Confirming Signature - New Version of Next.JS with Stripe Integration

Having trouble verifying the request signature in my Stripe webhook endpoint. I keep encountering this error:

No signatures found matching the expected signature for payload. Have you passed the raw request body received from Stripe?

I've experimented with various solutions, tried different methods of parsing the raw request body, and even attempted manual verification of the HMAC sig. Unfortunately, nothing seems to be effective.

My environment:

Next.js 13.3.2 Stripe SDK 12.4.0

Steps to replicate:

  1. Create an endpoint at: /pages/api/p/test

Code:

import Stripe from 'stripe';
import { NextApiRequest, NextApiResponse } from 'next';
import safe from 'colors/safe';
import { buffer } from 'micro';

const handler = async (
    req: NextApiRequest,
    res: NextApiResponse
): Promise<void> => {
    const stripe = new Stripe(process.env.STRIPE_SECRET as string, {
        apiVersion: '2022-11-15',
    });

    const webhookSecret: string = "whsec_33244....";

    if (req.method === 'POST') {
        const sig = req.headers['stripe-signature'] as string;
        const buf = await buffer(req);
        const body = buf.toString();

        let event: Stripe.Event;

        try {
            console.log(safe.bgGreen(body))
            event = stripe.webhooks.constructEvent(body, sig, webhookSecret);
        } catch (err) {
            // Log and return the error message on failure
            console.log(`❌ Error message: ${err.message}`);
            res.status(400).send(`Webhook Error: ${err.message}`);
            return;
        }

        // Event successfully constructed
        console.log('✅ Success:', event.id);

        // Typecast event data to Stripe object
        if (event.type === 'payment_intent.succeeded') {
            const stripeObject: Stripe.PaymentIntent = event.data.object as Stripe.PaymentIntent;
            console.log(`💰 PaymentIntent status: ${stripeObject.status}`);
        } else if (event.type === 'charge.succeeded') {
            const charge = event.data.object as Stripe.Charge;
            console.log(`💵 Charge id: ${charge.id}`);
        } else {
            console.warn(`🤷‍♀️ Unhandled event type: ${event.type}`);
        }

        // Respond to acknowledge receipt of the event
        res.json({ received: true });
    } else {
        res.setHeader('Allow', 'POST');
        res.status(405).end('Method Not Allowed');
    }
};

export const config = {
    api: {
        bodyParser: false,
    },
};

export default handler;
  1. Start dev server and initiate a stripe listener
stripe listen --forward-to localhost:3000/api/p/test
  1. Copy the generated webhook signing secret and paste it in the code

  2. Simulate an event

stripe trigger payment_intent.succeeded

Tried numerous approaches after thorough internet research but still stuck. Utilizing buffer from microservices package and also tested the buffer function mentioned in Stripe's documentation. It appears to parse the body correctly:

console.log(body)

{
  "id": "evt_3NIzhvEcQkKxoTiV1xjEMh02",
  "object": "event",
  "api_version": "2022-11-15",
  ...
}

If anyone has any suggestions, I would greatly appreciate it!

Answer №1

The problem lies in the Next.JS middleware that alters the original request body. To resolve this issue, consider disabling bodyParser for your specific route: https://nextjs.org/docs/pages/building-your-application/routing/api-routes#custom-config. Otherwise, ensure you access the untouched raw request data.

Before passing the data to constructEvent() function, check the content of the body variable at your endpoint. If it appears as binary (resembling buffer data), then you have successfully obtained the raw body. However, if you encounter JSON or a string, it indicates that the request body has been modified, resulting in potential failure of your Webhook signature verification.

Answer №2

After troubleshooting, I discovered that the issue was a single character missing from the end of my test key.

Answer №3

If you're encountering key-related problems, it could be due to Stripe webhook having separate keys for localhost and production environments. To retrieve these keys, navigate to the developer section, then click on webhooks followed by the signing secret. Visit https://i.stack.imgur.com/ZY7FA.png for more information.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for activating the default 500 error page in Next.js

I'm having trouble getting Next.js to display its default 500 error page. While most sources discuss creating a custom error page, the Next.js documentation only briefly references their built-in 500 error page. I want the default page to show up when ...

Guide to utilizing a JWT token within an httpOnly cookie for accessing a secured API endpoint

Utilizing next.js and next-auth for user login authentication with an API. Once the login is successful, a httpOnly cookie named __Secure-next-auth.session-token is stored in the browser. The following is a sample value (not actual data): eyJhbGciOiJIUzUxM ...

The login process in Next-auth is currently halted on the /api/auth/providers endpoint when attempting to log in with the

My Next-auth logIn() function appears to be stuck endlessly on /api/auth/providers, as shown in this image. It seems that the async authorize(credentials) part is not being executed at all, as none of the console.log statements are working. /pages/api/au ...

Tips for maintaining i18n locale slugs and ensuring i18n consistency when reloading in Next.js

I'm currently utilizing next-translate. The default recognition of my routes is as follows: /about <--- /de/about /es/about However, I would like to set a specific locale for all paths: /en/about <--- /de/about /es/about Below is ...

Instructions on transforming an img into an Image component within next.js

I have successfully implemented all the logic in this component, tailored to the <img> tag. Now, I am aiming to apply the same logic to the Image component. However, when attempting to do so, I encounter an error. TypeError: Failed to construct &apos ...

Adding auth0 authentication to a Next.js 13 application: A step-by-step guide

Currently, I am using a nextjs 12 application and set up auth0 as my authentication provider by following the guidelines provided here: . However, I am now looking to upgrade my application to nextjs 13, but I have not been able to find any documentation o ...

Error: Please provide the required client_id when setting up Google Sign-In with Next-Auth

I have been trying to implement the Sign in with Google option in my Next.js application using next-auth. Below is a snippet of my [...nextauth].js file located in the api/auth folder: import NextAuth from "next-auth"; import Google ...

No data is being retrieved by SWR

I'm struggling to make SWR work in my code. Despite trying multiple examples, I can't seem to get it functioning properly. It's frustrating because the code looks fine and should work. I feel like I must be missing something simple. Current ...

NextAuth encountered a CLIENT_FETCH_ERROR error while processing the session callback

Encountering issues while trying to set up nextauth v4. Keep getting this error: Client fetch error, Unexpected end of JSON input {error: {…}, path: 'session', message: 'JSON.parse: unexpected end of data at line 1 column 1 of the JSON d ...

What are the steps to deploy a React, Next.js, and Express.js application on Netlify?

I am currently in the process of deploying my application to Netlify, featuring a combination of React, Next.js, and Express.js. While there are no errors showing up in the Netlify console, unfortunately, the site is not live as expected. https://i.stack ...

Mongoose and Next.js: Encountered Runtime Error - Cannot Access Undefined Properties (Token)

For some reason, the Model I defined is not working properly, despite being similar to another one that works without errors. Can anyone help me figure out why? If you need to see a minimal, reproducible example, check it out here. The problematic code: ...

What is the reason for not displaying the various li elements on my webpage?

Here is the code snippet export default function DisplaySearchResults({ results }) { var arr = Object.entries(results) console.log(arr) return ( <div> Here are the search results : <ol> {arr.map((va ...

Making a POST request to a Next.js API route results in a 500 Internal Server Error being sent back

Check out the code in createComment.ts file, which serves as a Next.js api route: import type { NextApiRequest, NextApiResponse } from 'next' import sanityClient from "@sanity/client" const config = { dataset: process.env.NEXT_PUBLI ...

Explore various queries and paths within MongoDB Atlas Search

I am currently working on developing an API that can return search results based on multiple parameters. So far, I have been able to successfully query one parameter. For example, here is a sample URL: http://localhost:3000/api/search?term=javascript& ...

Add the file retrieved from Firestore to an array using JavaScript

Trying to push an array retrieved from firestore, but encountering issues where the array appears undefined. Here is the code snippet in question: const temp = []; const reference = firestore.collection("users").doc(user?.uid); firestore .collec ...

Fetch data from Firestore when the page loads using the useEffect hook

Below is the simplified code snippet I am currently using: import { useState, useEffect, useContext } from 'react' import { useRouter } from 'next/router' import { firestore } from './firebase-config' import { getDoc, doc } f ...

The combination of Nest, Fastify, Fastify-next, and TypeOrm is unable to locate the next() function

In my attempt to set up Nest with Fastify and Next using the fastify-next plugin, everything went smoothly until I added TypeOrm for MongoDB integration. Upon loading the AppModule, Nest throws an error indicating that the .next() function cannot be found ...

I would prefer not to add another database table just to differentiate between team members and friends. Can you provide assistance with this?

Instead of creating another table named friends in Strapi and linking it to Visual Studio Code, I have opted to use a Characters table for both team members and friends. This way, I can input new data only at Characters and filter it to differentiate betwe ...

The functionality to scroll to the top of the page is not functioning properly in Next.js when navigating to a new page using the Link

While using Next.js, I encountered an issue where opening a new page would maintain the scroll position from the previous page. For instance, if I had scrolled to the bottom of a product listing page and clicked on a specific product, the product details p ...

Error in Next.js: The function (0 , firebase_auth__WEBPACK_IMPORTED_MODULE_1__.onAuthStateChanged) is not defined as a function

Just starting out with Next.js development and currently following a Youtube tutorial on creating a Whatsapp clone using firebase8.9 as the database. I am looking to implement a feature where the app checks if the user is logged in, if so redirect them to ...