A payments API for Nepal that you can read in an afternoon.
One call creates a checkout for eSewa, Khalti and Fonepay. We handle each gateway's signing, redirects and verification, then tell your server with a signed webhook.
Test mode with a Sandbox gateway is free. The full docs open after you sign in.
import Paymentsnp from "@paymentsnp/sdk";
const pnp = new Paymentsnp({ apiKey: process.env.PAYMENTSNP_API_KEY! });
// 1. Create a checkout (NPR 1,500.00 = 150000 paisa)
const session = await pnp.checkout.sessions.create(
{ order_id: "order-1001", amount_minor: 150000, currency: "NPR",
success_url: "https://shop.example.com/orders/1001" },
{ idempotencyKey: "order-1001" },
);
// Redirect the customer to session.checkout_url
// 2. Webhook route: pass the raw body, not parsed JSON
const event = await Paymentsnp.webhooks.constructEvent(
rawBody, req.get("Paymentnp-Signature"), process.env.PAYMENTSNP_WEBHOOK_SECRET!,
); // throws SignatureVerificationError if forged or stale
if (event.type === "payment.succeeded") fulfilOnce(event.id, event.data);The whole flow
Same three steps for every gateway, in test and in live.
Your server creates a checkout
Send an order ID and an amount in paisa with your secret key and an
Idempotency-Key. You get acheckout_urlback. Retrying with the same key returns the same checkout.The customer pays
Redirect them, or open the page in a popup with
checkout.js. They choose a method and pay in the provider's own app.You get a verified webhook
After the provider confirms the exact amount, we POST
payment.succeededto your endpoint. Verify the signature, then fulfil the order once per event ID.
POST /your/webhook HTTP/1.1
Paymentnp-Signature: t=1791100000,v1=5f2c…
Paymentnp-Event-Id: 8f4f7c0e-2b1d-4a7e-9c55-0d3e1f6a9b21
{
"id": "8f4f7c0e-2b1d-4a7e-9c55-0d3e1f6a9b21",
"type": "payment.succeeded",
"api_version": "v1",
"environment": "test",
"created_at": "2026-10-01T06:45:05.000Z",
"data": {
"payment_id": "5b2d6c1e-…",
"checkout_session_id": "c1a94d07-…",
"order_id": "order-1001",
"provider": "esewa",
"provider_transaction_id": "000AB12",
"amount_minor": 150000,
"currency": "NPR",
"is_simulated": false,
"overpaid": false
}
}The API at a glance
REST over HTTPS with JSON. Amounts are integer paisa. Every key is either test or live and carries only the scopes you give it.
- Idempotent checkout creation, safe to retry
- Webhooks signed with HMAC-SHA256, retried up to 8 times, replayable
- Keys with scopes, expiry, rolling with a grace period, IP allowlists and per-key rate limits
- Test mode only sees test data; the Sandbox gateway simulates success and failure
- Unclear gateway answers stay pending, never paid by guesswork
| Method | Route | Scope |
|---|---|---|
| POST | /v1/checkout/sessions | checkout:create |
| GET | /v1/checkout/sessions/:id | checkout:read |
| POST | /v1/checkout/sessions/:id/expire | checkout:create |
| GET | /v1/payments | payments:read |
| GET | /v1/payments/:id | payments:read |
| GET | /v1/invoices | invoices:read |
| POST | /v1/invoices | invoices:write |
| POST | /v1/invoices/:id/finalize | invoices:write |
| POST | /v1/invoices/:id/send | invoices:write |
| POST | /v1/reconciliation/import/bulk | reconciliation:write |
| GET | /v1/reconciliation/report | reconciliation:read |
SDKs, CLI and MCP server
Official, zero-dependency libraries with typed errors, retries and webhook verification. Same method names in every language.
| Language | Registry | Install | Notes |
|---|---|---|---|
| TypeScript / Node.js | npm | npm install @paymentsnp/sdk | Node 18+, Bun, Deno, edge runtimes; includes the paymentsnp CLI |
| PHP | Packagist | composer require paymentsnp/paymentsnp-php | PHP 7.4+, curl and json only; works without Composer too |
| Python | PyPI | pip install paymentsnp | Python 3.9+, standard library only |
| MCP server | npm | npx -y @paymentsnp/mcp | Lets Claude, Cursor and other assistants read your payments; read-only unless you allow writes |

Plugins if you would rather not write code
Download them from the dashboard. Each one completes an order only after Paymentsnp verifies the payment.
| WHMCS | Gateway module v3 pays WHMCS invoices with eSewa, Khalti and Fonepay, and upgrades v2 installs in place. |
|---|---|
| WooCommerce | Adds Paymentsnp as a payment method, including the block checkout and HPOS stores. |
| Shopify | A self-hosted app that sends customers a pay link and marks the order paid once verified. Shopify only lets approved partners inside its checkout, so it uses a manual payment method. |
| No website | Payment links take a payment with no code at all. |
A redirect is not a receipt
Your success_url tells you the customer came back. It does not tell you they paid. Fulfil on the webhook, or fetch the session.
- Money settles directly to your own eSewa, Khalti and Fonepay merchant accounts.
- Every payment is verified server-side with the gateway, for the exact amount.
- API key secrets are shown once and stored only as a hash.
- More on how we handle money and data on the security page.

