rc 1.0
This commit is contained in:
92
lib/geolocation.ts
Normal file
92
lib/geolocation.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
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<string | null> {
|
||||
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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user