Skip to content

Local testing

You have three ways to receive webhooks against a local handler.

A tunnel exposes localhost:3000 as a public HTTPS URL. Paylera delivers to that URL; the tunnel forwards to your machine.

ngrok

Terminal window
ngrok http 3000

Copy the https://….ngrok-free.app URL it prints. Register it as a sandbox webhook endpoint (the dashboard accepts any HTTPS URL).

Cloudflare Tunnel

Terminal window
cloudflared tunnel --url http://localhost:3000

Slightly slower to start, free, no account needed for ad-hoc use.

tailscale funnel

If you’re already on Tailscale:

Terminal window
tailscale serve --bg --https=443 http://localhost:3000
tailscale funnel 443 on

The 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:

Terminal window
brew install paylera/tap/paylera
# or: curl -fsSL https://cli.paylera.io/install.sh | sh

Authenticate once with a sandbox key:

Terminal window
paylera login --sandbox

Listen and forward to your local handler:

Terminal window
paylera listen --forward-to http://localhost:3000/webhooks

The 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:

Terminal window
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:

Terminal window
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 succeeded for 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; same event_id twice — only one should).

Common pitfalls

  • localhost can’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.