How To Integrate Esewa Payment Gateway (V2) In Laravel & Vue 3
Published on May 5, 2025 by Bswatantra

How to Integrate eSewa Payment Gateway (V2) in Laravel & Vue 3
Prerequisites
Before you begin, ensure the following tools and configurations are set up:
- PHP 8.3+
- Composer
- Laravel 11 or 12
- Vue 3
- Postman (for API testing)
- A modern code editor (e.g., VS Code)
eSewa Documentation
Step 1: Set Up Payment Initialization (Backend - Laravel)
1. Create API Routes
// routes/api.php use App\Http\Controllers\PaymentController; Route::prefix('esewa')->controller(PaymentController::class)->group(function () { Route::post('/initiate-payment', 'initiatePayment'); Route::get('/verify-payment', 'verifyPayment');});
2. Create initiatePayment
Method
// app/Http/Controllers/PaymentController.php use Illuminate\Support\Facades\Http;use Illuminate\Http\Request; public function initiatePayment(Request $request){ $taxAmount = 0; $totalAmount = $request->amount; $transactionUuid = str()->uuid(); $productCode = config('payment.esewa.product_code'); $successUrl = url("/api/esewa/verify-payment"); $failureUrl = config('payment.esewa.redirect') . 'payment/failure'; $message = "total_amount={$totalAmount},transaction_uuid={$transactionUuid},product_code={$productCode}"; $signature = base64_encode(hash_hmac('sha256', $message, config('payment.esewa.secret_key'), true)); $paymentData = [ 'amount' => $totalAmount, 'tax_amount' => $taxAmount, 'total_amount' => $totalAmount, 'transaction_uuid' => $transactionUuid, 'product_code' => $productCode, 'product_service_charge' => 0, 'product_delivery_charge' => 0, 'success_url' => $successUrl, 'failure_url' => $failureUrl, 'signed_field_names' => 'total_amount,transaction_uuid,product_code', 'signature' => $signature, 'api_endpoint' => config('payment.esewa.base_url') . '/api/epay/main/v2/form', ]; return response()->json(['data' => $paymentData]);}
3. Create Configuration File
// config/payment.php return [ 'esewa' => [ 'redirect' => env('ESEWA_REDIRECT_URL'), 'base_url' => env('ESEWA_BASE_URL'), 'secret_key' => env('ESEWA_SECRET_KEY'), 'product_code' => env('ESEWA_MERCHANT_CODE'), ],];
4. Add Environment Variables
// .env ESEWA_BASE_URL=https://rc-epay.esewa.com.npESEWA_SECRET_KEY=your_secret_key_hereESEWA_MERCHANT_CODE=EPAYTESTESEWA_REDIRECT_URL=http://localhost:9000/
💡 Run
php artisan config:cache
after updating the.env
file.
Step 2: Payment Verification (Backend - Laravel)
Create verifyPayment
Method
// app/Http/Controllers/PaymentController.php public function verifyPayment(Request $request){ $result = json_decode(base64_decode($request->data), true); $params = [ "product_code" => $result['product_code'], "total_amount" => str_replace(',', '', $result['total_amount']), "transaction_uuid" => $result['transaction_uuid'] ]; $response = Http::get(config('payment.esewa.base_url') . '/api/epay/transaction/status/', $params); if ($response->successful()) { $data = $response->json(); if ($data['status'] === 'COMPLETE') { return redirect(config('payment.esewa.redirect') . "payment/success"); } } return redirect(config('payment.esewa.redirect') . "payment/failed");}
Step 3: Frontend Integration (Vue 3)
1. Define Route
// router/index.js or similar { path: "/payment/esewa", name: "EsewaPayment", component: () => import("src/pages/payment/Esewa.vue"),}
2. Create Esewa.vue
Component
<!-- src/pages/payment/Esewa.vue --> <script setup>import axios from 'axios'; const initiatePayment = () => { axios.post('http://localhost:8000/api/esewa/initiate-payment', { amount: 100 // replace with dynamic value if needed }) .then((response) => { const result = response.data.data; const form = document.createElement("form"); form.method = "POST"; form.action = result.api_endpoint; for (const key in result) { const input = document.createElement("input"); input.type = "hidden"; input.name = key; input.value = result[key]; form.appendChild(input); } document.body.appendChild(form); form.submit(); }) .catch((error) => { console.error("Payment initiation failed:", error.response?.data?.message || error.message); });};</script> <template> <div> <h1>eSewa Payment Integration</h1> <button @click="initiatePayment">Pay with eSewa</button> </div></template>
Final Notes
- Always use secure HTTPS in production.
- Log payment data for security audits.
- Follow eSewa documentation for any new changes.
- Never expose secret keys to the frontend.
Happy coding! 💻💸

Filed in: