/stripe-guides

How to test webhooks locally for Stripe?

Learn how to test Stripe webhooks locally using the Stripe CLI, set up a local server, forward events, debug issues, and prepare for production—all step by step.

Matt Graham, CEO of Rapid Developers

Book a call with an Expert

Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.

Book a free consultation

How to test webhooks locally for Stripe?

How to Test Webhooks Locally for Stripe

 

Step 1: Understand What Webhooks Are

 

Webhooks are a way for Stripe to notify your application when an event happens in your account. For example, when a customer's payment succeeds or fails, Stripe can send an HTTP POST request to your specified endpoint with information about the event.

 

Step 2: Install the Stripe CLI

 

The Stripe CLI is a tool that helps you interact with your Stripe account from the command line. It also allows you to forward webhooks to your local server.

For macOS (using Homebrew):

brew install stripe/stripe-cli/stripe

For Windows (using Scoop):

scoop bucket add stripe https://github.com/stripe/scoop-stripe-cli.git
scoop install stripe

For Linux:

curl -s https://packages.stripe.dev/api/security/keypair/stripe-cli-gpg/public | gpg --dearmor | sudo tee /usr/share/keyrings/stripe.gpg
echo "deb [signed-by=/usr/share/keyrings/stripe.gpg] https://packages.stripe.dev/stripe-cli-debian-local stable main" | sudo tee -a /etc/apt/sources.list.d/stripe.list
sudo apt update
sudo apt install stripe

 

Step 3: Login to Your Stripe Account via CLI

 

Run the following command and follow the instructions to authenticate:

stripe login

This will open your browser and ask you to authorize the Stripe CLI to access your account. Once authorized, you'll be redirected back to your terminal.

 

Step 4: Set Up Your Local Development Server

 

Before testing webhooks, you need a local server that can receive HTTP requests. Here's a simple example using Express.js in Node.js:

const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const port = 3000;

// Use JSON parser for webhooks
app.use(
  bodyParser.json({
    // We need the raw body to verify webhook signatures.
    // Let's compute it only when hitting the Stripe webhook endpoint.
    verify: function(req, res, buf) {
      if (req.originalUrl.startsWith('/webhook')) {
        req.rawBody = buf.toString();
      }
    }
  })
);

// Stripe webhook endpoint
app.post('/webhook', (req, res) => {
  const sig = req.headers['stripe-signature'];
  const endpointSecret = 'whsec\_...'; // Your webhook signing secret

  let event;

  try {
    // Verify the event came from Stripe
    const stripe = require('stripe')('sk_test_...');
    event = stripe.webhooks.constructEvent(req.rawBody, sig, endpointSecret);
  } catch (err) {
    console.log(`⚠️ Webhook signature verification failed.`, err.message);
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }

  // Handle the event
  console.log(`Received event: ${event.type}`);
  
  switch (event.type) {
    case 'payment\_intent.succeeded':
      const paymentIntent = event.data.object;
      console.log(`PaymentIntent ${paymentIntent.id} succeeded!`);
      // Then define and call a function to handle the event payment\_intent.succeeded
      break;
    // ... handle other event types
    default:
      console.log(`Unhandled event type ${event.type}`);
  }

  // Return a 200 response to acknowledge receipt of the event
  res.json({received: true});
});

app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}/`);
});

 

Step 5: Start Forwarding Webhooks to Your Local Server

 

Now that your local server is running, use the Stripe CLI to forward webhooks:

stripe listen --forward-to http://localhost:3000/webhook

After running this command, you'll see a webhook signing secret that looks like whsec_.... Save this secret as it will be used to verify the webhook signatures.

 

Step 6: Update Your Webhook Handler with the Signing Secret

 

Update the endpointSecret variable in your webhook handler code with the signing secret provided by the Stripe CLI:

const endpointSecret = 'whsec\_...'; // Replace with your webhook signing secret from the CLI

 

Step 7: Trigger Test Events

 

You can trigger test webhook events using the Stripe CLI. For example, to simulate a successful payment:

stripe trigger payment\_intent.succeeded

Here are some other common events you might want to test:

stripe trigger payment_intent.payment_failed
stripe trigger charge.succeeded
stripe trigger invoice.payment\_succeeded
stripe trigger customer.subscription.created

You can see a full list of available events by running:

stripe trigger --help

 

Step 8: Check the Webhook Response

 

When you trigger an event, the Stripe CLI will forward it to your local server. You should see logs in both your terminal running the Stripe CLI and your server application showing the event being received and processed.

 

Step 9: Debug Webhook Issues

 

If your webhook handler isn't working as expected, you can use the Stripe CLI's logs to help debug:

stripe logs tail

This will show you recent API requests, responses, and webhook events in real-time.

 

Step 10: Test with Real Data (Optional)

 

If you want to test with real data from your Stripe account (instead of simulated events), you can use:

stripe listen --forward-to http://localhost:3000/webhook --live

This will forward actual webhook events from your Stripe account to your local server. Be careful when using this with a production account!

 

Step 11: Use ngrok for External Testing (Optional)

 

If you need to test webhooks from external services that can't reach your localhost, you can use ngrok:

npm install -g ngrok
ngrok http 3000

This will give you a public URL that forwards to your local server. You can use this URL in the Stripe dashboard to register your webhook endpoint.

Then update your Stripe CLI forwarding:

stripe listen --forward-to https://your-ngrok-url.ngrok.io/webhook

 

Step 12: Set Up Webhook in Stripe Dashboard for Production

 

Once you've tested your webhook locally and are confident it works correctly, you can set it up in the Stripe Dashboard:

  1. Go to the Stripe Dashboard
  2. Navigate to Developers > Webhooks
  3. Click "Add endpoint"
  4. Enter your production endpoint URL
  5. Select the events you want to receive
  6. Save the endpoint

Stripe will provide you with a signing secret for this endpoint. Make sure to store this securely in your production environment.

 

Conclusion

 

Testing Stripe webhooks locally helps ensure your application correctly handles events before deploying to production. The Stripe CLI makes this process straightforward by forwarding webhook events to your local server, allowing you to develop and debug without deploying your code.

Want to explore opportunities to work with us?

Connect with our team to unlock the full potential of no-code solutions with a no-commitment consultation!

Book a Free Consultation

Client trust and success are our top priorities

When it comes to serving you, we sweat the little things. That’s why our work makes a big impact.

Rapid Dev was an exceptional project management organization and the best development collaborators I've had the pleasure of working with. They do complex work on extremely fast timelines and effectively manage the testing and pre-launch process to deliver the best possible product. I'm extremely impressed with their execution ability.

CPO, Praction - Arkady Sokolov

May 2, 2023

Working with Matt was comparable to having another co-founder on the team, but without the commitment or cost. He has a strategic mindset and willing to change the scope of the project in real time based on the needs of the client. A true strategic thought partner!

Co-Founder, Arc - Donald Muir

Dec 27, 2022

Rapid Dev are 10/10, excellent communicators - the best I've ever encountered in the tech dev space. They always go the extra mile, they genuinely care, they respond quickly, they're flexible, adaptable and their enthusiasm is amazing.

Co-CEO, Grantify - Mat Westergreen-Thorne

Oct 15, 2022

Rapid Dev is an excellent developer for no-code and low-code solutions.
We’ve had great success since launching the platform in November 2023. In a few months, we’ve gained over 1,000 new active users. We’ve also secured several dozen bookings on the platform and seen about 70% new user month-over-month growth since the launch.

Co-Founder, Church Real Estate Marketplace - Emmanuel Brown

May 1, 2024 

Matt’s dedication to executing our vision and his commitment to the project deadline were impressive. 
This was such a specific project, and Matt really delivered. We worked with a really fast turnaround, and he always delivered. The site was a perfect prop for us!

Production Manager, Media Production Company - Samantha Fekete

Sep 23, 2022