package Finance::Bank::AllianceAndLeicester;
use strict;
use Carp;
our $VERSION = '1.00';
use WWW::Mechanize;
use HTML::TokeParser;
sub check_balance {
my ($class, %opts) = @_;
my @accounts;
croak 'Must provide a Customer ID' unless exists $opts{customerid};
croak 'Must provide Memorable information' unless exists $opts{memorable};
croak 'Must provide a Unique Phrase' unless exists $opts{phrase};
croak 'Must provide a PIN Code' unless exists $opts{pin};
croak 'Customer ID should be 12 digits' unless $opts{customerid} =~ /^\d{12}$/;
croak 'PIN Code should be 5 digits' unless $opts{pin} =~ /^\d{5}$/;
my $self = bless { %opts }, $class;
# Submit Customer ID
my $agent = WWW::Mechanize->new();
$agent->get("https://www.mybank.alliance-leicester.co.uk/login/checkLogin.asp?txtCustomerID=$opts{customerid}");
# Submit the memorable information
$agent->get("https://www.mybank.alliance-leicester.co.uk/login/checkPM5.asp?txtMemDetail=$opts{memorable}");
# Check we have got the correct Unique Phrase
my $content = $agent->content;
my $stream = HTML::TokeParser->new(\$content) or die "$!";
for (my $a=0; $a<5; $a++) {
$stream->get_tag("span");
}
my $phrase = $stream->get_trimmed_text('/span');
croak "Unique Phrase Mismatch." unless(lc($phrase) eq lc($opts{phrase}));
# Submit the PIN Number
$agent->get("https://www.mybank.alliance-leicester.co.uk/login/checkPM4point1.asp?txtCustomerPIN=$opts{pin}");
# Check for login errors
$content = $agent->content;
$stream = HTML::TokeParser->new(\$content) or die "$!";
while(my $token = $stream->get_tag('div')) {
if($token->[1]{'id'} eq 'error') {
my $error = $stream->get_trimmed_text('/div');
croak "Error During Login: $error\n";
last;
}
}
# save this data to parse later
$content = $agent->{content};
# We have the data we need, so lets logout
$agent->get("https://www.mybank.alliance-leicester.co.uk/login/calls/logout.asp");
# Begin parsing the HTML
$stream = HTML::TokeParser->new(\$content) or die "$!";
$stream->get_tag("tr");
while (my $token = $stream->get_tag('tr')) {
my($accountbalance, $accountname,
$accountoverdraft, $accountnumber, $accountavailable);
# Get the Account Name and number
$token = $stream->get_tag('td');
$accountname = $stream->get_trimmed_text('/td');
$accountname =~ s/\s(\d+)$//;
$accountnumber = $1;
# Get the balance
$stream->get_tag('td');
$accountbalance = $stream->get_trimmed_text('/td');
# Get overdraft
$stream->get_tag('td');
$accountoverdraft = $stream->get_trimmed_text('/td');
# Get Available Balance
$stream->get_tag('td');
$accountavailable = $stream->get_trimmed_text('/td');
# Strip pounds signs from balances
$accountbalance =~ s/^\x{00A3}//;
$accountoverdraft =~ s/^\x{00A3}//;
$accountavailable =~ s/^\x{00A3}//;
# Strip Comma ',' from balances
$accountbalance =~ s/\,//g;
$accountoverdraft =~ s/\,//g;
$accountavailable =~ s/\,//g;
# Add to list of accounts to return
push @accounts, {
balance => $accountbalance,
name => $accountname,
overdraft => $accountoverdraft,
account => $accountnumber,
available_balance => $accountavailable
};
}
# Return the list of accounts
return @accounts;
}
1;
__END__
# Documentation is below here
=head1 NAME
Finance::Bank::AllianceAndLeicester - Check your Alliance & Leicester bank accounts from Perl
=head1 SYNOPSIS
use Finance::Bank::AllianceAndLeicester;
my @accounts = Finance::Bank::AllianceAndLeicester->check_balance(
customerid => '012345678912',
pin => '12345',
memorable => 'mybirthplace',
phrase => 'my unique phrase'
);
foreach (@accounts) {
printf "%12s(%20s): GBP %8.2f (Overdraft: GBP %8.2f Available: GBP %8.2f)\n",
$_->{account}, $_->{name}, $_->{balance}, $_->{overdraft}, $_->{available_balance} ;
}
=head1 DESCRIPTION
This module provides a rudimentary interface to the Alliance & Leicester
online banking system at C.
=head1 DEPENDENCIES
You will need either C or C installed
for HTTPS support to work with LWP. This module also depends on
C and C for screen-scraping.
=head1 CLASS METHODS
=over
=item B
check_balance ( customerid => $c,
pin => $p,
memorable => $m,
phrase => $s
)
Return an array of account hashes, one for each of your bank accounts.
=item customerid
The Customer ID is 12 Digit number supplied with your account
=item pin
Your 5 Digit PIN Number
=item memorable
This is your memorable information. Such as your birth place.
This is asked for when you first login to your bank account.
=item phrase
Your unique phrase. This is used to make sure we are connecting to
the Alliance & Leicester website and that the connection has not been hijacked.
This is created when you fisrt sign up your account, and can be changed on the
Alliance & Leicester internet banking website.
=back
=head1 ACCOUNT HASH KEYS
$ac->account
$ac->name
$ac->balance
$ac->overdraft
$ac->available_balance
Return the account number, account name (eg. 'PlusSaver'), account
balance, account overdraft limit and available balance as a signed floating point value.
=head1 WARNING
This warning is from Simon Cozens' C, and seems
just as apt here.
This is code for B, and that means B, and
that means B. You are encouraged, nay, expected, to audit
the source of this module yourself to reassure yourself that I am not
doing anything untoward with your banking data. This software is useful
to me, but is provided under B, explicit or implied.
=head1 THANKS
Simon Cozens for C and Chris Ball for Finance::Bank::HSBC,
upon which most of this code is based.
Andy Lester (and Skud, by continuation) for WWW::Mechanize, Gisle Aas for HTML::TokeParser.
=head1 CHANGELOG
=over
=item Version 1.01 - 04/10/2006 - Ian Bissett
* Strip commas from balances.
=back
=head1 AUTHOR
Ian Bissett C
=cut