Every Nepali payment gateway. One Go interface.
eSewa, Khalti, ConnectIPS, Fonepay, IME Pay and Hamro Pay behind paynp.Provider. Integer paisa,
verified callbacks, and a server-side Lookup you can trust.
go get github.com/mukezhz/pay-np
var p paynp.Provider = khalti.New(cfg) // 1. Start: redirect or auto-submit form co, _ := p.Initiate(ctx, paynp.InitiateRequest{ TxnID: "ord-42", Amount: 150000, // Rs 1,500 in paisa SuccessURL: "https://shop.np/return", }) co.Write(w, r) // 2. Return: trust only Lookup tx, err := p.Lookup(ctx, paynp.LookupRequest{ TxnID: "ord-42", Amount: 150000, ProviderRef: co.ProviderRef, }) if err == nil && tx.Status == paynp.StatusSuccess { fulfil(order) }
-
1
InitiateSign the form or create the provider session.
-
2
CheckoutUser pays on eSewa, Khalti, ConnectIPS…
-
3
CallbackSignature checked when signed. A hint, never proof.
-
4
LookupServer-to-server status. Amount must match.
Boring where it matters.
Every adapter follows the same rules, so swapping providers never changes how you verify a payment.
Integer paisa
paynp.Paisa everywhere. Rupee strings like 1,000.0 or 10.0000 are
parsed at the edge; sub-paisa is rejected.
Lookup is the truth
Unsigned callbacks never report SUCCESS. A paid transaction with the wrong amount returns
ErrAmountMismatch and no transaction.
One contract
Initiate, ParseCallback, Lookup. Context, timeouts and typed
*APIError on every call.
Six gateways, one shape.
Click a provider for its setup guide and env status. eSewa and Khalti run against their public sandboxes out of the box. Hamro Pay has free self-service UAT keys; the rest need merchant credentials.