Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ipinfolaravel Laravel Package

ipinfo/ipinfolaravel

Laravel integration for IPinfo's IP data API, adding geolocation, ASN, company, carrier, and privacy detection to your app. Includes configuration, middleware, caching, and a simple facade for looking up visitor IP addresses.

View on GitHub
Deep Wiki
Context7

Getting Started

composer require ipinfo/ipinfolaravel
php artisan vendor:publish --provider="ipinfo\ipinfolaravel\ipinfolaravelServiceProvider" --tag=config

Add your token to .env (the package reads it from config/ipinfo.php):

IPINFO_TOKEN=your_token_here
IPINFO_COUNTRY=US   # fallback country used for private/bogon IPs

The provider and Ipinfo facade are auto-discovered. First use case — resolve a visitor's country in a controller or middleware:

use ipinfo\ipinfolaravel\facades\Ipinfo;

$details = Ipinfo::getDetails($request->ip());

$country  = $details->country ?? config('ipinfo.country');
$currency = $country === 'GB' ? 'GBP' : 'USD';

Where to look first

  1. config/ipinfo.php after publishing — this is the entire surface area of the wrapper.
  2. vendor/ipinfo/ipinfolaravel/src/ — it is a very thin service provider + facade; you'll see it just builds an ipinfo\ipinfo\IPinfo client from config.
  3. The underlying ipinfo/ipinfo README — that, not the Laravel repo, is the real API reference for getDetails(), getBatchDetails(), and the Details object.

Before anything else, check installability on your stack. The last release was January 2021, so its composer constraints target Laravel 6–8 era. Run composer show ipinfo/ipinfolaravel --all and confirm your Laravel/PHP versions are allowed; on Laravel 10/11 you will likely need to skip the wrapper and bind ipinfo/ipinfo yourself (see Gotchas).

Implementation Patterns

Treat it as a container binding, not a framework feature. Day-to-day, the pattern is: inject or resolve ipinfo\ipinfo\IPinfo (bound as ipinfo), call one of two methods, read the Details object.

Resolve once per request via middleware. Avoid scattering lookups through controllers; geolocation is request-scoped context.

class ResolveGeo
{
    public function handle($request, Closure $next)
    {
        $ip = $request->ip();

        $request->attributes->set('geo', Cache::remember(
            "ipinfo:{$ip}",
            now()->addDay(),
            fn () => Ipinfo::getDetails($ip)->all   // cache the array, not the object
        ));

        return $next($request);
    }
}

Then anywhere downstream: $request->attributes->get('geo')['country'].

Cache per IP, explicitly. Even if the package config exposes cache settings, wrap calls in Cache::remember with a key like ipinfo:{ip} and a 24h–7d TTL. Geolocation is stable; this is the single biggest lever on latency, rate limits, and cost. Cache the ->all array — the Details object serializes awkwardly into Redis/file caches and queues.

Batch enrichment in jobs. For imports, order backfills, or log analysis, never loop getDetails(); call the batch endpoint with deduped IPs, chunked to the API limit (~1000 per request):

$results = Ipinfo::getBatchDetails($ips); // ['8.8.8.8' => Details, ...]

foreach ($results as $ip => $details) {
    // $details->country, $details->org, ...
}

Do this in a queued job, not a web request — batches can be slow and the payload is large.

Fraud / security scoring. Store country, asn, org, and (paid plan) privacy/company on login events or orders. Typical checks: country mismatch vs. billing country, hosting/VPN ASN, datacenter org strings. Keep the raw lookup result alongside the decision so you can re-evaluate rules later without re-querying.

Localization and pricing. country, timezone, and loc drive default locale, currency, and date formatting. Always layer a config fallback for bogon results rather than branching on null everywhere.

Testing. Mock the facade or swap the binding — never hit the network in tests:

Ipinfo::shouldReceive('getDetails')->andReturn((object) ['country' => 'DE']);

// or
$this->app->instance('ipinfo', $fakeClient);

Gotchas and Tips

  • getDetails() with no argument looks up the server's IP, not the visitor's — the API resolves the caller when no IP is supplied. In a Laravel app that means your web node's egress IP. Always pass $request->ip().
  • Private/bogon IPs return mostly nulls. 127.0.0.1, ::1, 10.x, 172.16–31.x, 192.168.x, and Docker/CI addresses are bogons: $details->bogon is true and country, city, etc. are empty. Set the fallback country option and test locally with a real public IP; don't conclude the package is broken when local dev returns blanks.
  • Behind a load balancer or CDN, $request->ip() is the proxy. Configure TrustProxies (or read CF-Connecting-IP/X-Forwarded-For deliberately) or every user will geolocate to your datacenter.
  • Http::fake() will not intercept these calls. The underlying library uses cURL directly, so Laravel's HTTP client fakes, preventStrayRequests(), and Telescope's HTTP watcher won't see them. Mock the container binding or the facade instead.
  • Fields are plan-dependent and always nullable. privacy, company, carrier, domains, and abuse data require paid plans; free/anonymous usage returns a reduced field set and stricter rate limits. Guard with ?? and null-safe operators rather than assuming ->city exists.
  • A missing or empty token fails at call time, not boot time. The client is constructed happily with ''; you get 401/429 responses later. Add a startup check (config('ipinfo.token') empty → log a warning) and run php artisan config:clear after editing .env, since config:cache will otherwise freeze the old token.
  • The 2021 release is the real risk. Zero dependents and no releases in years mean Laravel 10/11 and PHP 8.1+ compatibility is unverified. Fallback plan is trivial: composer require ipinfo/ipinfo and in AppServiceProvider::register() do $this->app->singleton(IPinfo::class, fn () => new IPinfo(config('ipinfo.token'), config('ipinfo'))). Same client, same Details object, no facade.
  • Namespace casing is unpleasant. It's ipinfo\ipinfolaravel\facades\Ipinfo (lowercase segments), which breaks IDE autocompletion and PSR-4 conventions. Alias it in config/app.php or import with as Geo in files you touch often.
  • Wrap it, don't sprinkle it. Put all calls behind your own GeoService with lookup(string $ip): GeoData; that one indirection lets you swap the wrapper for the raw client, change providers, add circuit breaking, or fake responses in tests without touching call sites.
  • Failure handling is on you. Catch exceptions/timeouts at the boundary and degrade to the fallback country or default locale — a third-party outage should never 500 a page render. Do lookups in middleware/jobs, never inline in a view.
  • GDPR/privacy. Every lookup ships an end-user IP to a third party. Keep it to what you need (country only where possible), cache so repeat visits don't re-send, and reflect the transfer in your privacy policy and retention rules.
  • Extension points are limited — the wrapper exposes config and a container binding, nothing more. If you need custom caching adapters, base URLs, or retry logic, that lives in the underlying IPinfo client's options, so configure it there rather than expecting the Laravel package to grow features.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console