1 package Business::OnlinePayment::AuthorizeNet;
3 # $Id: AuthorizeNet.pm,v 1.8 2002-04-23 01:38:59 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 $self->error_message($col[3].
159 " DEBUG: No x_response_code from server, ".
160 "(HTTPS response: $server_response) ".
162 join(", ", map { "$_ => ". $headers{$_} } keys %headers ). ") ".
163 "(Raw HTTPS content: $page)"
174 Business::OnlinePayment::AuthorizeNet - AuthorizeNet backend for Business::OnlinePayment
178 use Business::OnlinePayment;
180 my $tx = new Business::OnlinePayment("AuthorizeNet");
183 login => 'testdrive',
185 action => 'Normal Authorization',
186 description => 'Business::OnlinePayment test',
188 invoice_number => '100100',
189 customer_id => 'jsk',
190 first_name => 'Jason',
191 last_name => 'Kohles',
192 address => '123 Anystreet',
196 card_number => '4007000000027',
197 expiration => '09/02',
201 if($tx->is_success()) {
202 print "Card processed successfully: ".$tx->authorization."\n";
204 print "Card was rejected: ".$tx->error_message."\n";
207 =head1 SUPPORTED TRANSACTION TYPES
209 =head2 Visa, MasterCard, American Express, Discover
211 Content required: type, login, password, action, amount, first_name, last_name, card_number, expiration.
215 Content required: type, login, password, action, amount, first_name, last_name, account_number, routing_code, bank_name.
219 For detailed information see L<Business::OnlinePayment>.
223 Unlike Business::OnlinePayment or pre-3.0 verisons of
224 Business::OnlinePayment::AuthorizeNet, 3.1 requires separate first_name and
227 To settle an authorization-only transaction (where you set action to
228 'Authorization Only'), submit the nine-digit transaction id code in
229 the field "order_number" with the action set to "Post Authorization".
230 You can get the transaction id from the authorization by calling the
231 order_number method on the object returned from the authorization.
232 You must also submit the amount field with a value less than or equal
233 to the amount specified in the original authorization.
235 Recently (February 2002), Authorize.Net has turned address
236 verification on by default for all merchants. If you do not have
237 valid address information for your customer (such as in an IVR
238 application), you must disable address verification in the Merchant
239 Menu page at https://secure.authorize.net/ so that the transactions
240 aren't denied due to a lack of address information.
244 This module implements Authorize.Net's API verison 3.1 using the ADC
245 Direct Response method. See
246 https://secure.authorize.net/docs/developersguide.pml for details.
250 Jason Kohles, jason@mediabang.com
252 Ivan Kohler <ivan-authorizenet@420.am> updated it for Authorize.Net protocol
253 3.0/3.1 and is the current maintainer.
255 Jason Spence <jspence@lightconsulting.com> contributed support for separate
256 Authorization Only and Post Authorization steps and wrote some docs.
257 OST <services@ostel.com> paid for it.
261 perl(1). L<Business::OnlinePayment>.