1 package Business::OnlinePayment::AuthorizeNet;
3 # $Id: AuthorizeNet.pm,v 1.17 2002-11-26 05:47:23 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 currency => 'x_Currency_Code',
91 invoice_number => 'x_Invoice_Num',
92 order_number => 'x_Trans_ID',
93 auth_code => 'x_Auth_Code',
94 customer_id => 'x_Cust_ID',
95 customer_ip => 'x_Customer_IP',
96 last_name => 'x_Last_Name',
97 first_name => 'x_First_Name',
98 address => 'x_Address',
102 country => 'x_Country',
106 company => 'x_Company',
107 card_number => 'x_Card_Num',
108 expiration => 'x_Exp_Date',
109 cvv2 => 'x_Card_Code',
110 check_type => 'x_Echeck_Type',
111 account_name => 'x_Bank_Account_Name',
112 account_number => 'x_Bank_Acct_Num',
113 account_type => 'x_Bank_Acct_Type',
114 bank_name => 'x_Bank_Name',
115 routing_code => 'x_Bank_ABA_Code',
116 customer_org => 'x_Customer_Organization_Type',
117 customer_ssn => 'x_Customer_Tax_ID',
118 license_num => 'x_Drivers_License_Num',
119 license_state => 'x_Drivers_License_State',
120 license_dob => 'x_Drivers_License_DOB',
123 if ($self->transaction_type() eq "ECHECK") {
124 if ($self->{_content}->{customer_org} ne '') {
125 $self->required_fields(qw/type login password amount routing_code
126 account_number account_type bank_name
127 account_name account_type check_type
128 customer_org customer_ssn/);
130 $self->required_fields(qw/type login password amount routing_code
131 account_number account_type bank_name
132 account_name account_type check_type
133 license_num license_state license_dob/);
135 } elsif ($self->transaction_type() eq 'CC' ) {
136 if ( $self->{_content}->{action} eq 'PRIOR_AUTH_CAPTURE' ) {
137 $self->required_fields(qw/type login password action amount
138 card_number expiration/);
140 $self->required_fields(qw/type login password action amount last_name
141 first_name card_number expiration/);
144 Carp::croak("AuthorizeNet can't handle transaction type: ".
145 $self->transaction_type());
148 my %post_data = $self->get_fields(qw/x_Login x_Password x_Invoice_Num
149 x_Description x_Amount x_Cust_ID x_Method x_Type x_Card_Num x_Exp_Date
150 x_Card_Code x_Auth_Code x_Echeck_Type x_Bank_Acct_Num
151 x_Bank_Account_Name x_Bank_ABA_Code x_Bank_Name x_Bank_Acct_Type
152 x_Customer_Organization_Type x_Customer_Tax_ID x_Customer_IP
153 x_Drivers_License_Num x_Drivers_License_State x_Drivers_License_DOB
154 x_Last_Name x_First_Name x_Address x_City x_State x_Zip x_Country
155 x_Phone x_Fax x_Email x_Email_Customer x_Company x_Country
156 x_Currency_Code x_Trans_ID/);
157 $post_data{'x_Test_Request'} = $self->test_transaction()?"TRUE":"FALSE";
158 $post_data{'x_ADC_Delim_Data'} = 'TRUE';
159 $post_data{'x_ADC_URL'} = 'FALSE';
160 $post_data{'x_Version'} = '3.1';
162 my $pd = make_form(%post_data);
163 my $s = $self->server();
164 my $p = $self->port();
165 my $t = $self->path();
166 my $r = $self->{_content}->{referer};
167 my($page,$server_response,%headers) = post_https($s,$p,$t,$r,$pd);
168 #escape NULL (binary 0x00) values
169 $page =~ s/\x00/\^0/g;
171 my $csv = new Text::CSV_XS({ 'binary'=>1 });
173 my @col = $csv->fields();
175 $self->server_response($page);
176 if($col[0] eq "1" ) { # Authorized/Pending/Test
177 $self->is_success(1);
178 $self->result_code($col[0]);
179 $self->authorization($col[4]);
180 $self->order_number($col[6]);
182 $self->is_success(0);
183 $self->result_code($col[2]);
184 $self->error_message($col[3]);
185 unless ( $self->result_code() ) { #additional logging information
186 #$page =~ s/\x00/\^0/g;
187 $self->error_message($col[3].
188 " DEBUG: No x_response_code from server, ".
189 "(HTTPS response: $server_response) ".
191 join(", ", map { "$_ => ". $headers{$_} } keys %headers ). ") ".
192 "(Raw HTTPS content: $page)"
203 Business::OnlinePayment::AuthorizeNet - AuthorizeNet backend for Business::OnlinePayment
207 use Business::OnlinePayment;
209 my $tx = new Business::OnlinePayment("AuthorizeNet");
212 login => 'testdrive',
214 action => 'Normal Authorization',
215 description => 'Business::OnlinePayment test',
217 invoice_number => '100100',
218 customer_id => 'jsk',
219 first_name => 'Jason',
220 last_name => 'Kohles',
221 address => '123 Anystreet',
225 card_number => '4007000000027',
226 expiration => '09/02',
227 cvv2 => '1234', #optional
228 referer => 'http://valid.referer.url/',
232 if($tx->is_success()) {
233 print "Card processed successfully: ".$tx->authorization."\n";
235 print "Card was rejected: ".$tx->error_message."\n";
238 =head1 SUPPORTED TRANSACTION TYPES
240 =head2 Visa, MasterCard, American Express, Discover
242 Content required: type, login, password, action, amount, first_name, last_name, card_number, expiration.
246 Content required: type, login, password, action, amount, first_name, last_name, account_number, routing_code, bank_name.
250 For detailed information see L<Business::OnlinePayment>.
254 Unlike Business::OnlinePayment or pre-3.0 verisons of
255 Business::OnlinePayment::AuthorizeNet, 3.1 requires separate first_name and
258 Business::OnlinePayment::AuthorizeNet uses the ADC direct response method,
259 and sends a username and password with every transaction. Therefore,
260 Authorize.Net's referrer "security" is not necessary. In your Authorize.Net
261 interface at https://secure.authorize.net/ make sure the list of allowable
262 referers is blank. Alternatively, set the B<referer> field in the transaction
265 To settle an authorization-only transaction (where you set action to
266 'Authorization Only'), submit the nine-digit transaction id code in
267 the field "order_number" with the action set to "Post Authorization".
268 You can get the transaction id from the authorization by calling the
269 order_number method on the object returned from the authorization.
270 You must also submit the amount field with a value less than or equal
271 to the amount specified in the original authorization.
273 Recently (February 2002), Authorize.Net has turned address
274 verification on by default for all merchants. If you do not have
275 valid address information for your customer (such as in an IVR
276 application), you must disable address verification in the Merchant
277 Menu page at https://secure.authorize.net/ so that the transactions
278 aren't denied due to a lack of address information.
282 This module implements Authorize.Net's API verison 3.1 using the ADC
283 Direct Response method. See
284 https://secure.authorize.net/docs/developersguide.pml for details.
288 Jason Kohles, jason@mediabang.com
290 Ivan Kohler <ivan-authorizenet@420.am> updated it for Authorize.Net protocol
291 3.0/3.1 and is the current maintainer.
293 Jason Spence <jspence@lightconsulting.com> contributed support for separate
294 Authorization Only and Post Authorization steps and wrote some docs.
295 OST <services@ostel.com> paid for it.
297 T.J. Mather <tjmather@maxmind.com> sent a patch for the CVV2 field.
299 Mike Barry <mbarry@cos.com> sent in a patch for the referer field.
303 perl(1). L<Business::OnlinePayment>.