Nothing is half-saved
A payment and the event that announces it are written in the same database transaction. Either both exist or neither does, so a crash cannot lose a webhook.
Plain answers to the questions a careful business owner should ask before letting anyone near their payments. Everything here describes how the software works today; we do not claim certifications or audits we have not done.
We are not in the middle of the money. We are in the middle of the information about it.
When a customer pays Rs 1,500 with eSewa, that Rs 1,500 lands in your eSewa merchant account. eSewa settles it to your bank on whatever schedule and fees you agreed with them. We receive the proof of payment so we can tell your system the order is paid.
That is why the dashboard shows verified payments, not a balance. To check what actually reached your bank, upload the provider's settlement file under Reconciliation.
| Area | What it covers | How it is protected |
|---|---|---|
| Gateway credentials | Your eSewa, Khalti and Fonepay secret keys | Encrypted with AES-256-GCM and tied to your workspace and the exact connection. The key lives outside the database. They are never sent back to a browser, written to logs or shown to Paymentsnp staff. Every save creates a new version, and a payment in progress keeps the version it started with. |
| API keys | The np_test_ and np_live_ keys your server uses | Shown once, then stored only as a hash. Each key has its own scopes, and can have an expiry date, an IP allowlist and a rate limit. Rolling a key gives the old one a grace period of an hour, a day or a week. Test keys can never see live data. |
| Dashboard sign-in | Your team's sessions | httpOnly cookies with CSRF protection, email verification before first sign-in, and a list of signed-in devices you can sign out remotely. Roles are checked again on every request. |
| Your business data | Orders, customers, payments | Each workspace is isolated in the database itself with row-level security, not only in application code. Test and live records are kept apart. |
| Webhooks | Events we send to your server | Signed with HMAC-SHA256 over a timestamp and the raw body. We only deliver to public HTTPS addresses on ports 443 or 8443, check the address again before every attempt, and never follow redirects. |
| Changes | Who did what | Credential saves, API key changes, team changes and settings changes go to an audit log with the person, the action and the time. |

Neither is a customer landing on your thank-you page. Return links can be opened by anyone. We only mark an order paid when the provider itself confirms the payment for the right merchant, the right order and the exact amount.
Networks drop and providers time out. Each payment attempt is in one of these states, and we never guess our way to ‘paid’.
A payment and the event that announces it are written in the same database transaction. Either both exist or neither does, so a crash cannot lose a webhook.
If your server is down, we retry with growing gaps for up to 8 attempts and you can replay any event from the dashboard. A failed webhook never changes the payment itself.
A background job re-checks unfinished eSewa and Khalti payments. If one succeeds after the checkout expired, it is recorded and your webhook is sent.
One honest limit: Fonepay has no status lookup, so a Fonepay payment where the customer never returns to the checkout cannot be confirmed by us. Check your Fonepay merchant panel for those. More about Fonepay
No. Customers sign in and approve payments on the provider's own pages. Paymentsnp never asks for wallet credentials.
No certification or audit is claimed on this site. The controls described here are implemented in the platform; provider approval and UAT are completed per merchant before live payments.
No. Platform administrators can see operational data such as payment records to help with support, but secrets are never returned to any screen, including ours.
Expiry stops new attempts but is not proof that no money moved. If the provider later confirms the payment, it is still recorded and your webhook is sent.