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

Isocodes Laravel Package

ronanguilloux/isocodes

ronanguilloux/isocodes provides Laravel validation rules and helpers for ISO standards, making it easy to verify country, language, currency, script, and other codes in forms, APIs, and data imports. Lightweight, configurable, and practical for robust international data validation.

Deep Wiki
Context7

Getting Started

Install and locate. There is no Laravel service provider, no facade, no config file — it is a plain library of static validator classes:

composer require ronanguilloux/isocodes

Open vendor/ronanguilloux/isocodes/src/ (or the README's validator table) first. The layout is one class per standard — Iban, Siret, Siren, Tva, Gtin, Sscc, CreditCard, ZipCode, PhoneNumber, Isbn, StructuredCommunication, plus BIC/SWIFT and the ISO country/language lists. Find the class that matches the identifier your business actually handles, and read that single file; you rarely need more than two or three of them.

First use case. Money movement is the canonical entry point — validating an IBAN before storing payout details or initiating a SEPA transfer:

use IsoCodes\Iban;

Iban::validate('GB82WEST12345698765432'); // true — spaces?
Iban::validate('GB82 WEST 1234 5698 7654 32'); // normalise first, see Gotchas

Most classes follow the same two-method shape: a boolean validate() and, where the standard is formatting-sensitive, a format() that returns the canonical presentation (grouped IBAN, spaced SIRET, etc.). Some validators also expose getErrors() when instantiated rather than called statically — worth checking per class before you build error reporting on top of it.

Wire it into Laravel in five minutes. Create one rule per standard with php artisan make:rule IbanRule, inject the validator, and you have something reusable across FormRequests, Livewire components, and API controllers:

namespace App\Rules;

use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
use IsoCodes\Iban;

class IbanRule implements ValidationRule
{
    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        if (! is_string($value) || ! Iban::validate($this->normalise($value))) {
            $fail('The :attribute is not a valid IBAN.');
        }
    }

    private function normalise(string $value): string
    {
        return strtoupper(preg_replace('/\s+/', '', $value));
    }
}

Implementation Patterns

One rule class per standard, never inline. IbanRule, SiretRule, VatRule, GtinRule live in app/Rules. This is where normalisation, null handling, and country prerequisites belong — not scattered across FormRequests.

Normalise before you validate. Almost every real-world failure with this package is dirty input, not a bad identifier. Build a shared IdentifierNormalizer (trim, collapse whitespace, uppercase, strip dots and hyphens for VAT numbers) and call it at the boundary — request → normalise → validate → persist canonical form.

Country-dependent validators need a country first. ZipCode::validate($zip, 'FR') and PhoneNumber::validate($number, 'FR') require an ISO country code. Chain the checks so a bad country produces a clear error rather than a confusing "invalid zipcode":

if (! Iso3166::validate($request->country)) { /* fail on country */ }
if (! ZipCode::validate($request->postal_code, $request->country)) { /* fail on zip */ }

Store phones as E.164 and IBANs unspaced in the database; use format() only in Blade/mail templates.

Composite rules for payment details. A payout form needs IBAN and BIC and (optionally) a name match. Keep them as separate rules so error messages stay field-specific, rather than a single PaymentDetailsRule returning one opaque message.

Legacy string rules via a service provider. If parts of the codebase still use 'iban' => 'required|iban', register them once in AppServiceProvider::boot() with Validator::extend('iban', fn ($attr, $value) => Iban::validate(normalise($value))) and Validator::replacer(...) for the :attribute message. Don't mix both styles in the same area of the app.

Validation at import boundaries. For CSV/bulk onboarding, validate row-by-row and collect [row, field, value, reason] records instead of aborting on the first failure. The validators are pure and fast — the bottleneck is your I/O, not them.

Bind a thin wrapper for testability. Static calls are awkward to fake. Wrap the handful of validators you use behind an IdentifierValidator interface bound in the container. This also gives you a single place to swap the library out later (see the licence note below).

Test data. Don't hand-write fake IBANs — the checksum will bite you. Use published spec examples (the IBAN registry, SIRET/SIREN samples in the package's own test suite) as fixtures in your data providers.

Gotchas and Tips

GPL-3.0 is the headline risk. This is a copyleft licence in a library you link into a proprietary Laravel application. Many teams treat Composer dependencies as "just a dependency", but GPL-3.0 deserves a legal review before it ships in a closed-source SaaS. If counsel says no, the escape hatch is a thin wrapper interface plus an alternative (e.g. symfony/validator constraints, or hand-rolled checksum logic for IBAN/GTIN/SIRET — these algorithms are short and well documented). Decide this before you've wired 30 call sites.

No framework integration means no mocking, no caching, no config. Everything is static. In Octane or long-running queue workers, prefer instantiating validators when you need getErrors(); static error state shared across requests is exactly the kind of thing that produces ghost failures under load.

Maintenance is quiet. Last release mid-2023. Pin the version, run your test suite on every PHP minor upgrade, and watch for deprecation notices on 8.3/8.4. Check composer.json for extension requirements — some validators lean on ext-intl, ext-mbstring, or a big-integer extension. Add those to your Docker image and CI, not just your laptop.

Checksums are not existence checks. A valid SIRET passes the Luhn check but the company may be dissolved; a valid IBAN passes mod-97 but the account may be closed; a valid VAT number passes the format check but may not be registered. Where the business cares, pair the local validation with the authoritative registry (VIES for EU VAT, a bank account verification API for payouts) and treat this package as the cheap first filter.

Country coverage lags. New IBAN countries, new phone numbering plans, and reassigned zip codes appear after the library's release. If you onboard users in markets added recently, spot-check against the official registry rather than trusting a false verdict blindly.

Validators disagree about input hygiene. Some reject lowercase, some reject spaces, some tolerate both. Never assume; normalise explicitly and add a test case for the lowercased and space-separated forms of each fixture.

Write your own messages. The package ships no translations. Add lang/en/validation.php keys (iban, siret, vat) and use :attribute replacers so error output matches the rest of your app's tone.

Test both directions. For each rule, assert a known-good value, a known-bad checksum, a wrong-length value, a lowercase variant, and null/empty. The negative cases are where this library's value actually shows up — a rule that only ever returns true in tests is not tested.

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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings