initial import
[Business-OnlinePayment-eSec.git] / eSec.pm
1 package Business::OnlinePayment::eSec;
2
3 use strict;
4 use Carp;
5 use Business::OnlinePayment;
6 use Business::CreditCard;
7 use Net::SSLeay qw( make_form post_https );
8 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $DEBUG);
9
10 require Exporter;
11
12 @ISA = qw(Exporter AutoLoader Business::OnlinePayment);
13 @EXPORT = qw();
14 @EXPORT_OK = qw();
15 $VERSION = '0.01';
16
17 $DEBUG = 0;
18
19 sub set_defaults {
20     my $self = shift;
21     $self->server('sec.aba.net.au');
22     $self->port('443');
23     $self->path('/cgi-bin/service/authint');
24 }
25
26 sub revmap_fields {
27     my($self,%map) = @_;
28     my %content = $self->content();
29     foreach(keys %map) {
30         $content{$_} = ref($map{$_})
31                          ? ${ $map{$_} }
32                          : $content{$map{$_}};
33     }
34     $self->content(%content);
35 }
36
37 sub get_fields {
38     my($self,@fields) = @_;
39
40     my %content = $self->content();
41     my %new = ();
42     foreach( grep defined $content{$_}, @fields) { $new{$_} = $content{$_}; }
43     return %new;
44 }
45
46 sub submit {
47     my($self) = @_;
48     my %content = $self->content;
49
50     my $action = lc($content{'action'});
51     die 'eSec only supports "Authorization Only" transactions'
52       unless $action eq 'authorization only';
53
54     my %typemap = (
55       "VISA card"                  => 'visa',
56       "MasterCard"                 => 'mastercard',
57       "Discover card"              => 'discover', #not supported...
58       "American Express card"      => 'amex',
59       "Diner's Club/Carte Blanche" => 'dinersclub',
60       "enRoute"                    => 'enroute', #not supported...
61       "JCB"                        => 'jcb',
62       "BankCard"                   => 'bankcard',
63     );
64     my $cardtype = $self->test_transaction
65                      ? 'testcard'
66                      : $typemap{cardtype($content{'card_number'})};
67
68     $content{'expiration'} =~ /^(\d+)\D+(\d+)$/
69       or croak "unparsable expiration $content{expiration}";
70     my ($month, $year) = ( $1, $2 );
71     $month += 0;
72     $year += 2000 if $year < 2000; #not y4k safe, oh shit
73
74     $self->revmap_fields(
75       EPS_MERCHANT    => 'login',
76       EPS_REFERENCEID => 'invoice_number',
77       EPS_CARDNUMBER  => 'card_number',
78       EPS_CARDTYPE    => \$cardtype,
79       EPS_EXPIRYMONTH => \$month,
80       EPS_EXPIRYYEAR  => \$year,
81       EPS_NAMEONCARD  => 'name',
82       EPS_AMOUNT      => 'amount',
83       EPS_CCV         => \'',
84       EPS_VERSION     => \'2',
85       EPS_TEST        => \( $self->test_transaction() ? 'true' : 'false' ),
86     );
87     %content = $self->content;
88     if ( $DEBUG ) {
89       warn "content:$_ => $content{$_}\n" foreach keys %content;
90     }
91
92     if ($self->transaction_type() eq 'CC' ) {
93       $self->required_fields(qw/type action amount card_number expiration/);
94     } else {
95       croak("eSec can't handle transaction type: ".
96             $self->transaction_type());
97     }
98
99     my %post_data = $self->get_fields( map "EPS_$_", qw(
100       MERCHANT REFERENCEID CARDNUMBER CARDTYPE EXPIRYMONTH EXPIRYYEAR
101       NAMEONCARD AMOUNT CCV VERSION TEST
102     ) );
103     if ( $DEBUG ) {
104       warn "post_data:$_ => $post_data{$_}\n" foreach keys %post_data;
105     }
106
107     my $pd = make_form(%post_data);
108     my $server = $self->server();
109     my $port = $self->port();
110     my $path = $self->path();
111     my($page,$server_response,%headers) =
112       post_https($server,$port,$path,'',$pd);
113
114     my( $r, $a, $m, $s, $e ) =
115       map { /^\s*\w+\s*\=\s*(.*)$/; $1; } split("\n", $page);
116
117     if ( $m =~ /^200/ ) {
118       $self->is_success(1);
119       $self->result_code($e);
120       $self->authorization($a);
121     } else {
122       $self->is_success(0);
123       $self->result_code($e);
124       $self->error_message($m);
125     }
126
127 }
128
129 1;
130 __END__
131
132 =head1 NAME
133
134 Business::OnlinePayment::eSec - eSec backend for Business::OnlinePayment
135
136 =head1 SYNOPSIS
137
138   use Business::OnlinePayment;
139
140   my $tx = new Business::OnlinePayment("eSec");
141   $tx->content(
142       type           => 'CC',
143       login          => 'test', #EPS_MERCHANT
144       action         => 'Authorization Only',
145       description    => 'Business::OnlinePayment test',
146       amount         => '49.95',
147       invoice_number => '100100',
148       name           => 'Tofu Beast',
149       card_number    => '4007000000027',
150       expiration     => '09/02',
151   );
152   $tx->submit();
153
154   if($tx->is_success()) {
155       print "Card processed successfully: ".$tx->authorization."\n";
156   } else {
157       print "Card was rejected: ".$tx->error_message."\n";
158   }
159
160 =head1 DESCRIPTION
161
162 For detailed information see L<Business::OnlinePayment>.
163
164 =head1 NOTE
165
166 =head1 COMPATIBILITY
167
168 This module implements eSec's API verison 2.  See
169 http://www.esec.com.au/sep/content/eps_support/integrate/integrate_use.html
170 for details.
171
172 =head1 AUTHOR
173
174 Ivan Kohler <ivan-esec@420.am>
175
176 =head1 SEE ALSO
177
178 perl(1). L<Business::OnlinePayment>.
179
180 =cut
181