Convert to Business::OnlinePayment:HTTPS
[Business-OnlinePayment-eWay.git] / eWay.pm
1 package Business::OnlinePayment::eWay;
2
3 use strict;
4 use Carp;
5 use Business::OnlinePayment 3;
6 use Business::OnlinePayment::HTTPS;
7 use Business::CreditCard;
8 use XML::Simple;
9 use vars qw($VERSION @ISA $DEBUG);
10
11 @ISA = qw(Business::OnlinePayment::HTTPS);
12 $VERSION = '0.01';
13
14 $DEBUG = 0;
15
16 my $default_path = '/gateway/xmlpayment.asp';
17 my $default_cvn_path = '/gateway_cvn/xmlpayment.asp';
18 my $default_test_path = '/gateway/xmltest/testpage.asp';
19 my $default_cvn_test_path = '/gateway_cvn/xmltest/testpage.asp';
20
21 sub set_defaults {
22     my $self = shift;
23     $self->server('www.eway.com.au');
24     $self->port('443');
25     $self->path($default_path);
26 }
27
28 sub revmap_fields {
29     my($self,%map) = @_;
30     my %content = $self->content();
31     foreach(keys %map) {
32         $content{$_} = ref($map{$_})
33                          ? ${ $map{$_} }
34                          : (exists($content{$map{$_}})
35                              ? $content{$map{$_}}
36                              : '' 
37                            );
38     }
39     $self->content(%content);
40 }
41
42 sub get_fields {
43     my($self,@fields) = @_;
44
45     my %content = $self->content();
46     my %new = ();
47     foreach( grep defined $content{$_}, @fields) { $new{$_} = $content{$_}; }
48     return %new;
49 }
50
51 sub submit {
52     my($self) = @_;
53     my %content = $self->content;
54
55     my $action = lc($content{'action'});
56     die 'eSec only supports "Normal Authorization" transactions'
57       unless $action eq 'normal authorization';
58
59     $content{'expiration'} =~ /^(\d+)\D+(\d+)$/
60       or croak "unparsable expiration $content{expiration}";
61     my ($month, $year) = ( $1, $2 );
62     $month += 0;
63     $year %= 100; #not y2.1k safe
64
65     $content{'amount'} =~ /^(\d+\.+\d{0,2})$/
66       or croak "unparsable amount $content{amount}";
67     my $amount = $1*100;
68
69     my $address = $content{'address'} if exists $content{'address'};
70     $address .=   $content{'city'}    if exists $content{'city'};
71     $address .=   $content{'state'}   if exists $content{'state'};
72     $address .=   '';
73
74     $self->revmap_fields(
75       ewayCustomerID                 => 'login',
76       ewayTotalAmount                => \$amount,
77       ewayCustomerFirstName          => 'first_name',
78       ewayCustomerLastName           => 'last_name',
79       ewayCustomerEmail              => 'email',
80       ewayCustomerAddress            => \$address,
81       ewayCustomerPostcode           => 'zip',
82       ewayCustomerInvoiceDescription => 'description',
83       ewayCustomerInvoiceRef         => 'invoice_number',
84       ewayCardHoldersName            => 'name',
85       ewayCardNumber                 => 'card_number',
86       ewayCardExpiryMonth            => \$month,
87       ewayCardExpiryYear             => \$year,
88       ewayTrxnNumber                 => 'transaction_number',
89       ewayOption1                    => 'option1',
90       ewayOption2                    => 'option1',
91       ewayOption3                    => 'option1',
92       ewayCVN                        => 'cvv2',
93     );
94     %content = $self->content;
95     if ( $DEBUG ) {
96       warn "content:$_ => $content{$_}\n" foreach keys %content;
97     }
98
99     if ($self->transaction_type() eq 'CC' ) {
100       $self->required_fields(qw/action login amount name card_number expiration/);
101     } else {
102       croak("eWay can't handle transaction type: ".
103             $self->transaction_type());
104     }
105
106     my %post_data = $self->get_fields( map "$_", qw(
107       ewayCustomerID ewayTotalAmount ewayCustomerFirstName ewayCustomerLastName
108       ewayCustomerEmail ewayCustomerAddress ewayCustomerPostcode 
109       ewayCustomerInvoiceDescription ewayCustomerInvoiceRef ewayCardHoldersName
110       ewayCardNumber ewayCardExpiryMonth ewayCardExpiryYear ewayTrxnNumber
111       ewayOption1 ewayOption2 ewayOption3 ewayCVN
112     ) );
113     if ( $DEBUG ) {
114       warn "post_data:$_ => $post_data{$_}\n" foreach keys %post_data;
115     }
116
117     my $pd = XMLout({%post_data}, 'NoAttr' => 1, 'RootName' => 'ewaygateway');
118     if ( $DEBUG ) {
119       warn $pd,"\n";
120     }
121     my $oldpath = $self->path;
122     if ($post_data{ewayCVN} && $self->path eq $default_path){
123       $self->path($default_cvn_path);
124     }
125     if ($self->test_transaction) {
126       if ($self->path eq $default_path) {
127         $self->path($default_test_path);
128       }elsif ($self->path eq $default_cvn_path){
129         $self->path($default_cvn_test_path);
130       }else{
131         croak "Test mode not supported for path: " . $self->path . "\n";
132       }
133     }
134
135     my($page,$server_response) = $self->https_post($pd);
136     $self->path($oldpath);
137     if ( $DEBUG ) {
138       warn $page,"\n";
139     }
140
141     my $response;
142     if ($server_response =~ /200/){
143       $response = XMLin($page);
144     }else{
145       $response->{ewayTrxnError} = $server_response;
146     }
147
148     if ( $response->{ewayTrxnStatus} =~ /^True/ ) {
149       $self->is_success(1);
150       $self->authorization($response->{ewayAuthCode});
151     } else {
152       $self->is_success(0);
153     }
154     $self->error_message($response->{ewayTrxnError});
155     $self->server_response($response);
156 }
157
158 1;
159 __END__
160
161 =head1 NAME
162
163 Business::OnlinePayment::eWay - eWay backend for Business::OnlinePayment
164
165 =head1 SYNOPSIS
166
167   use Business::OnlinePayment;
168
169   my $tx = new Business::OnlinePayment("eWay");
170   $tx->content(
171       login          => '87654321', #ewayCustomerID
172       action         => 'Normal Authorization',
173       description    => 'Business::OnlinePayment test',
174       amount         => '49.95',
175       invoice_number => '100100',
176       name           => 'Tofu Beast',
177       card_number    => '46464646464646',
178       expiration     => '11/08',
179   );
180   $tx->submit();
181
182   if($tx->is_success()) {
183       print "Card processed successfully: ".$tx->authorization."\n";
184   } else {
185       print "Card was rejected: ".$tx->error_message."\n";
186   }
187
188 =head1 DESCRIPTION
189
190 For detailed information see L<Business::OnlinePayment>.
191
192 =head1 NOTE
193
194 =head1 COMPATIBILITY
195
196 This module implements eWay's XML API.  See
197 http://www.eway.com.au/support/xml.aspx for details.
198
199 =head1 AUTHOR
200
201 Jeff Finucane <jeff@cmh.net>
202
203 =head1 SEE ALSO
204
205 perl(1). L<Business::OnlinePayment>.
206
207 =cut
208