Skip to content

Appendix: Making notifyUrl Publicly Reachable ​

NOTE

This is an optional appendix, not a required step. If you already have a publicly reachable server or domain, use it for notifyUrl and skip this page.

Why this requirement exists ​

One-key setup asks for two URLs, and they point in opposite directions — which is the single most common mix-up when integrating:

FieldWho calls whomMust be publicly reachable
notifyUrlHashNut server → your serverYes
callbackUrlUser's browser → your siteNo

notifyUrl is the address HashNut calls you on once an order has been paid (the webhook). The request originates from HashNut's server, so the address has to be reachable from the public internet — http://localhost:1800 is not.

callbackUrl is only where the user's browser is redirected after paying. The redirect happens in the user's own browser, so http://localhost:5173 works perfectly well.

WARNING

Symptoms of getting these two backwards:

  • The payment succeeds but the order status never changes — notifyUrl points at a local address and HashNut cannot reach you
  • After paying you land on a page that will not load — callbackUrl points at a tunnel address and the tunnel is no longer running

A way to remember it: notify = your backend receives a notification (server to server), callback = your frontend gets a redirect (browser behaviour).

Your options ​

If you do not have a public server during local development, use a tunnel to expose a local port. Common choices:

ToolNotes
ngrokQuickest to get going; on the free tier the address changes on every restart
frpNeeds a machine of your own with a public IP; the address is stable
Cloudflare TunnelFree and can use your own domain; a bit more configuration

It makes no difference to HashNut which one you use — all it cares about is whether notifyUrl can be reached. The example below uses ngrok.

Example with ngrok ​

Sign up at ngrok.com, install it as described there, then expose your backend port (the demo shop uses 1800 by default; use whatever you set server.port to):

bash
ngrok http 1800

The Forwarding line in the output is the public address you need:

Forwarding    https://xxxxx.ngrok-free.dev -> http://localhost:1800

With that address in hand, fill in 1.3 Filling in the one-key setup parameters like this:

ParameterLocal developmentProduction
notifyUrlhttps://xxxxx.ngrok-free.dev/api/notifyhttps://your-domain/api/notify
callbackUrlhttp://localhost:5173/payment-resulthttps://your-domain/payment-result

The paths /api/notify and /payment-result are the demo shop's conventions; use your own routes if you are writing your own application.

WARNING

On the ngrok free tier the address changes every time you restart it. HashNut still has the old address stored, so notifications go to a dead URL — which looks exactly like "the payment succeeded but the order status never changed".

So leave ngrok running while you debug; if the address does change, update the API key's notifyUrl in the dashboard. To avoid this entirely, use a paid ngrok domain, or frp / Cloudflare Tunnel.

Checking that it works ​

With the backend running, call the demo shop's API through the public address:

bash
curl https://xxxxx.ngrok-free.dev/api/chains

If it returns the chains and tokens as JSON, the path from the internet to your machine is open and HashNut's notifications will get through.

If it does not, check in this order: is the tunnel still running, is the backend started, do the ports match.

See also ​