package Business::OnlineThirdPartyPayment;

use strict;
use vars qw($VERSION);
use Carp;
use base qw(Business::OnlinePayment);

require 5.005;

$VERSION = '0.10';
$VERSION = eval $VERSION; # modperlstyle: convert the string into a number

my %fields = (
    authorization        => undef,
    error_message        => undef,
    failure_status       => undef,
    fraud_detect         => undef,  # unsupported
    is_success           => undef,
    maximum_risk         => undef,  # unsupported
    path                 => undef,
    port                 => undef,
    require_avs          => undef,
    result_code          => undef,
    server               => undef,
    server_response      => undef,
    test_transaction     => undef,
    transaction_type     => undef,
    fraud_score          => undef,  # unsupported
    fraud_transaction_id => undef,  # unsupported
    popup_url            => undef,
    collectitems         => undef,
);

sub new {
    my($class,$processor,%data) = @_;

    croak("unspecified processor") unless $processor;

    my $subclass = "${class}::$processor";
    eval "use $subclass";
    croak("unknown processor $processor ($@)") if $@;

    my $self = bless {processor => $processor}, $subclass;
    $self->build_subs(keys %fields);

    if($self->can("set_defaults")) {
        $self->set_defaults(%data);
    }

    foreach(keys %data) {
        my $key = lc($_);
        my $value = $data{$_};
        $key =~ s/^\-+//;
        $self->build_subs($key);
        $self->$key($value);
    }

    return $self;
}

sub reference {
    my($self) = @_;

    croak("Processor subclass did not override reference function");
}

1;

__END__

=head1 NAME

Business::OnlineThirdPartyPayment - Perl extension for third party web page based online payment processing

=head1 SYNOPSIS

  use Business::OnlineThirdPartyPayment;

  my $transaction =
    new Business::OnlineThirdPartyPayment($processor, %processor_info);
  $transaction->content(
                        type        => 'CC',
                        action      => 'Authorization Only',
                        amount      => '49.95',
                        reference   => '3735928559',
                       );
  $transaction->submit();
  
  if($transaction->is_success()) {
    print "Success!  Redirect browser to ". $transaction->popup_url();
  } else {
    print "Card was rejected: ", $transaction->error_message(), "\n";
  }

  #when the provider calls us back via HTTP
  use CGI;
  my $cgi = new CGI;  #initialized to current page
  
  my $reference = $transaction->reference($cgi->Vars);
  $transaction->content(
                        type        => 'CC',
                        action      => 'Post Authorization',
                        reference   => $reference,
                       );
  $transaction->submit();
  if($transaction->is_success()) {
    print "Card processed scucessfully: ", $transaction->authorization(), "\n";
  } else {
    print "Card was rejected: ", $transaction->error_message(), "\n";
  }

  

=head1 DESCRIPTION

Business::OnlineThirdPartyPayment is a generic module for processing payments
through online credit card processors, electronic cash systems, etc. through
which the payors web browser is redirected.  It is a subclass of
L<Business::OnlinePayment>

=head1 METHODS AND FUNCTIONS

=head2 new($processor, %processor_options);

Create a new Business::OnlineThirdPartyPayment object, $processor is required,
and defines the online processor to use.  If necessary, processor
options can be specified, currently supported options are 'Server',
'Port', and 'Path', which specify how to find the online processor
(https://server:port/path), but individual processor modules should
supply reasonable defaults for this information, override the defaults
only if absolutely necessary (especially path), as the processor
module was probably written with a specific target script in mind.

=head2 content(%content);

The information necessary for the transaction, this tends to vary a
little depending on the processor, so we have chosen to use a system
which defines specific fields in the frontend which get mapped to the
correct fields in the backend.  Currently defined fields are:

=head3 PROCESSOR FIELDS

=over 4

=item * reference

A unique reference for this transaction.

=back

For additional fields, see L<Business::OnlinePayment> and the specific
processor module used.

=head2 submit();

Submit the transaction to the processor for completion

=head2 is_success();

Returns true if the transaction was submitted successfully, false if
it failed (or undef if it has not been submitted yet).

=head2 test_transaction();

Most processors provide a test mode, where submitted transactions will
not actually be charged or added to your batch, calling this function
with a true argument will turn that mode on if the processor supports
it, or generate a fatal error if the processor does not support a test
mode (which is probably better than accidentally making real charges).

=head1 AUTHOR

Jeff Finucane <business-onlinethirdpartypayment@weasellips>

=head1 COPYRIGHT

Partially based on code from Business::OnlinePayment.

Copyright (c) 1999-2004 Jason Kohles.
Copyright (c) 2004 Ivan Kohler
Copyright (c) 2007-2009 Freeside Internet Services, Inc.

All rights reserved. This program is free software; you can redistribute
it and/or modify it under the same terms as Perl itself.

=head1 DISCLAIMER

THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

=head1 SEE ALSO

L<Business::OnlinePayment>, http://420.am/business-onlinepayment/

For verification of credit card checksums, see L<Business::CreditCard>.

=cut
