IBAN plugin screenshot
Dark mode ready
Multilingual support
Supports v5.x

IBAN by asign

Community

IBAN input, validation rule, infolist entry and table column for Filament 5: grouped display, compact storage, SWIFT registry checks for every IBAN country and bank names for Ukraine and Poland.

Tags: Forms Infolist Entry
Supported versions:
5.x
asign avatar Author: asign

Package health

Automated checks of this plugin's Composer package

100 / 100
Security 100
Maintenance 100
Ecosystem 100
15 checks
  • Passed: GitHub Actions pinned to SHA
  • Skipped: GitLab CI includes pinned to SHA
  • Passed: Open security advisories
  • Passed: Dependabot PR responsiveness — No open Dependabot PRs.
  • Skipped: Renovate MR responsiveness
  • Passed: Dependabot or Renovate configured
  • Passed: Dependency update cooldown configured
  • Passed: Provides a security policy
  • Passed: Abandoned or archived — No consulted source marks the package abandoned (packagist, github).
  • Passed: Commit and release recency — Active: last commit 0 days ago; last release 0 days ago.
  • Passed: composer.lock not committed by library — composer.lock is absent from the released dist archive.
  • Passed: Dist archive is lean
  • Passed: Current Laravel version supported — Package dependencies resolve together with current Laravel 13.0.
  • Passed: Current PHP version supported — Constraint ^8.3 supports current PHP 8.5.
  • Skipped: Current Symfony version supported
Third-party plugin. This is built by the community, not the Filament team. Filament does not review, endorse, or vet the security of plugins outside the filament/ namespace. Review the source and install at your own risk. Found malware or an unresolved security issue the author won't address? Report it .
Powered by Plumb Last scanned 14 hours ago

Documentation

Filament IBAN

Tests

An IBAN field for Filament 5 that behaves: the user sees and edits the number in groups of four, the database gets the compact form, and the value is validated against the SWIFT IBAN registry (country, length, account structure, mod 97) for every IBAN country. Optionally it shows the bank name for Ukrainian and Polish accounts. Also ships the validation rule, an infolist entry, a table column and a value helper. No dependencies besides Filament, light and dark mode friendly.

#Screenshots

A table with IbanColumn: grouped numbers and bank names

The field groups the number as you type and shows the bank for Ukrainian and Polish accounts:

IbanInput with the bank name under the field

Every IBAN country is checked for length, account structure and check digits:

A validation error for a wrong IBAN

IbanEntry on a view page

Dark mode:

Dark mode

#Requirements

  • PHP 8.3+
  • Laravel 12 or 13
  • Filament 5

#Installation

composer require asignua/filament-iban

Registering the plugin on a panel is optional - every class works without it:

use Asignua\FilamentIban\IbanPlugin;

$panel->plugin(IbanPlugin::make());

#Usage

#Form field

use Asignua\FilamentIban\Forms\Components\IbanInput;

IbanInput::make('iban')
    ->countries(['UA', 'PL'])   // optional: accept only these countries (ISO 3166-1 alpha-2)
    ->showBankName();           // optional: bank name under the field once it loses focus
  • Typing, pasting and editing show UA21 3223 1300 0002 6007 2335 6600 1; the caret stays where you are.
  • The saved value is UA213223130000026007233566001.
  • The IBAN rule is built in. With exactly one allowed country the placeholder is a valid example of that country.
  • Separators are ignored on input and on the server: spaces, hyphens, dots, slashes, non-breaking and zero-width spaces, soft hyphens and BOM.
  • Validation (->unique(), ->maxLength() and the rest) sees the compact value, not the grouped text.
  • Backspace / Delete next to a group separator removes the neighbouring character too; the mask pauses during IME composition.
  • A helper text you set with ->helperText() is shown together with the bank name (Your hint — Bank name).
  • It is a TextInput, so ->required(), ->label(), ->helperText(), ->live() and the rest work as usual.

#Validation rule

use Asignua\FilamentIban\Rules\Iban;

$request->validate([
    'iban' => ['required', new Iban],
    'payout_iban' => ['nullable', Iban::make()->countries(['UA', 'PL'])],
]);

Spaces and case are ignored. Empty values pass - add required yourself.

#Helper

use Asignua\FilamentIban\Support\Iban;

Iban::normalize('ua21 3223 1300 0002 6007 2335 6600 1'); // UA213223130000026007233566001
Iban::format('UA213223130000026007233566001');            // UA21 3223 1300 0002 6007 2335 6600 1
Iban::isValid($iban);                                     // bool
Iban::problem($iban);                                     // null | empty | format | unknown_country | length | structure | checksum ('empty': nothing left after removing separators)
Iban::country($iban);                                     // 'UA'
Iban::bankCode($iban);                                    // the SWIFT bank identifier: '322313' (the MFO) for UA, '10901014' for PL, 'WEST' for GB
Iban::branchCode($iban);                                  // branch identifier where the registry has one ('123456' sort code for GB), else null
Iban::example('PL');                                      // a valid example IBAN

#Infolist entry and table column

use Asignua\FilamentIban\Infolists\Components\IbanEntry;
use Asignua\FilamentIban\Tables\Columns\IbanColumn;

IbanEntry::make('iban')->showBankName();
IbanColumn::make('iban')->showBankName();

Both show the grouped number in a monospaced font and are copyable; copying puts the compact form on the clipboard. The bank name is rendered through belowContent() / description(), so setting your own ->belowContent() / ->description() replaces it.

#Bank names

use Asignua\FilamentIban\Support\BankDirectories;

app(BankDirectories::class)->bankName($iban); // 'АТ "Укрексімбанк"', null when unknown

Built in: Ukraine (the bank identifier is the MFO, IBAN positions 5-10) and Poland. A Polish bank number (8 digits from position 5) is looked up in full first, because after mergers a number can belong to another bank than the code it starts with (144xxxxx is PKO BP, 150xxxxx is Erste, 106xxxxx is Alior); unlisted numbers fall back to the 5, 4 and 3 digit bank codes (cooperative banks have 4, a few institutions 5). Add your own country:

use Asignua\FilamentIban\Contracts\BankDirectory;

class GermanBanks implements BankDirectory
{
    public function bankName(string $iban): ?string
    {
        return ['37040044' => 'Commerzbank'][substr($iban, 4, 8)] ?? null;
    }
}

app(BankDirectories::class)->register('DE', GermanBanks::class); // in a service provider's boot()

#Keeping the bank registers current

The package ships the registers as they were on the day of the release. Refresh them any time:

php artisan filament-iban:update-banks        # UA and PL
php artisan filament-iban:update-banks UA
php artisan filament-iban:update-banks PL --path=/some/dir

The files are PHP arrays, written to filament-iban.banks_path (default storage/app/filament-iban/banks) through a temp file and rename() (opcache is invalidated for the CLI process only), and read before the shipped ones. A download below a sanity floor (50 UA / 200 PL entries) or an HTTP failure leaves the current file alone; an override that cannot be loaded is ignored in favour of the shipped data. Only write to a directory your app alone can write to - the file is executed by PHP. --path=<dir> is an export (used to regenerate the data shipped with the package); the app reads only banks_path. Schedule it if you care: Schedule::command('filament-iban:update-banks')->monthly();. The command cannot reach other processes: PHP-FPM with opcache.validate_timestamps=0, Octane and queue workers keep the previous data (opcache, and the in-memory directory of a long-lived worker) until they are reloaded or restarted after an update.

#Configuration

php artisan vendor:publish --tag=filament-iban-config
Key Default
banks_path null (storage/app/filament-iban/banks, env FILAMENT_IBAN_BANKS_PATH) where update-banks writes and where data files are read first
countries null default country restriction of every IbanInput
show_bank_name false default of showBankName() for field, entry and column

#Gotchas

  • Store the compact form. The grouping is only a mask in the browser. The state is compact after getState() and in the database; a stored compact value is regrouped when the form is filled. Do not compare or search with the grouped string.
  • Empty is valid. The rule skips empty values like every Laravel rule; use ->required().
  • Bank name appears on blur, not on every key stroke: it is resolved on the server (live on blur, enabled by showBankName() or the config default; a ->live() you call later wins). It stays hidden for an invalid IBAN or an unknown bank.
  • Check digits do not prove the account exists, only that the number is well-formed.
  • Registry data ages. New IBAN countries are added to the SWIFT registry from time to time (resources/data/countries.php, 88 countries); an IBAN of a country missing there is reported as an unknown country.
  • Ukrainian IBANs of branches and closed banks. The NBU register contains every MFO, branches resolved to the head bank, liquidated banks included. Some MFOs of old accounts (for example Raiffeisen Bank Aval's former 380805) are no longer listed and show no name.

#Data sources and licences

Country Source Licence
UA National Bank of Ukraine open data, https://bank.gov.ua/NBU_BankInfo/get_data_branch?json (reference book of MFO) NBU open data, free to use with attribution
PL Narodowy Bank Polski, plan numeracji rachunków bankowych, https://ewib.nbp.pl/plewibnra?dokNazwa=plewibnra.txt public register published by NBP

Both files were downloaded with filament-iban:update-banks and reduced to code/number and name: for UA, branch MFOs carry the name of the head bank; for PL, every settlement number (3.1k) and bank code is kept. The IBAN country structures follow the SWIFT IBAN registry; examples that are not published ones are synthetic (valid check digits, made-up accounts). The code is MIT; check the terms of the registers before redistributing the data files beyond this package.

#Translations

The interface ships in English, Ukrainian, German, Spanish, French, Italian, Dutch, Polish, Brazilian Portuguese and Turkish under the filament-iban::filament-iban namespace. A test keeps every language in step with the English keys. Override a string by publishing the translations (--tag=filament-iban-translations) and editing the copy in lang/vendor/filament-iban.

#AI agents

The package ships Laravel Boost guidelines (resources/boost/guidelines/core.blade.php) so a coding agent wires it up correctly.

#Testing

composer install
vendor/bin/phpunit
vendor/bin/phpstan analyse --memory-limit=1G
vendor/bin/pint --test

#Changelog

See CHANGELOG.md.

#License

The MIT License (MIT). See LICENSE.md.

The author

asign avatar Author: asign

asign is a small web-dev company from Lviv, Ukraine. We build business applications on Laravel and Filament — CRMs, automation systems for standard and non-standard business processes, booking and content management systems, including our own Filament-based CMS. We open-source the parts that prove useful beyond a single project

Plugins
19
Stars
24

From the same author