At Praxium Labs we build this for Nepali businesses every month; this is the field-tested version. Khalti is Nepal's second-largest wallet by volume and the preferred gateway for many SaaS and education clients. KPG v2 is cleaner than eSewa's scheme, but the pitfalls are different — most production bugs come from skipping the lookup step or trusting the redirect query string.
How Khalti KPG v2 differs from eSewa
Khalti does not send a signed callback. After the user pays, Khalti redirects them back to your return_url with query params (pidx, status, txnId, amount, purchase_order_id). You must then call Khalti's lookup endpoint (POST https://khalti.com/api/v2/epayment/lookup/) to confirm the payment server-side. Trusting the query params alone is the #1 way fraud creeps in.
The n8n workflow
- Webhook node: catches the return_url redirect
- HTTP Request node: POST to lookup endpoint with pidx and your live secret key
- IF node: proceed only if response.status == "Completed" and amount matches expected
- Postgres / Sheets node: mark invoice paid (idempotently — use the pidx as the unique key)
- WhatsApp node: send receipt
- Error workflow: alert ops on any failure
The lookup call
HTTP Request node configuration
POST https://khalti.com/api/v2/epayment/lookup/
Authorization: Key {KHALTI_LIVE_SECRET}
Content-Type: application/json
{
"pidx": "{{ $json.query.pidx }}"
}
Verify the response
// Function node after lookup
const r = $json;
if (r.status !== 'Completed') throw new Error('Khalti status: ' + r.status);
if (parseInt(r.total_amount) !== expectedAmountInPaisa) {
throw new Error('Amount mismatch: ' + r.total_amount);
}
return { ...r, verified: true };
Idempotency
Customers click "Pay" buttons twice. Pages reload. Webhooks fire on page-back. Build the workflow so calling it ten times with the same pidx produces the same end state. The pattern: query your invoices table for the pidx first; only mark paid if it is not already marked. Use a unique constraint on pidx at the database level as the ultimate guard.
Currency precision in paisa
Khalti expresses amounts in paisa (NPR × 100). Always store amounts in paisa internally — a NPR 1,250.50 invoice is 125,050 paisa. Mixing rupee and paisa scales is a recurring bug in beginner integrations.
Handling cancelled and pending payments
A user who cancels redirects back with status=User canceled. A pending bank transfer can take 5–30 minutes; the redirect returns status=Pending. Your workflow needs three branches: Completed (mark paid), Pending (set status to awaiting, schedule a re-lookup in 10 minutes), Cancelled / Refunded (mark void, free reserved inventory).
Production deployment checklist
- Use n8n with a public URL — Khalti needs to POST to a routable endpoint. Self-hosted n8n on a VPS + a Cloudflare-fronted domain works; see our self-hosted setup guide
- Sign webhook URLs: include a long random secret in the URL path; reject calls without it
- Reject replays: store pidx + timestamp; refuse the same pidx twice
- Set explicit timeout on the verify call to Khalti's API (5 seconds); fall back to "pending" not "success" on timeout
- Alert on workflow failures: n8n Slack / email notification on any execution error — payment workflows must not fail silently
- Backup workflow state: export your workflows to git so a server failure does not lose the integration
Multi-currency considerations
Khalti is NPR-only at the gateway level. If your products are priced in USD (common for SaaS), convert to NPR at checkout time using a rate from an FX-rate API (Open Exchange Rates, ExchangeRate API). Round to the nearest NPR — Khalti does not accept paisa. Store both the USD and NPR amounts in your order record to reconcile against your USD-denominated accounting. For broader pricing strategy in NPR, see our SaaS pricing guide.
Frequently asked questions
Does Khalti send a webhook when payment is completed?
KPG v2 does not push webhooks for completion events in the same way eSewa does. The pattern is: user redirects to your return_url → you call lookup → you mark paid. For asynchronous flows (bank transfers that complete later), poll lookup every 10 minutes for pending pidx values.
Why call lookup at all if I trust the redirect?
Because the redirect query string is trivially forgeable — a malicious user can manually visit your return_url with status=Completed and a made-up pidx. The lookup call goes server-to-server with your authenticated key, so the response is trustworthy.
What does Khalti charge per transaction?
Standard merchant pricing as of 2026 is 2.55% per transaction with no monthly minimum. Volume-discounted rates exist above NPR 5 lakh/month — talk to Khalti merchant support.
Can I refund a Khalti payment via the API?
Yes — Khalti exposes a refund endpoint that takes the original pidx. Refunds settle in 1–3 working days. Build a separate n8n workflow for refunds triggered from an internal admin panel.
Does Khalti work in Khalti UAT for testing?
Yes — there is a separate sandbox at https://dev.khalti.com/api/v2/ with test keys. All development happens there.
How do I support both eSewa and Khalti in the same workflow?
Use a single "payments" workflow with two webhook endpoints — one for eSewa, one for Khalti — that converge on the same "mark invoice paid + notify customer" sub-workflow. The common shape makes adding Fonepay or ConnectIPS later straightforward — see our multi-gateway selector guide.
Does Khalti charge n8n calls extra?
No — Khalti's pricing is per transaction, not per API call. Workflow orchestration cost is yours (n8n VPS, monitoring), not Khalti's.
Can n8n handle Khalti subscriptions?
Khalti does not have first-class subscription primitives. To run subscriptions through Khalti, schedule a recurring n8n workflow that creates a fresh pidx each billing cycle and emails the customer a pay link. Less ideal than auto-debit, but functional.
Who can build this in Nepal?
Praxium Labs — Nepal's AI and automation consultancy, based in Lalitpur — designs and builds the systems described in this guide for Nepali businesses and for international teams hiring from Nepal. Start a project or see all services.