1 package Business::OnlinePayment::AuthorizeNet;
3 # $Id: AuthorizeNet.pm,v 1.11 2002-07-31 14:38:17 ivan Exp $
7 use Business::OnlinePayment;
8 use Net::SSLeay qw/make_form post_https/;
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 # stuff it back into %content
53 $self->content(%content);
59 my %content = $self->content();
61 $content{$map{$_}} = $content{$_};
63 $self->content(%content);
67 my($self,@fields) = @_;
69 my %content = $self->content();
71 foreach( grep defined $content{$_}, @fields) { $new{$_} = $content{$_}; }
82 password => 'x_Password',
84 description => 'x_Description',
86 invoice_number => 'x_Invoice_Num',
87 customer_id => 'x_Cust_ID',
88 last_name => 'x_Last_Name',
89 first_name => 'x_First_Name',
90 address => 'x_Address',
94 card_number => 'x_Card_Num',
95 expiration => 'x_Exp_Date',
96 account_number => 'x_Bank_Acct_Num',
97 routing_code => 'x_Bank_ABA_Code',
98 bank_name => 'x_Bank_Name',
99 country => 'x_Country',
103 company => 'x_Company',
104 order_number => 'x_Trans_ID',
105 cvv2 => 'x_Card_Code',
108 if($self->transaction_type() eq "ECHECK") {
109 $self->required_fields(qw/type login password action amount last_name
110 first_name account_number routing_code
112 } elsif($self->transaction_type() eq 'CC' ) {
113 if ( $self->{_content}->{action} eq 'PRIOR_AUTH_CAPTURE' ) {
114 $self->required_fields(qw/type login password action amount
115 card_number expiration/);
117 $self->required_fields(qw/type login password action amount last_name
118 first_name card_number expiration/);
121 Carp::croak("AuthorizeNet can't handle transaction type: ".
122 $self->transaction_type());
125 my %post_data = $self->get_fields(qw/x_Login x_Password x_Invoice_Num
126 x_Description x_Amount x_Cust_ID
127 x_Method x_Type x_Card_Num x_Exp_Date
128 x_Auth_Code x_Bank_Acct_Num
129 x_Bank_ABA_Code x_Bank_Name
130 x_Last_Name x_First_Name x_Address
131 x_City x_State x_Zip x_Country x_Phone
132 x_Fax x_Email x_Email_Customer
133 x_Company x_Country x_Trans_ID
135 $post_data{'x_Test_Request'} = $self->test_transaction()?"TRUE":"FALSE";
136 $post_data{'x_ADC_Delim_Data'} = 'TRUE';
137 $post_data{'x_ADC_URL'} = 'FALSE';
138 $post_data{'x_Version'} = '3.1';
140 my $pd = make_form(%post_data);
141 my $s = $self->server();
142 my $p = $self->port();
143 my $t = $self->path();
144 my($page,$server_response,%headers) = post_https($s,$p,$t,'',$pd);
145 #escape NULL (binary 0x00) values
146 $page =~ s/\x00/\^0/g;
148 my $csv = new Text::CSV_XS();
150 my @col = $csv->fields();
152 $self->server_response($page);
153 if($col[0] eq "1" ) { # Authorized/Pending/Test
154 $self->is_success(1);
155 $self->result_code($col[0]);
156 $self->authorization($col[4]);
157 $self->order_number($col[6]);
159 $self->is_success(0);
160 $self->result_code($col[2]);
161 $self->error_message($col[3]);
162 unless ( $self->result_code() ) { #additional logging information
163 #$page =~ s/\x00/\^0/g;
164 $self->error_message($col[3].
165 " DEBUG: No x_response_code from server, ".
166 "(HTTPS response: $server_response) ".
168 join(", ", map { "$_ => ". $headers{$_} } keys %headers ). ") ".
169 "(Raw HTTPS content: $page)"
180 Business::OnlinePayment::AuthorizeNet - AuthorizeNet backend for Business::OnlinePayment
184 use Business::OnlinePayment;
186 my $tx = new Business::OnlinePayment("AuthorizeNet");
189 login => 'testdrive',
191 action => 'Normal Authorization',
192 description => 'Business::OnlinePayment test',
194 invoice_number => '100100',
195 customer_id => 'jsk',
196 first_name => 'Jason',
197 last_name => 'Kohles',
198 address => '123 Anystreet',
202 card_number => '4007000000027',
203 expiration => '09/02',
204 cvv2 => '1234', #optional
208 if($tx->is_success()) {
209 print "Card processed successfully: ".$tx->authorization."\n";
211 print "Card was rejected: ".$tx->error_message."\n";
214 =head1 SUPPORTED TRANSACTION TYPES
216 =head2 Visa, MasterCard, American Express, Discover
218 Content required: type, login, password, action, amount, first_name, last_name, card_number, expiration.
222 Content required: type, login, password, action, amount, first_name, last_name, account_number, routing_code, bank_name.
226 For detailed information see L<Business::OnlinePayment>.
230 Unlike Business::OnlinePayment or pre-3.0 verisons of
231 Business::OnlinePayment::AuthorizeNet, 3.1 requires separate first_name and
234 To settle an authorization-only transaction (where you set action to
235 'Authorization Only'), submit the nine-digit transaction id code in
236 the field "order_number" with the action set to "Post Authorization".
237 You can get the transaction id from the authorization by calling the
238 order_number method on the object returned from the authorization.
239 You must also submit the amount field with a value less than or equal
240 to the amount specified in the original authorization.
242 Recently (February 2002), Authorize.Net has turned address
243 verification on by default for all merchants. If you do not have
244 valid address information for your customer (such as in an IVR
245 application), you must disable address verification in the Merchant
246 Menu page at https://secure.authorize.net/ so that the transactions
247 aren't denied due to a lack of address information.
251 This module implements Authorize.Net's API verison 3.1 using the ADC
252 Direct Response method. See
253 https://secure.authorize.net/docs/developersguide.pml for details.
257 Jason Kohles, jason@mediabang.com
259 Ivan Kohler <ivan-authorizenet@420.am> updated it for Authorize.Net protocol
260 3.0/3.1 and is the current maintainer.
262 Jason Spence <jspence@lightconsulting.com> contributed support for separate
263 Authorization Only and Post Authorization steps and wrote some docs.
264 OST <services@ostel.com> paid for it.
268 perl(1). L<Business::OnlinePayment>.