1 package Business::OnlinePayment::AuthorizeNet;
3 # $Id: AuthorizeNet.pm,v 1.14 2002-08-16 06:53:28 ivan Exp $
7 use Business::OnlinePayment;
8 use Net::SSLeay qw/make_form post_https make_headers/;
10 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
14 @ISA = qw(Exporter AutoLoader Business::OnlinePayment);
22 $self->server('secure.authorize.net');
24 $self->path('/gateway/transact.dll');
26 $self->build_subs('order_number'); #no idea how it worked for jason w/o this
32 my %content = $self->content();
35 my %actions = ('normal authorization' => 'AUTH_CAPTURE',
36 'authorization only' => 'AUTH_ONLY',
38 'post authorization' => 'PRIOR_AUTH_CAPTURE',
40 $content{'action'} = $actions{lc($content{'action'})} || $content{'action'};
43 my %types = ('visa' => 'CC',
45 'american express' => 'CC',
49 $content{'type'} = $types{lc($content{'type'})} || $content{'type'};
50 $self->transaction_type($content{'type'});
52 $content{'referer'} = defined( $content{'referer'} )
53 ? make_headers( 'Referer' => $content{'referer'} )
56 # stuff it back into %content
57 $self->content(%content);
63 my %content = $self->content();
65 $content{$map{$_}} = $content{$_};
67 $self->content(%content);
71 my($self,@fields) = @_;
73 my %content = $self->content();
75 foreach( grep defined $content{$_}, @fields) { $new{$_} = $content{$_}; }
86 password => 'x_Password',
88 description => 'x_Description',
90 invoice_number => 'x_Invoice_Num',
91 customer_id => 'x_Cust_ID',
92 last_name => 'x_Last_Name',
93 first_name => 'x_First_Name',
94 address => 'x_Address',
98 card_number => 'x_Card_Num',
99 expiration => 'x_Exp_Date',
100 account_number => 'x_Bank_Acct_Num',
101 routing_code => 'x_Bank_ABA_Code',
102 bank_name => 'x_Bank_Name',
103 country => 'x_Country',
107 company => 'x_Company',
108 order_number => 'x_Trans_ID',
109 cvv2 => 'x_Card_Code',
110 currency => 'x_Currency_Code',
113 if($self->transaction_type() eq "ECHECK") {
114 $self->required_fields(qw/type login password action amount last_name
115 first_name account_number routing_code
117 } elsif($self->transaction_type() eq 'CC' ) {
118 if ( $self->{_content}->{action} eq 'PRIOR_AUTH_CAPTURE' ) {
119 $self->required_fields(qw/type login password action amount
120 card_number expiration/);
122 $self->required_fields(qw/type login password action amount last_name
123 first_name card_number expiration/);
126 Carp::croak("AuthorizeNet can't handle transaction type: ".
127 $self->transaction_type());
130 my %post_data = $self->get_fields(qw/x_Login x_Password x_Invoice_Num
131 x_Description x_Amount x_Cust_ID
132 x_Method x_Type x_Card_Num x_Exp_Date
133 x_Auth_Code x_Bank_Acct_Num
134 x_Bank_ABA_Code x_Bank_Name
135 x_Last_Name x_First_Name x_Address
136 x_City x_State x_Zip x_Country x_Phone
137 x_Fax x_Email x_Email_Customer
138 x_Company x_Country x_Trans_ID
140 $post_data{'x_Test_Request'} = $self->test_transaction()?"TRUE":"FALSE";
141 $post_data{'x_ADC_Delim_Data'} = 'TRUE';
142 $post_data{'x_ADC_URL'} = 'FALSE';
143 $post_data{'x_Version'} = '3.1';
145 my $pd = make_form(%post_data);
146 my $s = $self->server();
147 my $p = $self->port();
148 my $t = $self->path();
149 my $r = $self->{_content}->{referer};
150 my($page,$server_response,%headers) = post_https($s,$p,$t,$r,$pd);
151 #escape NULL (binary 0x00) values
152 $page =~ s/\x00/\^0/g;
154 my $csv = new Text::CSV_XS();
156 my @col = $csv->fields();
158 $self->server_response($page);
159 if($col[0] eq "1" ) { # Authorized/Pending/Test
160 $self->is_success(1);
161 $self->result_code($col[0]);
162 $self->authorization($col[4]);
163 $self->order_number($col[6]);
165 $self->is_success(0);
166 $self->result_code($col[2]);
167 $self->error_message($col[3]);
168 unless ( $self->result_code() ) { #additional logging information
169 #$page =~ s/\x00/\^0/g;
170 $self->error_message($col[3].
171 " DEBUG: No x_response_code from server, ".
172 "(HTTPS response: $server_response) ".
174 join(", ", map { "$_ => ". $headers{$_} } keys %headers ). ") ".
175 "(Raw HTTPS content: $page)"
186 Business::OnlinePayment::AuthorizeNet - AuthorizeNet backend for Business::OnlinePayment
190 use Business::OnlinePayment;
192 my $tx = new Business::OnlinePayment("AuthorizeNet");
195 login => 'testdrive',
197 action => 'Normal Authorization',
198 description => 'Business::OnlinePayment test',
200 invoice_number => '100100',
201 customer_id => 'jsk',
202 first_name => 'Jason',
203 last_name => 'Kohles',
204 address => '123 Anystreet',
208 card_number => '4007000000027',
209 expiration => '09/02',
210 cvv2 => '1234', #optional
211 referer => 'http://valid.referer.url/',
215 if($tx->is_success()) {
216 print "Card processed successfully: ".$tx->authorization."\n";
218 print "Card was rejected: ".$tx->error_message."\n";
221 =head1 SUPPORTED TRANSACTION TYPES
223 =head2 Visa, MasterCard, American Express, Discover
225 Content required: type, login, password, action, amount, first_name, last_name, card_number, expiration.
229 Content required: type, login, password, action, amount, first_name, last_name, account_number, routing_code, bank_name.
233 For detailed information see L<Business::OnlinePayment>.
237 Unlike Business::OnlinePayment or pre-3.0 verisons of
238 Business::OnlinePayment::AuthorizeNet, 3.1 requires separate first_name and
241 Business::OnlinePayment::AuthorizeNet uses the ADC direct response method,
242 and sends a username and password with every transaction. Therefore,
243 Authorize.Net's referrer "security" is not necessary. In your Authorize.Net
244 interface at https://secure.authorize.net/ make sure the list of allowable
245 referers is blank. Alternatively, set the B<referer> field in the transaction
248 To settle an authorization-only transaction (where you set action to
249 'Authorization Only'), submit the nine-digit transaction id code in
250 the field "order_number" with the action set to "Post Authorization".
251 You can get the transaction id from the authorization by calling the
252 order_number method on the object returned from the authorization.
253 You must also submit the amount field with a value less than or equal
254 to the amount specified in the original authorization.
256 Recently (February 2002), Authorize.Net has turned address
257 verification on by default for all merchants. If you do not have
258 valid address information for your customer (such as in an IVR
259 application), you must disable address verification in the Merchant
260 Menu page at https://secure.authorize.net/ so that the transactions
261 aren't denied due to a lack of address information.
265 This module implements Authorize.Net's API verison 3.1 using the ADC
266 Direct Response method. See
267 https://secure.authorize.net/docs/developersguide.pml for details.
271 Jason Kohles, jason@mediabang.com
273 Ivan Kohler <ivan-authorizenet@420.am> updated it for Authorize.Net protocol
274 3.0/3.1 and is the current maintainer.
276 Jason Spence <jspence@lightconsulting.com> contributed support for separate
277 Authorization Only and Post Authorization steps and wrote some docs.
278 OST <services@ostel.com> paid for it.
280 T.J. Mather <tjmather@maxmind.com> sent a patch for the CVV2 field.
282 Mike Barry <mbarry@cos.com> sent in a patch for the referer field.
286 perl(1). L<Business::OnlinePayment>.