Integrating eSewa, Khalti Payment & Dynamic Fonepay QR Gateways in .NET Applications
Integrating eSewa, Khalti Payment & Dynamic Fonepay QR Gateways in .NET Applications
Integrating eSewa, Khalti Payment & Dynamic Fonepay QR Gateways in .NET Applications

My phone buzzed. It was my brother — CSIT student, second year, probably surviving on noodles and tei dai ko sasto Mo:mo.
“Dai, 3 days bhayo. Khalti integrate hunna. Project submission Monday ho.”
I knew that panic. That specific brand of developer anxiety when:
- The deadline is breathing down your neck
- The documentation makes sense… until it doesn’t
- You’ve rewritten the same code 17 times
- You’re questioning your career choices
“Video call gar,” I replied.
The Screen Share of…
His screen was a beautiful disaster:
- 23 Brave tabs open (12 of them AI)
- Rider with more red squiggles than actual code
“Dai, documentation ma yo lekheko cha. Tara mildai milena.”
I smiled. Not because it was funny. But because I’d been there. We’ve ALL been there.
Rewind: 2022 (Probably). TU Convocation Season.
It was convocation form filling season. TU students everywhere were trying to pay online.
Khalti team pinged me.
“Sushil, developers are struggling to integrate our API. Can you help?”
Back then, I thought, “How hard can payment integration be?”
Spoiler alert: Hard enough that people were giving up and going back to bank deposits. In 2022. In Nepal. Where country were desperately trying to go digital.
So I built plugin.web.eSewa.and.Khalti.
Developers downloaded it. Projects shipped. Crisis averted.
I moved on. Built other stuff. Forgot about it.
Lol…
My brother’s call was a wake-up call.
I pulled up my old package. The code looked like it was written by someone who just discovered async/await and went wild with it. The package name was longer than some of my functions. And the architecture? Let’s just say “extensible” wasn’t in the vocabulary.
“What happens when Fonepay becomes popular?”
“What about that new gateway launching next month?”
The answer: Copy-paste chaos. Refactor hell. Developer tears.
Nope. Not on my watch.
Renamed: Nepal.Payments.Gateways
I did what any reasonable developer would do at midnight: Started a complete rewrite.
- If my brother can’t use it, it’s too complicated
- Support both V1 and V2 APIs (because some gateways still need V1)
The result? This:
// Step 1: Initialize (same for ALL gateways)
// using Nepal.Payments.Gateways.Models.Khalti.PaymentRequest
var paymentManager = new PaymentManager(
paymentMethod: PaymentMethod.Khalti, // or Esewa, or Fonepay (coming soon!)
paymentVersion: PaymentVersion.V2,
paymentMode: PaymentMode.Sandbox,
secretKey: _khaltiSecretKey
);
// Step 2: Create request
var request = new PaymentRequest()
{
Amount = 1300,
PurchaseOrderId = "order_" + DateTime.Now.Ticks,
CustomerInfo = new CustomerInfo
{
Name = "Your Customer",
Email = "customer@email.com",
Phone = "98XXXXXXXX"
},
ProductDetails = new[]
{
new ProductDetail
{
Name = "Your Product",
TotalPrice = 1300,
Quantity = 1
}
}
};
// Step 3: Get payment URL and redirect
var response = await paymentManager.InitiatePaymentAsync<dynamic>(request);
return Redirect(response.Data.PaymentUrl);
That’s it. Three steps. You can skip the official documentation but don’t trust me.
“But Dai, What About Verification?”
Even simpler:
var paymentManager = new PaymentManager(
paymentMethod: PaymentMethod.Khalti,
paymentVersion: PaymentVersion.V2,
paymentMode: PaymentMode.Sandbox,
secretKey: _khaltiSecretKey
);
var response = await paymentManager.VerifyPaymentAsync<dynamic>(pidx);
if (response?.Data is PaymentResponse v)
{
Console.WriteLine($"Paid: Rs. {v.TotalAmount}");
Console.WriteLine($"Transaction: {v.TransactionId}");
// Party time! vanna hunthyo raksi khadainas...ehh piudainas
}
eSewa? Copy-Paste-Change-One-Line
// Literally just change this line:
// using Nepal.Payments.Gateways.Models.Esewa.PaymentRequest
paymentMethod: PaymentMethod.Esewa // Was: PaymentMethod.Khalti
// Everything else? EXACTLY THE SAME.
That’s the magic. Same pattern. Same structure. Different gateway.
“Dai, Testing Kasari Garney?”
Ah, the million rupee question. Here’s the cheat sheet (bookmark this!):
https://payments-demo.sksushil.info.np/Payment
eSewa Test Credentials:
Username: 9806800001 (or 2/3/4/5)
Password: Nepal@123
Token: 123456
Merchant ID: EPAYTEST
Secret Key: 8gBm/:&EnhH.1/q
Khalti Test Credentials:
Mobile Number: 9800000001 (or 2/3/4/5)
Pin: 1111
OTP: 987654
Secret Key: live_secret_key_68791341fdd94846a146f0457ff7b455
Pro tip: Screenshot this. Trust me, you’ll need it at 3 AM when you’re testing payments.
Version Support (V1 & V2)
Both gateways have evolved over time. The package supports both versions:
// For newer implementations
paymentVersion: PaymentVersion.V2
// For legacy systems
paymentVersion: PaymentVersion.V1
Just specify the version, and the package handles the rest. No need to rewrite your entire codebase when APIs evolve.
The REAL Test
I sent the package to my brother.
Me: “Try this.” Him: (30 minutes later) “Dai, kaam bhayo!” Me: “Demo pathai.” Him: (sent video of successful payment) Me: “la mojj gares.”
If he can integrate it at midnight, I’d call that a win.
What’s Cooking Next?
Fonepay Dynamic QR is in the works.
Imagine:
var qrManager = new PaymentManager(
paymentMethod: PaymentMethod.FonepayQR,
...
);
var qrCode = await qrManager.GenerateQRAsync(amount, reference);
// Boom. QR code ready.
Same pattern. New gateway. Zero headaches.
Get Started (Seriously, It Takes 2 Minutes)
dotnet add package Nepal.Payments.Gateways
Real Talk
Look, I’m not building this because I’m some coding wizard.
I’m building it because my brother was panicking about a project deadline.
Because somewhere right now, a developer in Pokhara is staring at Khalti/Esewa documentation wondering why their callback isn’t working.
Because in Butwal, someone just spent 6 hours debugging a signature mismatch.
Because we’ve ALL been that person.
If this package saves you even one hour debugging session, if it helps you ship your project on time…
Then it was worth rebuilding.
메타데이터
- post_id
- 7c6c1e66da59
- slug
- dai-khalti-integration-gardai-chu-help-7c6c1e66da59
- url
- https://medium.com/@shoesheill/dai-khalti-integration-gardai-chu-help-7c6c1e66da59
- canonical_url
- https://medium.com/@shoesheill/dai-khalti-integration-gardai-chu-help-7c6c1e66da59
- author_url
- https://medium.com/@shoesheill
- status
- ok
- fetched_at
- 2026-07-16 18:24:12