E-commerce fraud follows a pattern. The orders look legitimate—real-seeming names, real-seeming addresses, cards that pass AVS checks. But they're placed through VPNs or Tor, using stolen credit card numbers. By the time chargebacks roll in, the goods are gone.
The thing is, these orders look suspicious if you know where to look. The IP addresses scream "I'm hiding something." VPN servers. Tor exit nodes. IPs on abuse blacklists.
The information is there. Most stores just aren't checking.
What IP Addresses Actually Tell You
Every connection to your server includes an IP address. That IP address tells you:
- Where they claim to be — Geographic location
- Whether they're hiding — VPN, proxy, or Tor usage
- Whether they've been bad before — Blacklist status
- What kind of network they're on — Residential, datacenter, mobile
None of these are definitive fraud signals on their own. But combined, they paint a picture. And certain combinations are red flags.
The Red Flags
Let me be specific about what should concern you:
Datacenter IP + No VPN signature = Bot. Real humans don't browse from AWS or Google Cloud. If you see a datacenter IP that isn't a known VPN provider, it's almost certainly automated traffic.
Tor exit node = Maximum anonymity. Tor has legitimate privacy uses, but it's also the tool of choice for people who really don't want to be identified. High-value transactions from Tor deserve scrutiny.
Blacklisted IP = Known bad actor. If an IP is on abuse blacklists, someone has already reported problems from that address. Maybe spam, maybe fraud, maybe attacks. Either way, it's a signal.
VPN + Country mismatch + High-value transaction = Suspicious. Someone claiming to be in the US, shopping with a US card, but connecting through a Netherlands VPN? Maybe they're privacy-conscious. Maybe they're not who they claim to be.
Building the Detection System
You need four data points about every IP:
async function analyzeIP(ip) {
const apiKey = process.env.APIVERVE_KEY;
// Fetch all signals in parallel
const [vpn, tor, blacklist, location] = await Promise.all([
// VPN/Proxy detection
fetch(`https://api.apiverve.com/v1/vpndetector?ip=${ip}`, {
headers: { 'x-api-key': apiKey }
}).then(r => r.json()).then(r => r.data),
// Tor exit node check
fetch(`https://api.apiverve.com/v1/tordetect?ip=${ip}`, {
headers: { 'x-api-key': apiKey }
}).then(r => r.json()).then(r => r.data),
// Blacklist check
fetch(`https://api.apiverve.com/v1/ipblacklistlookup?ip=${ip}`, {
headers: { 'x-api-key': apiKey }
}).then(r => r.json()).then(r => r.data),
// Geographic location
fetch(`https://api.apiverve.com/v1/iplookup?ip=${ip}`, {
headers: { 'x-api-key': apiKey }
}).then(r => r.json()).then(r => r.data)
]);
return { vpn, tor, blacklist, location };
}
Four API calls, one Promise.all, all the data you need in ~300ms.
Scoring the Risk
Raw data isn't useful. You need a score that tells you what to do.
function calculateRiskScore(analysis, context = {}) {
let score = 0;
const flags = [];
// VPN Detection
if (analysis.vpn.is_vpn) {
score += 25;
flags.push('vpn_detected');
}
// Datacenter without VPN = likely bot
if (analysis.vpn.is_datacenter && !analysis.vpn.is_vpn) {
score += 45;
flags.push('datacenter_ip_non_vpn');
}
// High risk assessment from VPN detector
if (analysis.vpn.risk_level === 'High') {
score += 20;
flags.push('high_risk_ip');
}
// Tor is serious anonymization
if (analysis.tor.isTor) {
score += 50;
flags.push('tor_exit_node');
}
// Already on blacklists
if (analysis.blacklist.isIPBlacklisted) {
score += 60;
flags.push('blacklisted');
}
// Country mismatch (if we have claimed country)
if (context.claimedCountry) {
const actualCountry = analysis.location.country;
if (actualCountry !== context.claimedCountry) {
score += 30;
flags.push('country_mismatch');
}
}
return {
score,
flags,
riskLevel: score >= 80 ? 'critical' : score >= 50 ? 'high' : score >= 25 ? 'medium' : 'low',
recommendation: getRecommendation(score)
};
}
function getRecommendation(score) {
if (score >= 80) return 'block';
if (score >= 50) return 'challenge'; // CAPTCHA, 2FA, manual review
if (score >= 25) return 'monitor'; // Log, flag for review if issues
return 'allow';
}
Now you get actionable output:
{
"score": 85,
"flags": ["vpn_detected", "blacklisted", "country_mismatch"],
"riskLevel": "critical",
"recommendation": "block"
}
Where to Check
Not every request needs full fraud analysis. Be strategic:
Always check:
- Account registration
- Payment/checkout
- Password reset
- Sensitive data access
Sometimes check:
- Login (maybe only on failed attempts or new devices)
- High-value actions
- Actions that can't be undone
Don't check:
- Static asset requests
- Already-authenticated internal tools
- Health check endpoints
Checking everything wastes credits and adds latency. Check the moments that matter.
Integration Example: E-Commerce Checkout
app.post('/checkout', async (req, res) => {
const ip = req.headers['x-forwarded-for']?.split(',')[0] || req.socket.remoteAddress;
const { billingCountry, cartTotal } = req.body;
// Skip fraud check for tiny orders
if (cartTotal < 50) {
return processOrder(req, res);
}
const analysis = await analyzeIP(ip);
const risk = calculateRiskScore(analysis, { claimedCountry: billingCountry });
// Log everything for later analysis
await logFraudCheck({
ip,
cartTotal,
risk,
analysis,
timestamp: new Date()
});
if (risk.recommendation === 'block') {
// Don't reveal why - that helps fraudsters
return res.status(400).json({
error: 'Unable to process order. Please contact support.'
});
}
if (risk.recommendation === 'challenge') {
// Require additional verification
return res.json({
requiresVerification: true,
verificationType: cartTotal > 500 ? 'phone' : 'captcha'
});
}
// Low risk - proceed
return processOrder(req, res);
});
Key points:
- Skip checks for low-value orders (not worth the fraud risk)
- Log everything (you'll want this data later)
- Don't tell blocked users why (that's a training manual for fraudsters)
- Scale verification to risk (high-value + suspicious = more friction)
The VPN Nuance
Here's where it gets complicated: not everyone using a VPN is a fraudster.
Legitimate VPN users:
- Privacy-conscious individuals
- Remote workers on corporate VPNs
- Travelers accessing home services
- People in countries with internet restrictions
- Journalists, activists, at-risk individuals
VPN usage alone shouldn't block anyone. It should increase scrutiny.
The scoring system above gives VPN detection 25 points—enough to flag for monitoring, not enough to block. You need additional signals (blacklist, country mismatch, other behavioral red flags) to push into blocking territory.
Datacenter IPs without VPN signatures are different. That's someone running requests from a cloud server, not a human at a computer. That's either a bot, a scraper, or someone doing something unusual enough to spin up a server for it.
Tor Is Different
Tor is maximum-strength anonymity. The entire network is designed to make identification impossible.
There are legitimate Tor users. But the overlap between "needs absolute anonymity" and "doing something you won't like" is significant.
I'd recommend:
- Block Tor for financial transactions
- Require strong additional verification for account creation
- Allow Tor for browsing/reading (why not?)
- Let human reviewers handle edge cases
The 50-point Tor score in the system above reflects this—it's a strong signal, but not an automatic block.
Caching and Performance
IP reputation doesn't change every second. Cache results:
const cache = new Map();
async function analyzeIPCached(ip) {
const cached = cache.get(ip);
if (cached && Date.now() < cached.expiresAt) {
return cached.data;
}
const data = await analyzeIP(ip);
cache.set(ip, {
data,
expiresAt: Date.now() + (60 * 60 * 1000) // 1 hour
});
return data;
}
One hour is reasonable. The same IP hitting your checkout 10 times in an hour doesn't need 10 fraud checks—one is enough.
For high-traffic sites, use Redis instead of an in-memory Map so the cache survives restarts and works across multiple servers.
What This Doesn't Catch
IP intelligence is one layer of fraud prevention. It doesn't catch:
- Residential proxies — Fraudsters route through real home IPs
- Mobile carriers — One IP represents thousands of users
- Good IPs gone bad — Someone's first fraud from a clean IP
- Sophisticated actors — State-level threats with clean infrastructure
You still need:
- Device fingerprinting
- Behavioral analysis
- Payment verification
- Manual review for edge cases
Think of IP intelligence as the first filter. It catches the lazy fraud—the people using known bad IPs, obvious VPNs, or Tor. That's a lot of fraud. But it's not all fraud.
The Numbers
What does this cost?
- VPN detection: 1 credit
- Tor detection: 1 credit
- Blacklist check: 1 credit
- IP lookup: 1 credit
- Total: 4 credits per check
On a Starter plan ({{plan.starter.calls}} credits/month), that's thousands of fraud checks. If your checkout conversion rate is 3% and you're checking all checkouts, that supports tens of thousands of monthly visitors.
Is that worth it? Let's do different math:
- One fraudulent order costs you the merchandise + shipping + chargeback fee (~$25) + potential account penalty
- Average fraud case: $150-500 in losses
- Cost of 4 credits: ~$0.01
You're paying a penny to potentially save hundreds. The ROI is obvious.
Fraud prevention isn't about catching every bad actor. It's about making fraud expensive and inconvenient enough that they go somewhere else.
IP intelligence catches the obvious stuff—the fraudsters who don't bother hiding properly, the bots pretending to be humans, the IPs with known histories. Layer it with other signals and you have a real defense.
The VPN Detector, Tor Detector, IP Blacklist Lookup, and IP Lookup APIs all work together. Same API key, same response format, four signals that tell you who you're dealing with.
Get your API key and start protecting your platform. The free tier is enough to test the entire system.
Originally published at APIVerve Blog
Top comments (0)