/** * Test script to verify PAN API through localhost * This script tests the Setu API integration through your local API server * Usage: node scripts/test-localhost-pan.js */ require('dotenv').config(); const axios = require('axios'); const crypto = require('crypto'); const { query, connectDB } = require('../src/database/connection'); // Static Setu API credentials (from your curl command) const SETU_CREDENTIALS = { PAN_PROVIDER_URL: 'https://dg-sandbox.setu.co/api/verify/pan', PAN_CLIENT_ID: '292c6e76-dabf-49c4-8e48-90fba2916673', PAN_CLIENT_SECRET: '7IZMe9zvoBBuBukLiCP7n4KLwSOy11oP', PAN_PRODUCT_INSTANCE_ID: '439244ff-114e-41a8-ae74-a783f160622d' }; const LOCALHOST_URL = process.env.LOCALHOST_URL || 'http://localhost:3000'; const TEST_PAN = 'ABCDE1234A'; // Function to generate API key function generateApiKey(type = 'test') { const prefix = type === 'test' ? 'vf_test_' : 'vf_live_'; return prefix + crypto.randomBytes(24).toString('hex'); } // Function to create or get test API key async function getOrCreateTestApiKey() { try { await connectDB(); // Check if test user exists let testUser = await query( 'SELECT * FROM users WHERE email = $1', ['test@example.com'] ); let userId; if (testUser.rows.length === 0) { // Create test user const bcrypt = require('bcryptjs'); const passwordHash = await bcrypt.hash('testpassword123', 10); const userResult = await query( `INSERT INTO users (email, password_hash, company_name, plan, monthly_quota, quota_reset_date, is_active) VALUES ($1, $2, $3, $4, $5, DATE(NOW() + INTERVAL '1 month'), true) RETURNING id, email, plan`, ['test@example.com', passwordHash, 'Test Company', 'free', 10000] ); userId = userResult.rows[0].id; } else { userId = testUser.rows[0].id; } // Check for existing active test API key const existingKeys = await query( `SELECT ak.* FROM api_keys ak WHERE ak.user_id = $1 AND ak.is_test_key = true AND ak.is_active = true ORDER BY ak.created_at DESC LIMIT 1`, [userId] ); if (existingKeys.rows.length > 0) { // We can't retrieve the original key, so we'll need to create a new one // But first, let's try to use the existing one by checking if we can authenticate // For now, let's create a new one to be safe console.log(' ℹ️ Found existing test API key, creating a new one...'); // Deactivate old keys await query( 'UPDATE api_keys SET is_active = false WHERE user_id = $1 AND is_test_key = true', [userId] ); } // Generate new API key const apiKey = generateApiKey('test'); const keyHash = crypto.createHash('sha256').update(apiKey).digest('hex'); await query( `INSERT INTO api_keys (user_id, key_prefix, key_hash, key_hint, name, is_test_key, is_active) VALUES ($1, $2, $3, $4, $5, true, true)`, [userId, 'vf_test_', keyHash, apiKey.slice(-4), 'Test Key'] ); return apiKey; } catch (error) { console.error(' ❌ Error creating API key:', error.message); throw error; } } // Function to check if server is running async function checkServerRunning() { try { const response = await axios.get(`${LOCALHOST_URL}/health`, { timeout: 3000 }); return response.status === 200; } catch (error) { return false; } } // Function to update .env file with Setu credentials async function updateEnvFile() { const fs = require('fs'); const path = require('path'); const envPath = path.join(__dirname, '..', '.env'); try { let envContent = ''; // Read existing .env if it exists if (fs.existsSync(envPath)) { envContent = fs.readFileSync(envPath, 'utf8'); } // Update or add Setu credentials const updates = { 'PAN_PROVIDER_URL': SETU_CREDENTIALS.PAN_PROVIDER_URL, 'PAN_CLIENT_ID': SETU_CREDENTIALS.PAN_CLIENT_ID, 'PAN_CLIENT_SECRET': SETU_CREDENTIALS.PAN_CLIENT_SECRET, 'PAN_PRODUCT_INSTANCE_ID': SETU_CREDENTIALS.PAN_PRODUCT_INSTANCE_ID }; let updated = false; for (const [key, value] of Object.entries(updates)) { const regex = new RegExp(`^${key}=.*$`, 'm'); if (regex.test(envContent)) { envContent = envContent.replace(regex, `${key}=${value}`); updated = true; } else { // Add new line if file doesn't end with newline if (envContent && !envContent.endsWith('\n')) { envContent += '\n'; } envContent += `${key}=${value}\n`; updated = true; } } if (updated) { fs.writeFileSync(envPath, envContent, 'utf8'); console.log(' ✅ Updated .env file with Setu credentials'); return true; } return false; } catch (error) { console.log(' ⚠️ Could not update .env file:', error.message); console.log(' ℹ️ Please manually add these to your .env file:'); console.log(` PAN_PROVIDER_URL=${SETU_CREDENTIALS.PAN_PROVIDER_URL}`); console.log(` PAN_CLIENT_ID=${SETU_CREDENTIALS.PAN_CLIENT_ID}`); console.log(` PAN_CLIENT_SECRET=${SETU_CREDENTIALS.PAN_CLIENT_SECRET}`); console.log(` PAN_PRODUCT_INSTANCE_ID=${SETU_CREDENTIALS.PAN_PRODUCT_INSTANCE_ID}`); return false; } } // Main test function async function testLocalhostPAN() { console.log('\n🧪 Testing PAN API through Localhost\n'); console.log('='.repeat(70)); // Step 1: Check server is running console.log('\n📡 Step 1: Checking if server is running...'); const serverRunning = await checkServerRunning(); if (!serverRunning) { console.log(' ❌ Server is not running!'); console.log('\n Please start the server first:'); console.log(' npm start'); console.log(' or'); console.log(' npm run dev'); process.exit(1); } console.log(' ✅ Server is running on', LOCALHOST_URL); // Step 2: Update .env file with Setu credentials console.log('\n⚙️ Step 2: Setting up Setu API credentials...'); const envUpdated = await updateEnvFile(); if (envUpdated) { console.log(' ⚠️ Note: If your server was already running, restart it to load new credentials'); console.log(' Restart command: Press Ctrl+C and run "npm start" again'); } // Step 3: Create/get API key console.log('\n🔑 Step 3: Creating test API key...'); let apiKey; try { apiKey = await getOrCreateTestApiKey(); console.log(' ✅ Test API key created:', apiKey); } catch (error) { console.log(' ❌ Failed to create API key:', error.message); console.log(' Make sure your database is running and migrations are applied'); process.exit(1); } // Step 4: Test the API endpoint console.log('\n🚀 Step 4: Testing PAN verification endpoint...'); console.log(` URL: ${LOCALHOST_URL}/v1/pan/verify`); console.log(` PAN: ${TEST_PAN}`); try { const startTime = Date.now(); const response = await axios.post( `${LOCALHOST_URL}/v1/pan/verify`, { pan: TEST_PAN, consent: 'Y', reason: 'Testing' }, { headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey }, timeout: 30000 } ); const endTime = Date.now(); const duration = endTime - startTime; console.log('\n ✅ SUCCESS! API is working correctly!\n'); console.log('='.repeat(70)); console.log('\n📊 Response Details:'); console.log(` Status Code: ${response.status} ${response.statusText}`); console.log(` Response Time: ${duration}ms`); console.log(`\n📦 Response Body:`); console.log(JSON.stringify(response.data, null, 2)); if (response.data.success && response.data.data) { console.log('\n✅ PAN Verification Successful!'); if (response.data.data.full_name) { console.log(` PAN Holder: ${response.data.data.full_name}`); } if (response.data.data.status) { console.log(` Status: ${response.data.data.status}`); } } console.log('\n' + '='.repeat(70)); console.log('\n✅ All tests passed! Your localhost API is working correctly!\n'); } catch (error) { console.log('\n ❌ ERROR! API request failed!\n'); console.log('='.repeat(70)); if (error.response) { console.log('\n📊 Error Response:'); console.log(` Status Code: ${error.response.status} ${error.response.statusText}`); console.log(`\n📦 Error Body:`); console.log(JSON.stringify(error.response.data, null, 2)); console.log('\n⚠️ Possible Issues:'); if (error.response.status === 401) { console.log(' - Invalid API key (try running this script again to create a new key)'); } else if (error.response.status === 500) { console.log(' - Server error (check server logs)'); console.log(' - Make sure Setu credentials are in .env file'); console.log(' - Restart the server after updating .env'); } else if (error.response.status === 400) { console.log(' - Bad request (check PAN format)'); } } else if (error.request) { console.log('\n⚠️ No response received from server'); console.log(` Error: ${error.message}`); console.log('\n Possible Issues:'); console.log(' - Server is not running'); console.log(' - Wrong URL (check LOCALHOST_URL)'); console.log(' - Network connectivity problem'); } else { console.log(`\n⚠️ Request setup error: ${error.message}`); } console.log('\n' + '='.repeat(70)); console.log('\n❌ Test failed!\n'); process.exit(1); } } // Run the test testLocalhostPAN().catch(error => { console.error('\n❌ Unexpected error:', error.message); console.error(error); process.exit(1); });