IP Address Capture - Merchant Integration Guide

⚠️ Critical Requirement

When integrating PexiPay's payment API into your application, you MUST capture your customer's actual IP address on your frontend/checkout page and pass it in every payment request.

Why This Matters

ReasonImpact
Fraud DetectionPayment gateways use IP geolocation to detect suspicious transactions
3D SecureBanks use IP address for risk assessment during authentication
ComplianceRegulatory requirements mandate accurate cardholder location data
Decline RatesMismatched IP addresses can cause legitimate transactions to be declined

❌ Common Mistake

Calling from backend without customer IP:

// ❌ WRONG: Calling from backend without customer IP
app.post('/checkout', async (req, res) => {
  const payment = await fetch('https://gateway.pexipay.com/api/v1/payments', {
    method: 'POST',
    headers: {
      'x-api-key': process.env.PEXIPAY_API_KEY,
      'x-api-secret': process.env.PEXIPAY_API_SECRET,
    },
    body: JSON.stringify({
      amount: 100,
      currency: 'USD',
      customer: { /* ... */ },
      card: { /* ... */ }
      // ❌ Missing ipAddress field
    })
  });
});

Problem: The request headers will contain your server's IP address (e.g., 13.234.204.168 from AWS), not your customer's actual location.

✅ Correct Implementation

Step 1: Frontend - Capture Customer IP

<!-- checkout.html -->
<script>
async function captureCustomerIP() {
  try {
    // Use a public IP detection service
    const response = await fetch('https://api.ipify.org?format=json');
    const data = await response.json();
    return data.ip;
  } catch (error) {
    console.error('Failed to get customer IP:', error);
    return null;
  }
}

// When customer clicks Pay button
async function handlePayment() {
  const customerIP = await captureCustomerIP();
  
  // Send to your backend with customer's IP
  const response = await fetch('/api/create-payment', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      amount: 100.00,
      ipAddress: customerIP,  // ← Customer's actual IP
      customer: {
        firstName: 'John',
        lastName: 'Doe',
        email: 'john@example.com'
      },
      // ... other payment details
    })
  });
  
  const result = await response.json();
  
  // Handle 3DS redirect if needed
  if (result.redirectUrl) {
    window.location.href = result.redirectUrl;
  }
}
</script>

Step 2: Backend - Forward Customer IP to PexiPay

// Node.js/Express example
app.post('/api/create-payment', async (req, res) => {
  const { amount, ipAddress, customer, billing, card } = req.body;
  
  // Validate that customer IP was provided
  if (!ipAddress) {
    return res.status(400).json({ 
      error: 'Customer IP address is required' 
    });
  }
  
  try {
    // Forward to PexiPay with customer's IP
    const payment = await fetch('https://gateway.pexipay.com/api/v1/payments', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': process.env.PEXIPAY_API_KEY,
        'x-api-secret': process.env.PEXIPAY_API_SECRET,
      },
      body: JSON.stringify({
        amount,
        currency: 'USD',
        ipAddress,  // ← Customer's IP from frontend
        customer,
        billing,
        card,
        returnUrl: 'https://yoursite.com/payment/complete'
      })
    });
    
    const result = await payment.json();
    res.json(result);
    
  } catch (error) {
    console.error('Payment error:', error);
    res.status(500).json({ error: 'Payment processing failed' });
  }
});

IP Detection Services

You can use any of these services to capture customer IP on your frontend:

ServiceEndpointRate Limit
ipifyhttps://api.ipify.org?format=jsonFree, unlimited
my-ip.iohttps://api.my-ip.io/ip.jsonFree, 1000/day
ipapi.cohttps://ipapi.co/json/Free, 1000/day

Example with Error Handling

async function captureCustomerIP() {
  const services = [
    'https://api.ipify.org?format=json',
    'https://api.my-ip.io/ip.json',
    'https://ipapi.co/json/'
  ];
  
  for (const service of services) {
    try {
      const response = await fetch(service, { timeout: 3000 });
      const data = await response.json();
      
      // Different services return IP in different fields
      return data.ip || data.address || data.query;
    } catch (error) {
      console.warn(`Failed to get IP from ${service}:`, error);
      continue;
    }
  }
  
  console.error('All IP detection services failed');
  return null;
}

Testing Your Implementation

✅ What You Should See

   ipAddress      | Location
------------------|-----------------
 197.156.240.15   | Kenya
 102.89.32.156    | Nigeria
 41.203.85.129    | Ghana
 196.201.218.16   | Tanzania

❌ What Indicates a Problem

   ipAddress      | Location
------------------|-----------------
 13.234.204.168   | AWS Mumbai (your server!)
 13.234.204.168   | AWS Mumbai (your server!)
 3.108.235.114    | AWS Mumbai (your server!)

📥 Working Example Available

Download a complete, working HTML example that demonstrates proper IP capture implementation.

Need Help?

If you're consistently seeing the same IP address (your server's IP) in your transactions:

  • Verify your frontend is capturing customer IP
  • Verify your backend is receiving the IP from frontend
  • Verify your backend is forwarding the IP to PexiPay
  • Check browser console for JavaScript errors
  • Contact PexiPay support with transaction IDs for investigation