Testing webhooks on localhost

Testing webhooks on localhost

During one of my projects I was implementing payments using Stripe and PayPal. I had to test webhooks in order to confirm subscriptions (recurring payments) periodically. Since I was developing locally my app could not receive requests. In this post I’m going to show you how you can test remote webhook callback from 3rd party apps in your local app.

Webhooks theory

The theory is simple, you create a payment transaction (or any other supported event) in Stripe/PayPal/whatever, then you receive a request, which is sent by 3rd party software. You have to configure webhook URL, so remote applications know where to send requests. But since you develop locally your app cannot be reached from outside. After all, you cannot use localhost as webhook URL.

One way is to deploy your app, so it is accessible from internet, but this requires hosting and some time. This can also slow down debugging and, in some cases, make it troublesome.

The other way is to make your local app accessible from the internet. This basically means that we need a way to point some URL to our computer. In fact, we need a public URL for building webhook integrations, which will expose our local web server.

We’re lucky since there are a few providers letting us do that. I’m going to show you how to do that using ngrok. You can use for free. Free version is limited, if you need more then you can upgrade to a paid plan. But since we only want to test webhooks the free plan is good enough, we don’t need that many requests.


Testing webhooks locally becomes easy with ngrok. You only need one command to create URL pointing to your development machine. Go ahead and download it now. It works on Windows, Linux, Mac and FreeBSD.

Let’s expose our local web server (PowerShell):

PS F:\Data\Downloads\ngrok-stable-windows-amd64> ./ngrok http 80

Once you execute the command you should see something like similar to this:

Screenshot ngrok exposing localhost to the internet

The important bits are the URLs ({code}.ngrok.io). Actually if you open that url your should access your app. Be aware that we are working on port 80 here, so once you open the ngrok URL you will see the same thing you see on localhost:80.

Easy, wasn’t it? Also, notice that it exposes both HTTP and HTTPS, which comes in handy.

One more thing worth noting is that ngrok comes with web interface, which you can use to inspect requests and responses (web interface URL is printed above the ngrok public URLS, refer to screenshot). This is really helpful.