initial commit
This commit is contained in:
162
app/api/services/deploy-vpn/route.ts
Normal file
162
app/api/services/deploy-vpn/route.ts
Normal file
@@ -0,0 +1,162 @@
|
||||
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 }
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user