byrokrat / banking
Data types for accounts in the swedish banking system
Installs: 87 337
Dependents: 6
Suggesters: 0
Security: 0
Stars: 11
Watchers: 3
Forks: 10
Open Issues: 0
Requires
- php: >=7.3
Requires (Dev)
README
Banking
Data types and factories for bank accounts in the swedish banking system, Handelsbanken, ICA-banken, Nordea, SEB, Skandiabanken, Swedbank, PlusGirot, Bankgirot among others.
Introduction
Banking provides a way of parsing and validating bank account numbers from the swedish banking system. It validates clearing numbers, the structure of the account number as well as check digits. It also defines value objects for account numbers, with formatting capabilities and methods for accessing the different parts of the account number and to identify the bank the number belongs to.
Installation
composer require byrokrat/banking
Banking has no user land dependencies.
Usage
The main entry point is the AccountFactory that is used to create AccountNumber objects.
$accountFactory = new \byrokrat\banking\AccountFactory; $account = $accountFactory->createAccount('50001111116'); // Prints a formatted version of the validated number (5000,111111-6) echo $account->getNumber();
The standard factory does its best to recognize different number formats.
- Spaces, hyphens and dots are ignored.
- An optional
,
delimiter between clearing and serial numbers may be used. - Misplaced clearing-serial delimiters are ignored.
The following account numbers are all valid and considered equal to the account number of the previous example.
// Prints 111111 echo $accountFactory->createAccount('5000,1111116')->equals($account); echo $accountFactory->createAccount('5000-1111116')->equals($account); echo $accountFactory->createAccount('5000,111111-6')->equals($account); echo $accountFactory->createAccount('5000,111 111-6')->equals($account); echo $accountFactory->createAccount('5000000001111116')->equals($account); echo $accountFactory->createAccount('5000,000001111116')->equals($account);
Making the factory stricter
For a factory that only allows digits and correctly placed clearing-serial
delimiters (,
) pass an instance of StrictFactory
as the first argument to
AccountFactory::__construct()
.
$accountFactory = new \byrokrat\banking\AccountFactory(new \byrokrat\banking\StrictFactory); // Will throw an exception as '-' is not a valid character in strict mode $accountFactory->createAccount('5000-1111116');
Rewrites
When parsing an account number fails the standard factory attempts rewriting it to see if a valid account number can be produced.
- It tries to interpret the first digit of the serial number as a clearing check digit.
- It tries to trim left side ceros from the serial number.
- It tries to prepend the clearing number
3300
to see if the account number is a valid Nordea personal account number.
If any of the rewrites (or any combination of rewrites) is successful the rewritten
number is used. Opt out of this behaviour by passing an empty RewriterContainer
as the second argument to AccountFactory::__construct()
.
$accountFactory = new \byrokrat\banking\AccountFactory( new \byrokrat\banking\StrictFactory, new \byrokrat\banking\Rewriter\RewriterContainer ); // Will throw an exception as the serial number is too long and can not be trimmed. $accountFactory->createAccount('5000,01111116');
Clearing number check digits for Swedbank accounts
Swedbank account numbers with clearing numbers starting with 8
may specify a
fifth clearing number check digit. The clearing number check digit is optional,
but if present the parser will use it to validate the clearing number.
$swedbank = $accountFactory->createAccount('8105-9,744202466'); echo $accountFactory->createAccount('81059,744202466')->equals($swedbank);
Please note that if the clearing check digit is
0
and no comma (,
) is used to separate the clearing and serial numbers the parser may not understand that the0
is part of the clearing number, resulting in data loss. For this reason it is a good habit to always use a comma to separate the clearing and serial numbers.
Catching parser errors
When parsing fails an exception is thrown. Inspect the exception message for an in-depth description of the parser stages and where the error occurred.
try { $accountFactory->createAccount('8105-8,744202464'); } catch (\byrokrat\banking\Exception $e) { echo $e->getMessage(); }
Outputs something like:
Unable to parse account 8105-8,744202464 using format Swedbank:
* Clearing number 8105 is within range 8000 to 8999
* [FAIL] Invalid check digit 4, expected 6
* [FAIL] Invalid clearing number check digit 8, expected 9
* Valid serial length 8
Parsing Bankgiro and PlusGiro accounts
Use BankgiroFactory
or PlusgiroFactory
to parse bankgiro and plusgiro
account numbers. (As of version 2.0 it is no longer possible to parse bankgiro
or plusgiro account numbers using the regular AccountFactory
.)
Note that the
-
delimiter is optional when parsing Bankgiro and PlusGiro account numbers. When omitted it may not be possible determine if the raw number is indeed a Bankgiro or PlusGiro account number:5805-6201
is a valid Bankgiro number and5805620-1
is a valid PlusGiro number.
$account = (new \byrokrat\banking\PlusgiroFactory)->createAccount('58056201'); echo $account->getBankName() == \byrokrat\banking\BankNames::BANK_PLUSGIRO;
$account = (new \byrokrat\banking\BankgiroFactory)->createAccount('58056201'); echo $account->getBankName() == \byrokrat\banking\BankNames::BANK_BANKGIRO;
Creating a factory that can parse both regular accounts and bankgiro or plusgiro accounts
Use DelegatingFactory
the create a factory that incorporates the functionality
of one or more factories in a single object.
$factory = new \byrokrat\banking\DelegatingFactory( new \byrokrat\banking\AccountFactory, new \byrokrat\banking\BankgiroFactory ); $account = $factory->createAccount('58056201'); echo $account->getBankName() == \byrokrat\banking\BankNames::BANK_BANKGIRO;
The AccountNumber API
Created account objects implement the AccountNumber interface, which defines the following api.
getBankName()
Gets the name of the bank a number belongs to (for a list of bank identifiers see BankNames).
echo $account->getBankName(); echo $account->getBankName() == \byrokrat\banking\BankNames::BANK_SEB;
getRawNumber()
Gets the raw and unformatted number.
echo $account->getRawNumber();
getNumber()
Gets a formatted permutation of account number. Using PHPs magical __tostring()
method calls getNumber()
internaly.
echo $account->getNumber(); echo $account;
prettyprint()
Gets a formatted permutation of account number with more eye candy.
echo $account->prettyprint();
get16()
Gets the generic 16 digit format as defined by BGC.
echo $account->get16();
getClearingNumber()
, getClearingCheckDigit()
, getSerialNumber()
and getCheckDigit()
Gets the extracted account number parts.
echo $account->getClearingNumber(); echo $account->getClearingCheckDigit(); echo $account->getSerialNumber(); echo $account->getCheckDigit();
equals()
Validates that two account objects represents the same number.
echo $account->equals($account);