ai-wpa/app/api/services/deploy-vpn/route.ts

163 lines
4.9 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server'
import { authMiddleware } from '@/lib/auth-middleware'
import connectDB from '@/lib/mongodb'
import { User as UserModel } from '@/models/user'
import BillingService from '@/lib/billing-service'
// Define your VPN endpoints
const VPN_ENDPOINTS = {
america: 'https://wireguard-vpn.3027622.siliconpin.com/vpn',
europe: 'https://wireguard.vps20.siliconpin.com/vpn',
}
export async function POST(request: NextRequest) {
try {
// Check authentication
const user = await authMiddleware(request)
if (!user) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
// Get data from request body
const { orderId, location, plan, amount } = await request.json()
if (!orderId) {
return NextResponse.json({ error: 'Order ID is required' }, { status: 400 })
}
if (!location || !VPN_ENDPOINTS[location as keyof typeof VPN_ENDPOINTS]) {
return NextResponse.json({ error: 'Valid VPN location is required' }, { status: 400 })
}
// Connect to MongoDB
await connectDB()
// Get user data for billing
const userData = await UserModel.findOne({ email: user.email })
if (!userData) {
return NextResponse.json({ error: 'User not found' }, { status: 404 })
}
const requiredAmount = amount || 0
// Check balance only if amount > 0
if (requiredAmount > 0) {
const currentBalance = userData.balance || 0
if (currentBalance < requiredAmount) {
return NextResponse.json(
{
error: `Insufficient balance. Required: ₹${requiredAmount}, Available: ₹${currentBalance}`,
code: 'INSUFFICIENT_BALANCE',
},
{ status: 400 }
)
}
}
// Get environment variables
const VPN_API_KEY = process.env.VPN_API_KEY
if (!VPN_API_KEY) {
return NextResponse.json({ error: 'VPN API configuration missing' }, { status: 500 })
}
// Get the endpoint for the selected location
const endpoint = VPN_ENDPOINTS[location as keyof typeof VPN_ENDPOINTS]
// Make API request to the selected VPN endpoint
const response = await fetch(endpoint, {
method: 'POST',
headers: {
'X-API-Key': VPN_API_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
new: orderId.toString(),
userId: user.id,
plan,
location,
}),
})
console.log('VPN_API_KEY', VPN_API_KEY)
// Handle non-200 responses
if (!response.ok) {
const errorData = await response.text()
throw new Error(`VPN API returned HTTP ${response.status}: ${errorData}`)
}
// Parse the response
const vpnData = await response.json()
const deploymentSuccess = response.ok && vpnData?.config
if (!deploymentSuccess) {
throw new Error('Invalid response from VPN API: Missing config')
}
// Process billing using the new comprehensive billing service
try {
const billingResult = await BillingService.processServiceDeployment({
user: {
id: user.id,
email: user.email,
siliconId: userData.siliconId,
},
service: {
name: `VPN Service - ${location}`,
type: 'vpn',
id: orderId.toString(),
config: {
orderId,
location,
plan,
endpoint: endpoint,
},
},
amount: requiredAmount,
currency: 'INR',
cycle: 'monthly',
deploymentSuccess,
deploymentResponse: vpnData,
metadata: {
userAgent: request.headers.get('user-agent'),
ip: request.headers.get('x-forwarded-for') || request.headers.get('x-real-ip'),
vpnLocation: location,
vpnPlan: plan,
},
})
console.log('VPN billing processed:', {
billingId: billingResult.billing.billing_id,
transactionId: billingResult.transaction?.transactionId,
balanceUpdated: billingResult.balanceUpdated,
})
} catch (billingError) {
console.error('Billing processing failed:', billingError)
// Continue even if billing fails, but return error if it's balance-related
if (billingError instanceof Error && billingError.message.includes('Insufficient balance')) {
return NextResponse.json(
{
error: billingError.message,
code: 'INSUFFICIENT_BALANCE',
},
{ status: 400 }
)
}
}
// Return the VPN configuration
return NextResponse.json({
success: true,
data: vpnData,
})
} catch (error) {
console.error('VPN deployment error:', error)
return NextResponse.json(
{
error: 'VPN deployment failed',
details: error instanceof Error ? error.message : 'Unknown error',
},
{ status: 500 }
)
}
}