Skip to content
Troubleshooting⏱️ 11 min read·

“Invalid Signature” Error in eSewa: 5 Causes and Exact Fixes (2026 Developer Guide)

Stuck with 'Invalid Signature' on eSewa ePay v2? Here are the 5 exact cryptographic and formatting mistakes developers make in Node.js, Laravel, and Python, along with copyable verified fixes.

MN
Manoj NeupaneSoftware Developer & Programming Instructor
#eSewa#Invalid Signature#HMAC-SHA256#PHP#Laravel#Node.js#Error Fix
🎯 Who This Tutorial Is For

📋 Prerequisites
  • ✓An active project attempting eSewa ePay v2 integration
  • ✓Access to your signature generation code in PHP, Node.js, or Python

🚀 What You Will Learn & Build

  • ▸The exact string concatenation formula expected by eSewa v2
  • ▸Why float to string formatting breaks the HMAC hash
  • ▸The secret key binary vs string encoding trap in PHP and Node.js
  • ▸How to debug your hash using standard CLI tools
1

The 5 Reasons eSewa Rejects Your Signature

When eSewa's gateway displays **"Invalid Signature"**, it means the `signature` parameter in your form submission does not match the HMAC-SHA256 hash eSewa calculated on their server. Here are the 5 exact causes: ### 1. Wrong Concatenation Order in signed_field_names eSewa calculates the signature strictly over the fields listed in `signed_field_names`. The standard v2 fields are: `total_amount,transaction_uuid,product_code`. Your string **must** look like: `total_amount=100.00,transaction_uuid=123-abc,product_code=EPAYTEST` If you swap the order or add extra spaces, the signature is invalid. ### 2. Float and Decimal Number Formatting Bug If your form sends `total_amount: 100`, but your hash was generated with `100.00` (or vice versa), the hashes differ. Always normalize the string representation in both the hash and form payload. ### 3. Binary vs. Hex Output in hash_hmac In PHP, `hash_hmac('sha256', $data, $key, true)` must have the 4th parameter set to `true` (raw binary) before passing to `base64_encode()`. If you omit `true`, it outputs hex string, resulting in an invalid signature. ### 4. Whitespace or Quotes in Secret Key A trailing newline or carriage return (`\r\n`) in your `.env` file when copying `8gBm/:&EnhH.1/q` will corrupt the key. Always run `trim()` on environment variables. ### 5. Encoding Mismatches in Success Callback In the return URL, eSewa passes base64 encoded JSON in the `data` parameter. If you attempt to verify the return signature against individual query parameters instead of the decoded payload, verification fails.
2

Verified Working Implementation (Node.js & PHP)

Use these tested helper functions to generate 100% valid signatures:
const crypto = require("crypto");

function generateEsewaSignature(secretKey, totalAmount, transactionUuid, productCode) {
  // 1. Format totalAmount consistently
  const formattedAmount = Number(totalAmount).toFixed(2);
  
  // 2. Build exact concatenation string
  const dataToSign = `total_amount=${formattedAmount},transaction_uuid=${transactionUuid},product_code=${productCode}`;
  
  // 3. Generate raw binary HMAC-SHA256 and convert to base64
  const hmac = crypto.createHmac("sha256", secretKey.trim());
  hmac.update(dataToSign);
  const signature = hmac.digest("base64");
  
  return { signature, formattedAmount, dataToSign };
}

// Test with eSewa Sandbox values
const { signature, dataToSign } = generateEsewaSignature(
  "8gBm/:&EnhH.1/q",
  100,
  "241018-001",
  "EPAYTEST"
);
console.log("Input:", dataToSign);
console.log("Valid Signature:", signature);

✨ Expected Output & Verification

Immediate elimination of the 'Invalid Signature' error screen and smooth progression to the eSewa login view.

🧪 How to Test the Implementation

  1. 1Inspect the generated signature using the Node.js test script above
  2. 2Ensure form inputs in your Blade or React view exactly match the dataToSign string
  3. 3Verify .env secret key has no trailing space using trim(env('ESEWA_SECRET_KEY'))

⚠️ Common Errors & How to Fix Them

❌Sending hash_hmac hex string to base64_encode in PHP

Root Cause: Default hash_hmac outputs 64 hex characters. eSewa expects base64 encoded 32-byte raw binary.

Fix: Pass true as the 4th argument in hash_hmac('sha256', $data, $key, true).

🛡️ Security Considerations & Best Practices

  • !Never generate signatures on the client side in JavaScript. The secret key must remain private to your server.

❓ Frequently Asked Questions (FAQ)

The legacy eSewa v1 API used MD5 which is cryptographically broken and vulnerable to collision attacks. ePay v2 adopted modern HMAC-SHA256 to ensure authenticity and integrity.

📌 Summary of Key Takeaways

The eSewa Invalid Signature error is always caused by data concatenation mismatches, float formatting differences, or missing raw binary flags in HMAC generation.

Official References & Further Reading