Geolocation in an online store: how to detect the customer’s location and why

08.10.2026 | Author: Marcin Wiercioch

A customer from Berlin enters your store and sees prices in Polish złoty, shipping costs to Poland and terms and conditions in Polish. Statistically, you have just lost them. Geolocation, that is, detecting where a user is connecting from, lets you react to this automatically: switch the currency, show the right shipping methods, calculate the tax. In this article we look at the topic from a practical angle: how to detect location, why you should do it at all, what works well and what is a myth, and how much the different solutions cost, from completely free to commercial databases.

Why does a store need to know where the customer is?

  • Currency and language: offering EUR and a German version to a visitor from Germany is the lowest-hanging fruit of conversion,
  • shipping: showing the right carriers and costs straight away (and in Poland, a map of parcel lockers near the customer),
  • taxes: for B2C sales to EU countries, the VAT OSS scheme requires charging the rate of the consumer’s country, so the country has to be determined somehow,
  • regional content: promotions, product availability, compliance with local law,
  • security: an order paid with a card from a Polish bank but placed from the other side of the world is a signal for additional verification.

Method 1: GeoIP, or location by IP address

The basic and usually sufficient technique: we look up the visitor’s IP address in a database that maps address ranges to countries and cities. The key thing to understand: at country level GeoIP is very effective (accuracy of around 98 to 99%), but at city level it can be a lottery. Mobile networks and CGNAT can “place” a user from Wrocław in Warsaw, because that is where the operator’s gateway is. The design conclusion: make country-level decisions based on IP (currency, VAT, language), never street-level ones.

Method 2: a header from your CDN, the cheapest good solution

If your website is behind Cloudflare (or another CDN), the problem is essentially solved: Cloudflare determines the country of every request itself and passes it in the CF-IPCountry header. No databases to update, no delays, zero cost:

function okinet_customer_country(): string {
    // two-letter ISO code, e.g. PL, DE, or XX when unknown
    $country = $_SERVER["HTTP_CF_IPCOUNTRY"] ?? "";
    if ($country === "" || $country === "XX" || $country === "T1") {
        return "PL"; // a sensible default
    }
    return strtoupper($country);
}

if (okinet_customer_country() !== "PL") {
    // show a banner suggesting a change of currency/language
}

On paid plans, Cloudflare can also add the city and region. A practical note: the header is set by the CDN, so when you test locally (without the proxy), the field will be empty, hence the default value.

Method 3: the HTML5 Geolocation API, GPS with consent

The browser API can provide coordinates accurate to within metres, but it requires the user’s explicit consent (a browser prompt). It is a tool for specific features, such as “show the nearest parcel lockers” or “find a store near you”, not for silent profiling:

document.querySelector("#find-pickup-point").addEventListener("click", function () {
  navigator.geolocation.getCurrentPosition(
    function (pos) {
      showPickupPoints(pos.coords.latitude, pos.coords.longitude);
    },
    function (err) {
      // consent refused or no signal: fall back to the postcode
      showZipCodeForm();
    },
    { enableHighAccuracy: false, timeout: 8000 }
  );
});

Two iron rules: ask for the location only after a user action (a button), not when the page loads, and always have a fallback, because quite a few people will refuse.

Method 4: let the customer tell you

The most reliable “detector” is a country selector in the store header, remembered in a cookie. Geolocation should only suggest the default value; the decision belongs to the human. An anti-pattern we still see: a hard redirect to a language version based on IP, with no way to change it. A tourist with a German SIM card will not buy from you if they cannot get back to the Polish version.

What works and what does not: a cheat sheet

  • country from IP / CDN header: effective, go ahead (currency, language, VAT),
  • city from IP: unreliable; good at most for sorting a list of stores, never for decisions,
  • Accept-Language: this is the browser’s language preference, not a location; great for choosing the language, misleading as “where the customer is from”,
  • VPNs and proxies: a few percent of traffic will always be “not from there”; that is why you should suggest, not enforce,
  • automatic redirects by IP: dangerous for SEO too: Googlebot crawls mostly from the USA and may never see the Polish version; a banner with a suggestion is better,
  • cache and personalisation: if the page is cached, per-country variants have to be separated (a cache key including the country, or personalisation with JS or an edge worker); otherwise a German visitor will see the “Polish page from cache”.

Free solutions

  • Cloudflare CF-IPCountry: free on every plan; if you use Cloudflare, start here,
  • MaxMind GeoLite2: free databases (country/city) available after registration and updated weekly; less accurate than the paid version, but more than enough for country-level decisions,
  • ip-api.com: a simple JSON API, free for non-commercial use (with a request limit),
  • ipapi.co / ipinfo.io (free tier): limited pools of free requests per month, convenient for prototypes.

Working with a local GeoLite2 database in PHP takes a few lines with the official library:

require "vendor/autoload.php";
use GeoIp2\Database\Reader;

$reader = new Reader("/var/lib/geoip/GeoLite2-Country.mmdb");
try {
    $record = $reader->country($_SERVER["REMOTE_ADDR"]);
    $country = $record->country->isoCode; // np. "DE"
} catch (Exception $e) {
    $country = "PL";
}

Paid solutions

  • MaxMind GeoIP2: commercial databases and API; higher accuracy, ISP and connection type data; the industry standard, with prices starting from a few dozen dollars,
  • ipinfo.io / ipdata.co: APIs with rich context (ASN, VPN/proxy detection, useful against fraud), with subscriptions based on volume,
  • IP2Location: alternative downloadable databases with annual licences,
  • Google Geolocation API: location based on Wi-Fi networks and cell towers; great in mobile apps, rarely needed in a classic web store.

Good news for WooCommerce stores: the built-in MaxMind integration handles tax geolocation and the customer’s default country out of the box (including a mode compatible with page caching); all you need is a GeoLite2 licence key. For stores on Sylius or custom solutions, we plug similar logic into the application layer or, most efficiently, into the edge, as we described in our article on Cloudflare Workers.

Blocking traffic from unwanted countries

Geolocation also works the other way: sometimes traffic from parts of the world needs to be restricted. The reasons can be legal or practical: goods licensed only for Poland (publishing, supplements, products with regional restrictions), services provided in one country only, but also basic hygiene: waves of bots, form spam and login attempts usually come from a few specific regions that do not have a single customer anyway.

How to do it well:

  • at the firewall level (most effective): WAF rules in Cloudflare block traffic from selected countries, or send it to an additional check (a challenge), before it even reaches the server; GeoIP modules for nginx and Apache offer similar options,
  • at the application level (most user-friendly): instead of blocking the whole website, restrict only the transaction: let people browse the catalogue and inform them at checkout that delivery is only possible within Poland; a full block also cuts off those who are buying for a Polish address while abroad,
  • a challenge instead of a hard block: for “grey” destinations, verification (for example a managed challenge) is better than cutting them off: a human will pass, a bot will not.

Keep in mind: blocking by country filters mass noise, it is not legal protection. A VPN bypasses it in a minute, so formal protection comes from your terms and conditions and delivery address validation. Do not blindly block traffic from the USA either: Googlebot crawls from there and payment systems connect from there, so add exceptions for verified bots. And log rejected requests so that you know who you are actually cutting off.

Summary

Geolocation in e-commerce is not a single technology but a ladder: a CDN header or GeoLite2 for country-level decisions, the Geolocation API where the user consciously wants to share their exact position, and always the option to change it manually. Implemented with care, it increases conversion in foreign markets and keeps taxes in order; implemented by force, it irritates users and hurts SEO. Planning to sell abroad or want to add country detection to your store? We will be happy to help.

Marcin Wiercioch Marcin Wiercioch

full stack developer

Co-founder of Okinet, PHP developer, full stack developer, Linux administrator and technology enthusiast with 20 years of experience. Lately I have been focusing especially on optimising and automating development environments, which makes the web applications we build efficient, secure and easy to develop further.

All articles by this author

Share

Rate this article

Let’s talk
about your project

+48 506 160 480
biuro@okinet.pl

or write to us