1 package Business::OnlinePayment::AuthorizeNet;
3 # $Id: AuthorizeNet.pm,v 1.9 2002-04-24 02:39:38 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);
143 my $csv = new Text::CSV_XS();
145 my @col = $csv->fields();
147 $self->server_response($page);
148 if($col[0] eq "1" ) { # Authorized/Pending/Test
149 $self->is_success(1);
150 $self->result_code($col[0]);
151 $self->authorization($col[4]);
152 $self->order_number($col[6]);
154 $self->is_success(0);
155 $self->result_code($col[2]);
156 $self->error_message($col[3]);
157 unless ( $self->result_code() ) { #additional logging information
158 $page =~ s/\x00/\^0/g;
159 $self->error_message($col[3].
160 " DEBUG: No x_response_code from server, ".
161 "(HTTPS response: $server_response) ".
163 join(", ", map { "$_ => ". $headers{$_} } keys %headers ). ") ".
164 "(Raw HTTPS content: $page)"
175 Business::OnlinePayment::AuthorizeNet - AuthorizeNet backend for Business::OnlinePayment
179 use Business::OnlinePayment;
181 my $tx = new Business::OnlinePayment("AuthorizeNet");
184 login => 'testdrive',
186 action => 'Normal Authorization',
187 description => 'Business::OnlinePayment test',
189 invoice_number => '100100',
190 customer_id => 'jsk',
191 first_name => 'Jason',
192 last_name => 'Kohles',
193 address => '123 Anystreet',
197 card_number => '4007000000027',
198 expiration => '09/02',
202 if($tx->is_success()) {
203 print "Card processed successfully: ".$tx->authorization."\n";
205 print "Card was rejected: ".$tx->error_message."\n";
208 =head1 SUPPORTED TRANSACTION TYPES
210 =head2 Visa, MasterCard, American Express, Discover
212 Content required: type, login, password, action, amount, first_name, last_name, card_number, expiration.
216 Content required: type, login, password, action, amount, first_name, last_name, account_number, routing_code, bank_name.
220 For detailed information see L<Business::OnlinePayment>.
224 Unlike Business::OnlinePayment or pre-3.0 verisons of
225 Business::OnlinePayment::AuthorizeNet, 3.1 requires separate first_name and
228 To settle an authorization-only transaction (where you set action to
229 'Authorization Only'), submit the nine-digit transaction id code in
230 the field "order_number" with the action set to "Post Authorization".
231 You can get the transaction id from the authorization by calling the
232 order_number method on the object returned from the authorization.
233 You must also submit the amount field with a value less than or equal
234 to the amount specified in the original authorization.
236 Recently (February 2002), Authorize.Net has turned address
237 verification on by default for all merchants. If you do not have
238 valid address information for your customer (such as in an IVR
239 application), you must disable address verification in the Merchant
240 Menu page at https://secure.authorize.net/ so that the transactions
241 aren't denied due to a lack of address information.
245 This module implements Authorize.Net's API verison 3.1 using the ADC
246 Direct Response method. See
247 https://secure.authorize.net/docs/developersguide.pml for details.
251 Jason Kohles, jason@mediabang.com
253 Ivan Kohler <ivan-authorizenet@420.am> updated it for Authorize.Net protocol
254 3.0/3.1 and is the current maintainer.
256 Jason Spence <jspence@lightconsulting.com> contributed support for separate
257 Authorization Only and Post Authorization steps and wrote some docs.
258 OST <services@ostel.com> paid for it.
262 perl(1). L<Business::OnlinePayment>.