0%
PRAXIUM LABS

Namaste! 🇳🇵

You found our hidden gem! Something incredible is brewing in the heart of the Himalayas. We might have something special here for you soon.

Stay curious. Jay Nepal!

Share

Auto-Reconcile eSewa Payments with n8n: End-to-End Nepali Recipe (2026)

Auto-Reconcile eSewa Payments with n8n: End-to-End Nepali Recipe (2026)

TL;DR. eSewa's ePay v2 returns a base64-encoded JSON response with an HMAC-SHA256 signature in the `signature` field. The n8n workflow below verifies that signature, looks up the invoice by transaction_uuid, updates your accounting system, and triggers the customer notification — all in under 1 second. Skipping signature verification is the #1 reason fraudulent paid markings end up in production.

Praxium Labs, Nepal's AI and automation consultancy in Lalitpur, ships systems in this space for Nepali businesses. eSewa is Nepal's largest digital wallet, processing the majority of online payments for SMEs. Building a reliable reconciliation workflow is non-negotiable; doing it wrong (skipping signature checks, missing edge cases) means accepting fraudulent transactions as paid.

How eSewa ePay v2 callbacks work

After a successful payment, eSewa redirects the customer back to your success_url with a base64-encoded data query parameter. Decoded, it contains JSON with the transaction_code, status, total_amount, transaction_uuid (your reference), product_code (merchant ID), and a signature. The signature is HMAC-SHA256 of total_amount,transaction_uuid,product_code using your eSewa secret key, base64-encoded.

The n8n workflow at a glance

A single workflow handles the callback. Five nodes:

  • Webhook node: receives the success_url callback
  • Function node: base64-decodes the data param and parses JSON
  • Function node: compute expected HMAC-SHA256, compare to provided signature, abort if mismatch
  • HTTP Request node: verify with eSewa's transaction-status endpoint (defence in depth)
  • Database node: look up invoice by transaction_uuid, update status to paid
  • WhatsApp / Email node: send customer receipt

The signature verification code (production-tested)

Function node — verify signature

const crypto = require('crypto');
const SECRET = $env.ESEWA_SECRET_KEY;  // store in n8n credentials, not in node

const data = JSON.parse(Buffer.from($json.data, 'base64').toString());
const message = `total_amount=${data.total_amount},transaction_uuid=${data.transaction_uuid},product_code=${data.product_code}`;
const expected = crypto
  .createHmac('sha256', SECRET)
  .update(message)
  .digest('base64');

if (expected !== data.signature) {
  throw new Error('eSewa signature mismatch — rejecting');
}
return { ...data, signature_verified: true };

Defence in depth: also call eSewa's status API

A valid signature proves the callback came from eSewa, but does not prevent replay attacks. The extra safeguard is a server-side call to eSewa's transaction-status endpoint: POST https://epay.esewa.com.np/api/epay/transaction/status with your product_code and the transaction_uuid. If eSewa returns status=COMPLETE and matches the amount, you can trust the transaction. We always do both.

Updating your accounting system

For a small SME this is usually a Google Sheets update. For larger merchants we push directly into QuickBooks / Xero / your custom ERP. The fields we record per transaction: transaction_code, transaction_uuid (your invoice ref), total_amount, payment_method=esewa, status, raw_payload (for audit), signature_verified=true.

Customer notification template

WhatsApp message goes out within ~3 seconds of payment via the workflow described in our WhatsApp guide. Template includes order ID, amount, payment method, and a link to the invoice PDF. Open rates: 90%+ within an hour for Nepali customers.

Refunds and partial reconciliation

eSewa supports refunds via the Refund API — same HMAC signing scheme. Build a separate refund workflow that takes an admin-portal trigger and calls eSewa with the original transaction_uuid. Partial refunds are not supported; you must refund the full amount and re-charge the remaining if needed.

Frequently asked questions

Is eSewa's callback secure without HTTPS?

eSewa only allows HTTPS callback URLs in production. Use a real domain with a valid certificate — Cloudflare in front of your n8n instance covers this for free.

What if the customer closes the browser before the callback fires?

Two safety nets: (1) eSewa's server-side notification (configure a notify_url in your payment-initiation request — most teams skip this and shouldn't), (2) a 10-minute polling sub-workflow that calls the eSewa status API for any pending invoice older than 5 minutes.

Can n8n handle eSewa transaction volume for a large merchant?

Yes. A single CX22 Hetzner VPS comfortably handles 200+ payments/minute. The bottleneck is almost always the downstream system (your ERP or accounting tool), not n8n itself.

What's the most common bug in eSewa integrations?

Mismatched signature comparison — usually because the canonical string is built with the wrong field order or a stray space. Log the exact string you HMAC the first few times you run it; once you match eSewa's expected format the verification is rock-solid.

Do I need eSewa's production credentials to test this?

No — eSewa provides a UAT environment (epay.esewa.com.np with test merchant IDs and known signing keys). All development happens there; you only switch to production credentials when going live.

How does this differ from the Khalti integration?

Khalti uses an explicit verify-payment API call instead of a signed callback, and the signature scheme is different. The n8n workflow shape is similar (webhook → verify → update → notify) but the signature/verification step is different. See our Khalti webhook guide for the exact differences.

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.