163 lines
4.9 KiB
TypeScript
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 }
|
|
)
|
|
}
|
|
}
|