Finance::OFX - An OFX client implementation.


p5-Finance-OFX documentation Contained in the p5-Finance-OFX distribution.

Index


Code Index:

NAME

Top

Finance::OFX - An OFX client implementation.

SYNOPSIS

Top

 use Finance::OFX;
 use Finance::OFX::Institution;

 my $fi = Finance::OFX::Institution->new(ORG => $org, FID => $fid, URL => $url);
 my $ofx = Finance::OFX->new(userID=>$user, userPass=>$pass, Institution => $fi);
 my @accounts = $ofx->accounts;

DESCRIPTION

Top

Finance::OFX provides several convenience functions for interacting with OFX servers.

CONSTRUCTOR

Top

$ua = Finance::OFX->new( %options )

Constructs a new Finance::OFX object and returns it. %options can be anything accepted by Finance::OFX::UserAgent.

ATTRIBUTES

Top

$ofx->institution

Get/Set the Finance::OFX::Institution object used by the Finance::OFX::UserAgent object.

$ofx->response

Get the most recent Finance::OFX::Response generated by Finance::OFX::UserAgent.

$ofx->user_id

Get/Set the OFX user ID. Wraps Finance::OFX::UserAgent::user_id().

$ofx->user_pass

Get/Set the OFX user password. Wraps Finance::OFX::UserAgent::user_pass().

METHODS

Top

These are convenience functions that wrap calls to Finance::OFX::UserAgent and post-process the results.

$ofx->accounts()

Get a list of the user's accounts at the configured Financial Institution.

$ofx->balance( $acct )

Get the latest balance statement for the given account at the configured Financial Institution.

$ofx->transactions( $acct [ $start [ $end ] ] )

Get the transaction list for the given account. Some Financial Institutions will accept a full, or partial, date range. Others simply ignore the date range.

SEE ALSO

Top

Finance::OFX::Account Finance::OFX::Institution Finance::OFX::Parse Finance::OFX::UserAgent http://ofx.net

WARNING

Top

From Finance::Bank::LloydsTSB:

This is code for online banking, and that means your money, and that means BE CAREFUL. 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 NO GUARANTEE, explicit or implied.

AUTHOR

Top

Brandon Fosdick, <bfoz@bfoz.net>

COPYRIGHT AND LICENSE

Top


p5-Finance-OFX documentation Contained in the p5-Finance-OFX distribution.

# Filename: OFX.pm
# Serialize, Parse and Query using the Open Financial Exchange format
# http://www.ofx.net/
# 
# Created January 30, 2008	Brandon Fosdick <bfoz@bfoz.net>
#
# Copyright 2008 Brandon Fosdick <bfoz@bfoz.net> (BSD License)
#
# $Id: OFX.pm,v 1.2 2008/03/04 04:22:24 bfoz Exp $

package Finance::OFX;

use strict;
use warnings;
use vars qw($VERSION);

$VERSION = sprintf("%d.%03d", q$Revision: 1.2 $ =~ /(\d+)\.(\d+)/);

use Finance::OFX::UserAgent;

use HTTP::Date;

sub new
{
    my ($this, %options) = @_;
    my $class = ref($this) || $this;
    my $self = {};
    bless $self, $class;

    # Assume any unprocessed options are meant for the UserAgent, 
    #  which implies that this object will be used to generate and process 
    #  requests instead of processing stored files
    $self->{ua} = OFX::UserAgent->new(%options) if scalar keys %options;

    return $self;
}

# --- Getters and Setters ---

sub institution
{
    my $s = shift;
    $s->{ua}->institution(@_);
}

sub response
{
    my $s = shift;
    $s->{ua}->{response};
}

sub user_id
{
    my $s = shift;
    $s->{ua}->user_id(@_);
}

sub user_pass
{
    my $s = shift;
    $s->{ua}->user_pass(@_);
}

# --- Public Methods ---

sub accounts
{
    my $s = shift;

    my $r = $s->{ua}->account_info;

    return -1 unless $r->is_success;
    return -2 if $r->signon_status_code;
    return undef unless $r->ofx->{signupmsgsrsv1}{acctinfotrnrs}{acctinfors}{acctinfo};

    my @accounts;
    for( @{$r->ofx->{signupmsgsrsv1}{acctinfotrnrs}{acctinfors}{acctinfo}} )
    {
	my %b = flatten($_);
	push @accounts, \%b;
    }
    return @accounts;
}

sub balance
{
    my ($s, $acct) = @_;
    return undef unless ref($acct) eq 'Finance::OFX::Account';

    # Use the FID from the given FI if none is set in the given Account
    $acct->fid($s->institution()->fid()) unless $acct->fid();

    my $r = $s->{ua}->statement($acct);
    return -1 unless $r->is_success;
    return -2 if $r->signon_status_code;
    return undef unless $r->ofx->{bankmsgsrsv1}{stmttrnrs};

    my $transaction = $r->ofx->{bankmsgsrsv1}{stmttrnrs};
    return "Statement request error: ".($transaction->{status}{message}) if transactionStatusCode($transaction);
    return "No statement info returned" unless exists $transaction->{stmtrs};

    return $transaction->{stmtrs};
}

sub transactions
{
    my ($s, $acct, $start, $end) = @_;
    return undef unless ref($acct) eq 'Finance::OFX::Account';

    # Use the FID from the given FI if none is set in the given Account
    $acct->fid($s->institution()->fid()) unless $acct->fid();

    my %options;
    $options{transactions} = 'Y';
    $options{start} = $start if $start;
    $options{end} = $end if $end;

    my $r = $s->{ua}->statement($acct, %options);
    return -1 unless $r->is_success;
    return -2 if $r->signon_status_code;
    my $ofx = $r->ofx;
    return undef unless $ofx->{bankmsgsrsv1}{stmttrnrs}{stmtrs};
    my $transaction = $ofx->{bankmsgsrsv1}{stmttrnrs};
    return "Statement request error: ".($transaction->{status}{message}) if transactionStatusCode($transaction);

    return $transaction->{stmtrs}{banktranlist};
}

sub transactionStatusCode
{
    my $tree = shift;
    return undef unless ref($tree) eq 'HASH';
    return $tree->{status}{code};
}

# --- Internal use only ---

# Blindly flatten a HoH
sub flatten
{
    my $tree = shift;
    return $tree unless ref($tree) eq 'HASH';
    my %a;
    for( keys %{$tree} )
    {
	$a{$_} = $tree->{$_}, next unless ref($tree->{$_}) eq 'HASH';
	my %b = flatten($tree->{$_});
	@a{keys %b} = values %b;
    }
    return %a;
}

1;

__END__