I work with Laravel on a daily basis, and at some point I started integrating more than one payment gateway into the same project. Each gateway sends webhooks differently: different payload, different headers, signature validated in a different way. Nothing surprising for anyone who's been through this, but the volume of manual testing kept growing fast.
The tools I was already using
I started using expose.dev, since it was already part of the Laravel ecosystem I worked with every day. It worked well for the basics: spin up a tunnel, point the provider at it, receive the webhook. As I started needing more consistent testing, I paid for the version with a fixed subdomain, so I wouldn't have to reconfigure the endpoint on the provider every session.
The problem showed up with persistence. Requests were only visible while the console was open. I'd close the terminal, close the session, and lose the history. To debug something that happened an hour earlier, there was nothing to go back to.
To fix that, I started using webhook.site in parallel, since it keeps a history. The problem is its tunneling is pretty raw: no stable auto-reconnect, and I'd frequently lose the forwarding link, which broke the test halfway through.
Result: I had two subscriptions, each one covering half the problem.
The decision
At some point it came down to simple math: I was already paying for two incomplete tools. The combined cost of both was enough to keep a server running. It wasn't a plan to build a product, it was literally that: since I'm going to pay either way, why not build something that solves both problems at once?
Technical decisions
The first decision was the tunneling approach. Instead of polling or waiting for the provider to retry, I opted to keep a persistent WebSocket connection between a local CLI and the server: the public request arrives at the server, gets forwarded as a frame over the socket to the CLI, the CLI hits the local app and sends the real response back to the server, which returns it to the original provider. This eliminates waiting on the provider's retry to test again, and gives me real-time connection status (I know instantly if the tunnel dropped).
The second was separating capture from manipulation. At first the goal was just to inspect and tunnel, but I realized I needed to alter the request before it reached my local environment: fix a header, simulate a different payload, validate a signature before letting it through. Instead of that becoming hardcoded test code, it turned into a flow system: nodes that execute in sequence as soon as the request arrives, before the tunnel. HMAC signature verification, switch by payload field, header/body/method transformation, enrichment via external call, idempotency with a time window, simple conditionals. You can build this visually, without needing a redeploy for every test scenario.
Challenges
The trickiest part wasn't the tunnel itself, it was keeping the "real-time" feel without freezing the UI when several requests arrive in quick succession, especially during concurrency testing. Another point was deciding what to persist: keeping everything indefinitely doesn't scale, so I capped retention (today I keep the last 1,000 requests per account) instead of trying to maintain an infinite history.
What every dev likes
One thing I wanted from the start was to not depend on the web dashboard to keep up with day-to-day work. I like working with the terminal open, and opening a web app just to check if a webhook arrived breaks that flow. So, once the core was functional, I built a tail for requests right in the CLI: you can watch each request arrive in real time, with status, latency, and a colored table, without ever opening the browser. For anyone who lives in the terminal, that alone changed the way I test quite a bit.
Comparison
Against webhook.site: it handles inspecting and persisting well, but it doesn't tunnel stably, and it has nothing like manipulating the payload before delivery.
I never found a tool that tied together all three pieces (inspecting, stable tunneling, and manipulating before delivery), so I built one. Today I use it every day to test payment integrations, and I made it available for anyone who wants it: routely.me.
United States
NORTH AMERICA
Related News

Master Local Fine-Tuning with "gemma-trainer"
8h ago
Building a Plugin-Free Newsletter Popup on WordPress: Custom REST Endpoint Mailchimp API v3
8h ago
ภาษาโปรแกรมมิ่งที่ syntax ง่าย ทำให้ AI หลอนน้อยลง จริงหรือ?
8h ago
How I Built a File-Timestamp-Based Feedback Loop to Enforce AI Output Quality
8h ago
GitHub Trending Digest — 2026-07-07
9h ago