Skip to content
tolapayBeta
Engineering · Guides · 2 Oct 2026 · 5 min read

Your app got invoice.paid. Now what? Building reliable webhook handlers

Verify the signature, make the handler idempotent, grant access from the event not the redirect — the four habits that make billing webhooks boring.

The redirect after checkout is a user-experience event, not a financial one. The payment is real when the billing system says so — and it says so with a webhook.

1. Verify before you trust

Tola Pay signs every delivery with a `Tola-Signature` header: HMAC-SHA256 over the timestamp and body, using your endpoint secret. Recompute, compare in constant time, and reject anything older than a few minutes. Signed webhooks are what let you expose an HTTPS endpoint without worrying who else can reach it.

2. Be idempotent

Deliveries retry on failure, so the same event can arrive twice. Store the event ID; if you have seen it, return 200 and do nothing. This is the webhook twin of transaction_id on usage events.

3. Grant access from the event

`invoice.paid` is when a subscription starts or renews, a wallet top-up lands, or a benefit should be granted. Flip the customer's entitlement there — never from the success URL, which anyone can type into a browser.

4. Return fast, work later

Acknowledge within a second or two and push the real work onto a queue. Slow handlers cause retries, retries cause duplicates, duplicates test your idempotency.

Testing it

Use test keys and sandbox rails, pay yourself रू 10 with Khalti, and watch the delivery log in the dashboard. Replay a delivery and confirm your handler shrugs.

Related