Local testing
You have three ways to receive webhooks against a local handler.
1. Tunnels (recommended for active dev)
A tunnel exposes localhost:3000 as a public HTTPS URL. Paylera
delivers to that URL; the tunnel forwards to your machine.
ngrok
ngrok http 3000Copy the https://….ngrok-free.app URL it prints. Register it as a
sandbox webhook endpoint (the dashboard accepts any HTTPS URL).
Cloudflare Tunnel
cloudflared tunnel --url http://localhost:3000Slightly slower to start, free, no account needed for ad-hoc use.
tailscale funnel
If you’re already on Tailscale:
tailscale serve --bg --https=443 http://localhost:3000tailscale funnel 443 onThe URL is https://your-machine.your-tailnet.ts.net.
2. Webhook tester (no tunnel)
The sandbox dashboard ships a built-in Webhook tester: a hosted endpoint that captures deliveries and shows them live, with the raw envelope, the signature header, and the verification result.
Use it when:
- You’re not yet wiring a handler, just inspecting the payload shape.
- You want to confirm a webhook fires for a specific operation.
- You want to copy a real delivery for use in a unit test.
Go to Developers → Webhook tester, register the displayed endpoint, trigger an event, watch it land. You can replay any captured delivery to a different endpoint with one click.
3. CLI (paylera listen)
Install the CLI:
brew install paylera/tap/paylera# or: curl -fsSL https://cli.paylera.io/install.sh | shAuthenticate once with a sandbox key:
paylera login --sandboxListen and forward to your local handler:
paylera listen --forward-to http://localhost:3000/webhooksThe CLI:
- Registers an ephemeral sandbox webhook endpoint.
- Subscribes to
*(or--events invoice.*if you scope it). - Forwards each delivery to your local URL.
- Prints the event envelope and your handler’s response in the terminal.
- Tears down the endpoint when you Ctrl-C.
It also includes a fixture command:
paylera trigger invoice.paid --invoice-id inv_……which posts a synthetic delivery so you can exercise your handler without a real subscription / payment.
Testing signature verification
Sign a payload manually for unit tests:
paylera webhooks sign \ --secret whsec_… \ --body '{"id":"evt_test"}' \ --timestamp 1736179200# → t=1736179200,v1=…Or use the SDK helpers:
import { Webhooks } from "@paylera/sdk";
const sig = Webhooks.sign(payload, secret, { timestamp: 1736179200 });What “success” looks like
When verifying locally:
- Your handler returns 2xx within 10 seconds.
- The deliveries log (in the dashboard or on the CLI) shows
succeededfor the attempt. - Your handler observed the event exactly once per delivery (test that
by triggering the same event twice with different
event_ids — both should be processed; sameevent_idtwice — only one should).
Common pitfalls
localhostcan’t be a webhook URL. It must be reachable from the public internet. Use a tunnel.- Self-signed certs — Paylera only delivers to URLs with publicly-trusted certificates. Tunnels handle this for you.
- Slow handlers under the debugger. Step-debugging a 10-second handler is fine; Paylera’s 10-second timeout pretends nothing happened. Use the CLI for replay-driven debugging instead.