Kotak Bank Payment Gateway - Automated payment verification using bank statement scraping
npm install kotak-payment-gatewayprocessLatestCSV() when no CSV files found
bash
npm install kotak-payment-gateway
`
Prerequisites
1. Kotak NetBanking Account with username and password
2. Gmail Account with App Password enabled for OTP retrieval
3. MongoDB instance running locally or remotely
$3
1. Enable 2-Factor Authentication on your Gmail account
2. Go to Google Account settings → Security → App passwords
3. Generate a new app password for "Mail"
4. Use this app password (not your regular Gmail password)
Usage
`javascript
const KotakPaymentGateway = require('kotak-payment-gateway');
// Initialize with your credentials
const paymentGateway = new KotakPaymentGateway({
kotakUsername: 'your_kotak_username',
kotakPassword: 'your_kotak_password',
email: 'your_email@gmail.com',
emailPassword: 'your_gmail_app_password',
mongoUrl: 'mongodb://localhost:27017/kotak_payments',
autoUpdate: true,
updateFrequency: 'hourly', // See frequency options below
headless: true, // Set to false to see browser automation
defaultPaymentTimeout: 3600000, // 1 hour default timeout
// UPI Configuration (Optional) - Enables automatic UPI for all payments
upiId: 'yourbusiness@paytm', // Your UPI ID
businessName: 'Your Business Name' // Name shown in UPI requests
});
// Initialize the gateway
await paymentGateway.init();
// Create a payment expectation with enhanced tracking
const payment = await paymentGateway.createPayment({
orderId: 'order123',
amount: 34.00,
customerName: 'John Doe',
customerEmail: 'john@example.com', // New field for notifications
timeout: 1800000, // 30 minutes (optional)
metadata: { source: 'website' } // Custom data tracking
});
// If UPI is configured, payment will automatically include:
// payment.upi.qrCode - Base64 encoded QR code
// payment.upi.upiUrl - UPI payment URL
// payment.upi.upiId - Your configured UPI ID
// payment.upi.payeeName - Your configured business name
// payment.upi.instructions - Step-by-step payment guide
// Enhanced verification with dual methods
const verification = await paymentGateway.verifyPayment('order371538', 34.00);
if (verification.verified) {
console.log('Payment verified:', verification.transaction);
console.log('Verification method:', verification.verificationMethod); // 'order_id' or 'transaction_id'
console.log('Data source:', verification.source); // 'database' or 'fresh_download'
} else {
console.log('Payment not found');
}
// Optional: Verify with UPI transaction ID for precision
const preciseVerification = await paymentGateway.verifyPayment('order123', 34.00, '562066460598');
// Third parameter is the UPI transaction ID from payment description
// Verify a payment (with transaction ID fallback)
const verificationWithTxId = await paymentGateway.verifyPayment('order371538', 34.00, '525159190814');
if (verificationWithTxId.verified) {
console.log('Payment verified via transaction ID:', verificationWithTxId.transaction);
console.log('Verification method:', verificationWithTxId.verificationMethod);
}
// Check payment status
const status = await paymentGateway.getPaymentStatus('order123');
console.log('Payment status:', status);
// Get all pending payments
const pending = paymentGateway.getPendingPayments();
console.log('Pending payments:', pending);
// Cancel a payment
const cancelled = await paymentGateway.cancelPayment('order123');
// Get transaction history
const history = await paymentGateway.getTransactionHistory({
limit: 10,
orderId: 'order123' // Optional filter
});
// Get gateway statistics
const stats = await paymentGateway.getStats();
console.log('Gateway stats:', stats);
// Force update statements
const updateResult = await paymentGateway.forceUpdate();
console.log('Updated:', updateResult.transactionsProcessed, 'transactions');
// Listen to payment events
paymentGateway.on('payment.created', (payment) => {
console.log('Payment created:', payment);
});
paymentGateway.on('payment.verified', (data) => {
console.log('Payment verified:', data);
});
paymentGateway.on('payment.expired', (data) => {
console.log('Payment expired:', data);
});
// Close when done
await paymentGateway.close();
`
Configuration Options
| Option | Type | Required | Default | Description |
|--------|------|----------|---------|-------------|
| kotakUsername | string | Yes | - | Your Kotak NetBanking username |
| kotakPassword | string | Yes | - | Your Kotak NetBanking password |
| email | string | Yes | - | Gmail address for OTP retrieval |
| emailPassword | string | Yes | - | Gmail app password |
| mongoUrl | string | Yes | - | MongoDB connection URL |
| autoUpdate | boolean | No | true | Enable automatic statement updates |
| updateFrequency | string | No | 'hourly' | Update frequency (see options below) |
| headless | boolean | No | true | Run browser in headless mode |
| defaultPaymentTimeout | number | No | 3600000 | Default payment timeout in milliseconds (1 hour) |
| upiId | string | No | null | Your UPI ID for automatic UPI payment generation |
| businessName | string | No | 'Payment' | Business name shown in UPI payment requests |
$3
| Frequency | Cron Pattern | Description |
|-----------|--------------|-------------|
| '1min' | * | Every minute |
| '5min' | /5 * | Every 5 minutes |
| '15min' | /15 * | Every 15 minutes |
| '30min' | /30 * | Every 30 minutes |
| 'hourly' | 0 | Every hour |
| '6hours' | 0 /6 | Every 6 hours |
| 'daily' | 0 0 * | Every day at midnight |
UPI Payment Integration
When you configure the gateway with upiId and businessName, all payments automatically include UPI payment options:
`javascript
const paymentGateway = new KotakPaymentGateway({
// ... other config
upiId: 'yourbusiness@paytm',
businessName: 'Your Business Name'
});
// Every payment will now automatically include UPI details
const payment = await paymentGateway.createPayment({
orderId: 'order123',
amount: 100.50
});
// The payment object will include:
// payment.upi.qrCode - Base64 encoded QR code image
// payment.upi.upiUrl - UPI payment URL (upi://pay?pa=...)
// payment.upi.upiId - Your UPI ID
// payment.upi.payeeName - Your business name
// payment.upi.instructions - Step-by-step payment instructions
`
$3
- Automatic QR Code Generation: Every payment gets a unique QR code
- Standard UPI URLs: Compatible with all UPI apps (GPay, PhonePe, Paytm, etc.)
- No Manual Configuration: Set once in gateway, applies to all payments
- Mobile Optimized: QR codes work perfectly on mobile devices
$3
- Google Pay (@ybl)
- PhonePe (@phonepe)
- Paytm (@paytm)
- BHIM (@upi)
- And many more...
API Reference
$3
Creates a new payment gateway instance with enhanced configuration options.
$3
Initializes the gateway with improved error handling:
- Connects to MongoDB with optimized indexing
- Verifies banking credentials with retry logic
- Initializes PaymentManager for lifecycle tracking
- Sets up event-driven architecture
- Starts auto-update scheduler if enabled
$3
Verifies a payment by order ID and amount, with optional transaction ID fallback.
Parameters:
- orderId (string): Order ID to verify (must start with "order")
- amount (number): Expected payment amount
- transactionId (string, optional): Transaction ID without "UPI-" prefix (e.g., "525159190814")
Returns:
`javascript
{
verified: true/false,
orderId: 'order123',
amount: 34.00,
transaction: { / transaction object / },
source: 'database' | 'fresh_download' | 'database_by_transaction_id' | 'fresh_download_by_transaction_id' | 'not_found',
verificationMethod: 'order_id' | 'transaction_id'
}
`
Transaction ID Format:
- User provides: 562066460598 (the actual UPI transaction ID from the description)
- System searches for: 562066460598 (exact match from UPI description field)
- Extracted from UPI descriptions like: UPI/Harshit Singh/562066460598/order5234
- Note: This is different from bank reference numbers like UPI-525417035804
$3
Creates a payment expectation for tracking.
Parameters:
`javascript
{
orderId: 'order123', // Required: Unique order identifier
amount: 34.00, // Required: Expected payment amount
customerName: 'John Doe', // Optional: Customer name
customerEmail: 'john@example.com', // Optional: Customer email
timeout: 1800000, // Optional: Payment timeout in milliseconds
metadata: {} // Optional: Additional data
}
`
Returns: Payment object with status 'pending'
$3
Gets the current status of a payment.
Returns:
`javascript
{
orderId: 'order123',
amount: 34.00,
status: 'pending' | 'verified' | 'expired' | 'cancelled',
createdAt: Date,
expiresAt: Date,
verifiedAt: Date,
verificationAttempts: 0,
// ... other fields
}
`
$3
Cancels a pending payment.
Returns: true if successfully cancelled, false otherwise
$3
Gets all currently pending payments (in-memory).
Returns: Array of pending payment objects
$3
Gets transaction history with optional filters.
Filters:
- orderId: Filter by specific order ID
- amount: Filter by amount
- type: Filter by transaction type ('DR' or 'CR')
- dateFrom: Start date
- dateTo: End date
- limit: Maximum number of results
$3
Forces an immediate statement download and processing.
$3
Returns gateway statistics (total transactions, verification requests).
$3
Manually control the auto-update scheduler.
$3
Closes the gateway and cleans up resources.
Events
The gateway emits events for real-time payment tracking:
$3
`javascript
// Payment created
gateway.on('payment.created', (payment) => {
console.log('New payment created:', payment);
});
// Payment verified
gateway.on('payment.verified', (data) => {
console.log('Payment verified:', data.payment);
console.log('Transaction:', data.transaction);
});
// Payment expired
gateway.on('payment.expired', (data) => {
console.log('Payment expired:', data.payment);
});
// Payment cancelled
gateway.on('payment.cancelled', (data) => {
console.log('Payment cancelled:', data.payment);
});
// Payment status changed
gateway.on('payment.status_changed', (data) => {
console.log('Status changed:', data.payment);
console.log('From:', data.oldStatus, 'To:', data.newStatus);
});
`
$3
`javascript
// New transactions processed
gateway.on('transactions.processed', (data) => {
console.log(Processed ${data.count} new transactions);
console.log('Transactions:', data.transactions);
});
// Gateway ready
gateway.on('ready', () => {
console.log('Gateway is ready for use');
});
`
Payment Verification Methods
The gateway supports two verification methods:
$3
The system automatically detects order IDs from transaction descriptions using multiple patterns:
- /Order123, /order123456
- order123 Premium, Order456 VPN
- orderid: 789, ref: abc123
Examples from Kotak statements:
- "UPI/HARSIT SINGH MG/690263874520/Order123" → "Order123"
- "UPI/HARSIT SINGH MG/690314512235/order1757278991" → "order1757278991"
- "UPI/HARSIT SINGH MG/389028010745/order210185 Clo" → "order210185"
$3
When order ID verification fails, users can manually provide the transaction ID:
Transaction ID Format:
- CSV contains: UPI-525159190814
- User provides: 525159190814 (without UPI- prefix)
- System automatically adds the UPI- prefix for matching
Use Cases:
- Order ID not found in transaction description
- Manual verification needed
- Backup verification method
- Customer support scenarios
`javascript
// Primary verification (by order ID)
const result1 = await gateway.verifyPayment('order123', 100.00);
// Fallback verification (with transaction ID)
const result2 = await gateway.verifyPayment('order123', 100.00, '525159190814');
// Check which method was used
console.log('Verified by:', result2.verificationMethod); // 'order_id' or 'transaction_id'
`
Database Schema
$3
`javascript
{
_id: ObjectId,
transactionDate: Date,
valueDate: Date,
description: String,
refNo: String,
amount: Number,
type: String, // 'DR' or 'CR'
balance: Number,
balanceType: String, // 'DR' or 'CR'
orderId: String, // Extracted from description
accountNo: String,
createdAt: Date,
updatedAt: Date
}
`
$3
`javascript
{
_id: ObjectId,
orderId: String, // Unique order identifier
amount: Number,
status: String, // 'pending', 'verified', 'expired', 'cancelled'
customerName: String,
customerEmail: String,
createdAt: Date,
expiresAt: Date,
verifiedAt: Date,
cancelledAt: Date,
verificationAttempts: Number,
transactionId: ObjectId, // Reference to transaction when verified
metadata: Object, // Additional custom data
updatedAt: Date
}
`
Error Handling
The gateway includes comprehensive error handling:
- Invalid credentials: Throws error during initialization
- Network issues: Retries with exponential backoff
- Email OTP failures: Returns meaningful error messages
- Database connection issues: Throws connection errors
- CSV parsing errors: Logs warnings and continues processing
Advanced Usage Examples
$3
`javascript
const gateway = new KotakPaymentGateway(config);
await gateway.init();
// When customer initiates payment
const payment = await gateway.createPayment({
orderId: order_${Date.now()},
amount: 299.99,
customerName: 'John Doe',
customerEmail: 'john@example.com',
timeout: 900000 // 15 minutes
});
// Show payment instructions to customer
console.log(Please pay ₹${payment.amount} with reference: ${payment.orderId});
// Listen for verification
gateway.on('payment.verified', async (data) => {
// Process successful payment
await processOrder(data.payment.orderId);
await sendConfirmationEmail(data.payment.customerEmail);
});
gateway.on('payment.expired', async (data) => {
// Handle expired payment
await cancelOrder(data.payment.orderId);
});
`
$3
`javascript
// Check recurring payments
const checkSubscriptions = async () => {
const recentTransactions = await gateway.getTransactionHistory({
dateFrom: new Date(Date.now() - 24 60 60 * 1000), // Last 24 hours
type: 'CR' // Credit transactions
});
for (const transaction of recentTransactions) {
if (transaction.orderId && transaction.orderId.startsWith('sub_')) {
await renewSubscription(transaction.orderId, transaction.amount);
}
}
};
// Run subscription check every hour
setInterval(checkSubscriptions, 3600000);
`
$3
`javascript
const express = require('express');
const app = express();
// Setup webhook endpoint
app.post('/webhook/payment-verified', (req, res) => {
const { orderId, amount, transactionId } = req.body;
console.log(Payment verified: ${orderId} - ₹${amount});
res.status(200).send('OK');
});
// Forward gateway events to webhook
gateway.on('payment.verified', async (data) => {
await fetch('http://your-app.com/webhook/payment-verified', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
});
`
Examples
See the examples/ directory for complete usage examples:
`bash
npm start
`
Troubleshooting
$3
1. "Credential verification failed"
- Check Kotak username/password
- Ensure 2FA is enabled for NetBanking
- Verify Gmail app password is correct
2. "No OTP emails found"
- Check Gmail inbox for Kotak OTP emails
- Verify email configuration
- Ensure IMAP is enabled in Gmail
3. "MongoDB connection failed"
- Verify MongoDB is running
- Check connection URL format
- Ensure database permissions
4. "Payment not found"
- Verify order ID format in transaction description
- Check if transaction amount matches exactly
- Try force update to get latest statements
- Check if payment has expired or been cancelled
5. "Payment timeout/expired"
- Check defaultPaymentTimeout configuration
- Verify payment was made within timeout window
- Consider increasing timeout for specific payments
6. Auto-update not working
- Verify cron pattern for updateFrequency
- Check system time and timezone
- Ensure gateway remains initialized
- Monitor logs for scheduler errors
$3
Set headless: false to see the browser automation in action:
`javascript
const gateway = new KotakPaymentGateway({
// ... other config
headless: false // Shows browser window
});
`
Security Notes
- Store credentials securely (use environment variables)
- Use MongoDB authentication in production
- Keep Gmail app passwords secure
- Consider running in a secure, isolated environment
Version 1.2.0 Highlights
$3
- Complete Payment Lifecycle Management: From creation to verification or expiration
- Dual Verification System: Primary order ID matching with transaction ID fallback
- Real-time Event Architecture: Instant notifications for all payment status changes
- Enhanced Performance: Memory optimization and database indexing improvements
- Advanced Analytics: Comprehensive payment statistics and success rate tracking
$3
- PaymentManager Class: Centralized payment operations with timeout management
- Event-Driven Design: Real-time payment status updates and notifications
- Improved Error Handling: Exponential backoff retry logic for better reliability
- Database Optimization: Proper indexing and query performance improvements
- Memory Management: In-memory pending payment tracking for faster operations
$3
- Force Update API: Manual statement refresh for immediate processing
- Payment Cancellation: Cancel pending payments programmatically
- Advanced Filtering: Query transaction history with multiple criteria
- Verification Methods: Track which verification method was successful
- Auto-Expiry System: Configurable payment timeouts with automatic cleanup
Migration from v1.1.x
Version 1.2.0 is backward compatible, but takes advantage of new features:
`javascript
// Old way (still works)
const verification = await gateway.verifyPayment('order123', 100.00);
// New way with transaction ID fallback
const verification = await gateway.verifyPayment('order123', 100.00, '525159190814');
// New payment creation with enhanced features
const payment = await gateway.createPayment({
orderId: 'order123',
amount: 100.00,
customerName: 'John Doe',
customerEmail: 'john@example.com', // New field
timeout: 1800000, // 30 minutes
metadata: { source: 'api', version: '1.2.0' } // New field
});
`
Changelog
$3
#### 🔄 Critical Download System Overhaul
- Smart Download Verification: Enhanced verifyDownloadSuccess() to return boolean success status instead of just logging
- Intelligent Retry Mechanism: Implemented automatic retry system (up to 3 attempts) when CSV download verification fails
- Login State Recovery: Added proper login state reset (isLoggedIn = false) before each retry attempt
- Infinite Recursion Fix: Eliminated deadly infinite loop in processLatestCSV() by removing recursive forceUpdate() call
#### 🛠️ Advanced Error Recovery & Retry Logic
- Multi-Level Retry System: Separate retry strategies for download failures vs login failures
- Progressive Delay Implementation: Smart wait times (3s for download retries, 5s for login failures)
- Session State Management: Automatic browser session cleanup and state reset between attempts
- Timeout Protection: Added 30-second timeout for concurrent processing to prevent permanent deadlocks
#### 🔍 Enhanced Debugging & Monitoring
- Detailed Attempt Logging: Clear visibility into retry attempts with numbered attempts (1/3, 2/3, 3/3)
- Download Verification Feedback: Real-time feedback on CSV files found with file sizes and modification timestamps
- Failure Classification: Different error handling and messaging for different failure types
- Success Rate Tracking: Improved logging to track success/failure patterns across attempts
#### 🚀 Stability & Performance Improvements
- Deadlock Prevention: Eliminated all scenarios that could cause infinite waiting or processing loops
- Memory Leak Prevention: Proper downloadInProgress flag cleanup on all exit paths
- Resource Management: Enhanced browser state management and automatic cleanup processes
- Cross-Platform Reliability: Robust file detection that works consistently on Windows, macOS, and Linux
$3
#### 🐛 Critical Bug Fixes
- Fixed Infinite Loop: Resolved duplicate downloadInProgress flags causing endless "Download already in progress" cycles
- Enhanced CSV File Detection: Improved cross-platform CSV cleanup with multiple detection strategies (glob + fs.readdir fallbacks)
- Race Condition Protection: Added comprehensive locking mechanism to prevent CSV cleanup during active processing
- Download State Synchronization: Unified download progress tracking between gateway and scraper modules
#### 🔧 Technical Improvements
- Smart Processing Lock: Added processingCSV flag with timeout protection to prevent file conflicts
- Cross-Platform Compatibility: Enhanced file operations for reliable performance on Windows, macOS, and Linux
- Robust Error Recovery: Improved handling of concurrent operations and download failures
- Enhanced Logging: Added detailed operation logging for better debugging and monitoring
#### 🚀 Performance & Stability
- Eliminated Race Conditions: Comprehensive protection for concurrent download and processing operations
- Memory Optimization: Better resource management and automatic cleanup processes
- Platform Reliability: Enhanced compatibility and error handling across different operating systems
- Graceful Degradation: Better handling of edge cases and network interruptions
$3
#### 🐛 Bug Fixes
- Download Progress Tracking: Fixed issues with download state management
- Error Handling: Improved error recovery during statement downloads
- Browser Session Management: Enhanced stability for long-running sessions
$3
#### 🆕 New Features
- UPI Payment Integration: Complete UPI payment support with QR code generation
- Gateway-Level UPI Configuration: Set UPI ID and business name once for all payments
- Transaction ID Verification: Support for direct UPI transaction ID verification
- Enhanced Demo UI: Interactive QR codes, copy-to-clipboard, and mobile-optimized interface
#### 🔧 Improvements
- Automatic QR Code Generation: Base64-encoded QR codes for every UPI payment
- Dual Verification System: Order ID + Transaction ID verification methods
- Verification Source Tracking: Track which verification method was used
- Mobile Responsive UPI Interface: Optimized for all devices and UPI apps
#### 📦 Dependencies
- Added: qrcode@^1.5.4` for QR code generation