import { NextRequest } from 'next/server' import { CHF_COUNTRIES } from '@/lib/currency' /** * Get client IP address from request headers */ function getClientIp(request: NextRequest): string | null { // Check various headers that might contain the real IP const forwardedFor = request.headers.get('x-forwarded-for') if (forwardedFor) { // x-forwarded-for can contain multiple IPs, take the first one return forwardedFor.split(',')[0].trim() } const realIp = request.headers.get('x-real-ip') if (realIp) { return realIp.trim() } const cfConnectingIp = request.headers.get('cf-connecting-ip') // Cloudflare if (cfConnectingIp) { return cfConnectingIp.trim() } // Fallback to remote address if available const remoteAddress = request.headers.get('remote-addr') if (remoteAddress) { return remoteAddress.trim() } return null } /** * Get country code from IP address using ip-api.com (free, no API key required) * Returns country code (e.g., 'CH' for Switzerland, 'SG' for Singapore), or null if detection fails */ export async function getCountryFromIp(request: NextRequest): Promise { try { const ip = getClientIp(request) if (!ip) { console.warn('Could not determine client IP') return null } // Skip localhost/private IPs if (ip === '127.0.0.1' || ip === '::1' || ip.startsWith('192.168.') || ip.startsWith('10.') || ip.startsWith('172.')) { // For local development, default to Switzerland return 'CH' } // Use ip-api.com free service (no API key required, rate limited) // Returns JSON with country code const response = await fetch(`http://ip-api.com/json/${ip}?fields=countryCode`, { method: 'GET', headers: { 'Accept': 'application/json', }, }) if (!response.ok) { console.warn(`Failed to fetch geolocation: ${response.status}`) return null } const data = await response.json() if (data.countryCode) { return data.countryCode } return null } catch (error) { console.error('Error detecting country from IP:', error) return null } } /** * Calculate shipping fee based on country * Returns shipping fee in the appropriate currency * 15 CHF for countries in CHF_COUNTRIES, 40 EUR for all other countries */ export function calculateShippingFee(countryCode: string | null): number { // 15 CHF for countries in CHF_COUNTRIES, 40 EUR for all other countries if (countryCode && CHF_COUNTRIES.includes(countryCode as any)) { return 15 } return 40 }