import { NextRequest, NextResponse } from 'next/server' import jwt from 'jsonwebtoken' import crypto from 'crypto' interface AddBalanceRequest { amount: number currency: 'INR' | 'USD' } interface UserTokenPayload { siliconId: string email: string type: string } /** * Add Balance API * Initiates "Add Balance" transaction for user accounts */ export async function POST(request: NextRequest) { try { // Verify user authentication const token = request.cookies.get('accessToken')?.value if (!token) { return NextResponse.json( { success: false, message: 'Authentication required' }, { status: 401 } ) } const secret = process.env.JWT_SECRET || 'your-secret-key' const user = jwt.verify(token, secret) as UserTokenPayload // Parse request body const body: AddBalanceRequest = await request.json() const { amount, currency } = body // Validate input if (!amount || amount <= 0 || !['INR', 'USD'].includes(currency)) { return NextResponse.json( { success: false, message: 'Invalid amount or currency' }, { status: 400 } ) } // Validate amount limits const minAmount = currency === 'INR' ? 100 : 2 // Minimum ₹100 or $2 const maxAmount = currency === 'INR' ? 100000 : 1500 // Maximum ₹1,00,000 or $1500 if (amount < minAmount || amount > maxAmount) { return NextResponse.json( { success: false, message: `Amount must be between ${currency === 'INR' ? '₹' : '$'}${minAmount} and ${currency === 'INR' ? '₹' : '$'}${maxAmount}`, }, { status: 400 } ) } try { // Generate unique transaction ID const transactionId = generateTransactionId() // TODO: Save transaction to database // In real implementation: // await saveAddBalanceTransaction({ // siliconId: user.siliconId, // amount, // currency, // transaction_id: transactionId, // status: 'pending' // }) // Mock database save for demo await mockSaveAddBalanceTransaction(user.siliconId, amount, currency, transactionId) // PayU configuration const merchantKey = process.env.PAYU_MERCHANT_KEY || 'test-key' const merchantSalt = process.env.PAYU_MERCHANT_SALT || 'test-salt' const payuUrl = process.env.PAYU_URL || 'https://test.payu.in/_payment' // Prepare payment data const productinfo = 'add_balance' const firstname = 'Customer' const email = user.email const phone = '9876543210' // Default phone or fetch from user profile // Success and failure URLs for balance transactions const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:4024' const surl = `${baseUrl}/api/balance/success` const furl = `${baseUrl}/api/balance/failure` // Generate PayU hash const hashString = `${merchantKey}|${transactionId}|${amount}|${productinfo}|${firstname}|${email}|||||||||||${merchantSalt}` const hash = crypto.createHash('sha512').update(hashString).digest('hex') // Return payment form data for frontend submission const paymentData = { success: true, transaction_id: transactionId, currency, payment_url: payuUrl, form_data: { key: merchantKey, txnid: transactionId, amount: amount.toFixed(2), productinfo, firstname, email, phone, surl, furl, hash, service_provider: 'payu_paisa', }, } return NextResponse.json(paymentData) } catch (dbError) { console.error('Database error during add balance:', dbError) return NextResponse.json( { success: false, message: 'Failed to initiate balance transaction' }, { status: 500 } ) } } catch (error) { console.error('Add balance error:', error) return NextResponse.json( { success: false, message: 'Add balance initiation failed' }, { status: 500 } ) } } /** * Get Add Balance History */ export async function GET(request: NextRequest) { try { // Verify user authentication const token = request.cookies.get('accessToken')?.value if (!token) { return NextResponse.json( { success: false, message: 'Authentication required' }, { status: 401 } ) } const secret = process.env.JWT_SECRET || 'your-secret-key' const user = jwt.verify(token, secret) as UserTokenPayload // TODO: Fetch balance history from database // In real implementation: // const history = await getBalanceHistory(user.siliconId) // Mock balance history for demo const mockHistory = await getMockBalanceHistory(user.siliconId) return NextResponse.json({ success: true, balance_history: mockHistory, }) } catch (error) { console.error('Get balance history error:', error) return NextResponse.json( { success: false, message: 'Failed to fetch balance history' }, { status: 500 } ) } } // Utility functions function generateTransactionId(): string { const timestamp = Date.now().toString(36) const random = Math.random().toString(36).substr(2, 5) return `bal_${timestamp}${random}`.toUpperCase() } // Mock functions for demonstration async function mockSaveAddBalanceTransaction( siliconId: string, amount: number, currency: string, transactionId: string ) { console.log(`Mock DB Save: Add Balance Transaction`) console.log(`SiliconID: ${siliconId}, Amount: ${amount} ${currency}, TxnID: ${transactionId}`) // Mock database record const transaction = { id: Date.now(), silicon_id: siliconId, transaction_id: transactionId, amount, currency, status: 'pending', created_at: new Date(), updated_at: new Date(), } // Mock delay await new Promise((resolve) => setTimeout(resolve, 100)) return transaction } async function getMockBalanceHistory(siliconId: string) { // Mock balance transaction history return [ { id: 1, transaction_id: 'BAL_123ABC', amount: 1000, currency: 'INR', status: 'success', created_at: '2025-01-15T10:30:00Z', updated_at: '2025-01-15T10:31:00Z', }, { id: 2, transaction_id: 'BAL_456DEF', amount: 500, currency: 'INR', status: 'failed', created_at: '2025-01-10T14:20:00Z', updated_at: '2025-01-10T14:21:00Z', }, { id: 3, transaction_id: 'BAL_789GHI', amount: 2000, currency: 'INR', status: 'success', created_at: '2025-01-05T09:15:00Z', updated_at: '2025-01-05T09:16:00Z', }, ] }