1 package Business::OnlinePayment::AuthorizeNet;
3 # $Id: AuthorizeNet.pm,v 1.10 2002-04-24 05:02:54 ivan Exp $
6 use Business::OnlinePayment;
7 use Net::SSLeay qw/make_form post_https/;
9 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
13 @ISA = qw(Exporter AutoLoader Business::OnlinePayment);
21 $self->server('secure.authorize.net');
23 $self->path('/gateway/transact.dll');
25 $self->build_subs('order_number'); #no idea how it worked for jason w/o this
31 my %content = $self->content();
34 my %actions = ('normal authorization' => 'AUTH_CAPTURE',
35 'authorization only' => 'AUTH_ONLY',
37 'post authorization' => 'PRIOR_AUTH_CAPTURE',
39 $content{'action'} = $actions{lc($content{'action'})} || $content{'action'};
42 my %types = ('visa' => 'CC',
44 'american express' => 'CC',
48 $content{'type'} = $types{lc($content{'type'})} || $content{'type'};
49 $self->transaction_type($content{'type'});
51 # stuff it back into %content
52 $self->content(%content);
58 my %content = $self->content();
60 $content{$map{$_}} = $content{$_};
62 $self->content(%content);
66 my($self,@fields) = @_;
68 my %content = $self->content();
70 foreach( grep defined $content{$_}, @fields) { $new{$_} = $content{$_}; }
81 password => 'x_Password',
83 description => 'x_Description',
85 invoice_number => 'x_Invoice_Num',
86 customer_id => 'x_Cust_ID',
87 last_name => 'x_Last_Name',
88 first_name => 'x_First_Name',
89 address => 'x_Address',
93 card_number => 'x_Card_Num',
94 expiration => 'x_Exp_Date',
95 account_number => 'x_Bank_Acct_Num',
96 routing_code => 'x_Bank_ABA_Code',
97 bank_name => 'x_Bank_Name',
98 country => 'x_Country',
102 company => 'x_Company',
103 order_number => 'x_Trans_ID',
106 if($self->transaction_type() eq "ECHECK") {
107 $self->required_fields(qw/type login password action amount last_name
108 first_name account_number routing_code
110 } elsif($self->transaction_type() eq 'CC' ) {
111 if ( $self->{_content}->{action} eq 'PRIOR_AUTH_CAPTURE' ) {
112 $self->required_fields(qw/type login password action amount
113 card_number expiration/);
115 $self->required_fields(qw/type login password action amount last_name
116 first_name card_number expiration/);
119 Carp::croak("AuthorizeNet can't handle transaction type: ".
120 $self->transaction_type());
123 my %post_data = $self->get_fields(qw/x_Login x_Password x_Invoice_Num
124 x_Description x_Amount x_Cust_ID
125 x_Method x_Type x_Card_Num x_Exp_Date
126 x_Auth_Code x_Bank_Acct_Num
127 x_Bank_ABA_Code x_Bank_Name
128 x_Last_Name x_First_Name x_Address
129 x_City x_State x_Zip x_Country x_Phone
130 x_Fax x_Email x_Email_Customer
131 x_Company x_Country x_Trans_ID/);
132 $post_data{'x_Test_Request'} = $self->test_transaction()?"TRUE":"FALSE";
133 $post_data{'x_ADC_Delim_Data'} = 'TRUE';
134 $post_data{'x_ADC_URL'} = 'FALSE';
135 $post_data{'x_Version'} = '3.1';
137 my $pd = make_form(%post_data);
138 my $s = $self->server();
139 my $p = $self->port();
140 my $t = $self->path();
141 my($page,$server_response,%headers) = post_https($s,$p,$t,'',$pd);
142 #escape NULL (binary 0x00) values
143 $page =~ s/\x00/\^0/g;
145 my $csv = new Text::CSV_XS();
147 my @col = $csv->fields();
149 $self->server_response($page);
150 if($col[0] eq "1" ) { # Authorized/Pending/Test
151 $self->is_success(1);
152 $self->result_code($col[0]);
153 $self->authorization($col[4]);
154 $self->order_number($col[6]);
156 $self->is_success(0);
157 $self->result_code($col[2]);
158 $self->error_message($col[3]);
159 unless ( $self->result_code() ) { #additional logging information
160 #$page =~ s/\x00/\^0/g;
161 $self->error_message($col[3].
162 " DEBUG: No x_response_code from server, ".
163 "(HTTPS response: $server_response) ".
165 join(", ", map { "$_ => ". $headers{$_} } keys %headers ). ") ".
166 "(Raw HTTPS content: $page)"
177 Business::OnlinePayment::AuthorizeNet - AuthorizeNet backend for Business::OnlinePayment
181 use Business::OnlinePayment;
183 my $tx = new Business::OnlinePayment("AuthorizeNet");
186 login => 'testdrive',
188 action => 'Normal Authorization',
189 description => 'Business::OnlinePayment test',
191 invoice_number => '100100',
192 customer_id => 'jsk',
193 first_name => 'Jason',
194 last_name => 'Kohles',
195 address => '123 Anystreet',
199 card_number => '4007000000027',
200 expiration => '09/02',
204 if($tx->is_success()) {
205 print "Card processed successfully: ".$tx->authorization."\n";
207 print "Card was rejected: ".$tx->error_message."\n";
210 =head1 SUPPORTED TRANSACTION TYPES
212 =head2 Visa, MasterCard, American Express, Discover
214 Content required: type, login, password, action, amount, first_name, last_name, card_number, expiration.
218 Content required: type, login, password, action, amount, first_name, last_name, account_number, routing_code, bank_name.
222 For detailed information see L<Business::OnlinePayment>.
226 Unlike Business::OnlinePayment or pre-3.0 verisons of
227 Business::OnlinePayment::AuthorizeNet, 3.1 requires separate first_name and
230 To settle an authorization-only transaction (where you set action to
231 'Authorization Only'), submit the nine-digit transaction id code in
232 the field "order_number" with the action set to "Post Authorization".
233 You can get the transaction id from the authorization by calling the
234 order_number method on the object returned from the authorization.
235 You must also submit the amount field with a value less than or equal
236 to the amount specified in the original authorization.
238 Recently (February 2002), Authorize.Net has turned address
239 verification on by default for all merchants. If you do not have
240 valid address information for your customer (such as in an IVR
241 application), you must disable address verification in the Merchant
242 Menu page at https://secure.authorize.net/ so that the transactions
243 aren't denied due to a lack of address information.
247 This module implements Authorize.Net's API verison 3.1 using the ADC
248 Direct Response method. See
249 https://secure.authorize.net/docs/developersguide.pml for details.
253 Jason Kohles, jason@mediabang.com
255 Ivan Kohler <ivan-authorizenet@420.am> updated it for Authorize.Net protocol
256 3.0/3.1 and is the current maintainer.
258 Jason Spence <jspence@lightconsulting.com> contributed support for separate
259 Authorization Only and Post Authorization steps and wrote some docs.
260 OST <services@ostel.com> paid for it.
264 perl(1). L<Business::OnlinePayment>.