1 package Business::OnlinePayment::AuthorizeNet;
5 use Business::OnlinePayment;
6 use vars qw($VERSION @ISA $me);
8 @ISA = qw(Business::OnlinePayment);
10 $me = 'Business::OnlinePayment::AuthorizeNet';
15 $self->build_subs(qw( order_number md5 avs_code cvv2_response
23 my %content = $self->content();
24 my %processors = ('recurring authorization' => 'ARB',
25 'modify recurring authorization' => 'ARB',
26 'cancel recurring authorization' => 'ARB',
28 $processors{lc($content{'action'})} || 'AIM';
34 my $processor = $me. "::". $self->_map_processor();
36 eval "use $processor";
37 croak("unknown processor $processor ($@)") if $@;
39 my $object = bless $self, $processor;
40 $object->set_defaults();
50 Business::OnlinePayment::AuthorizeNet - AuthorizeNet backend for Business::OnlinePayment
54 use Business::OnlinePayment;
57 # One step transaction, the simple case.
60 my $tx = new Business::OnlinePayment("AuthorizeNet");
64 password => '', #password or transaction key
65 action => 'Normal Authorization',
66 description => 'Business::OnlinePayment test',
68 invoice_number => '100100',
70 first_name => 'Jason',
71 last_name => 'Kohles',
72 address => '123 Anystreet',
76 card_number => '4007000000027',
77 expiration => '09/02',
78 cvv2 => '1234', #optional
79 referer => 'http://valid.referer.url/',
83 if($tx->is_success()) {
84 print "Card processed successfully: ".$tx->authorization."\n";
86 print "Card was rejected: ".$tx->error_message."\n";
90 # Two step transaction, authorization and capture.
91 # If you don't need to review order before capture, you can
92 # process in one step as above.
95 my $tx = new Business::OnlinePayment("AuthorizeNet");
99 password => '', #password or transaction key
100 action => 'Authorization Only',
101 description => 'Business::OnlinePayment test',
103 invoice_number => '100100',
104 customer_id => 'jsk',
105 first_name => 'Jason',
106 last_name => 'Kohles',
107 address => '123 Anystreet',
111 card_number => '4007000000027',
112 expiration => '09/02',
113 cvv2 => '1234', #optional
114 referer => 'http://valid.referer.url/',
118 if($tx->is_success()) {
119 # get information about authorization
120 $authorization = $tx->authorization
121 $ordernum = $tx->order_number;
122 $avs_code = $tx->avs_code; # AVS Response Code
123 $cvv2_response = $tx->cvv2_response; # CVV2/CVC2/CID Response Code
124 $cavv_response = $tx->cavv_response; # Cardholder Authentication
125 # Verification Value (CAVV) Response
128 # now capture transaction
129 my $capture = new Business::OnlinePayment("AuthorizeNet");
133 action => 'Post Authorization',
135 password => 'YOURPASSWORD', #or transaction key
136 order_number => $ordernum,
142 if($capture->is_success()) {
143 print "Card captured successfully: ".$capture->authorization."\n";
145 print "Card was rejected: ".$capture->error_message."\n";
149 print "Card was rejected: ".$tx->error_message."\n";
153 # One step subscription, the simple case.
156 my $tx = new Business::OnlinePayment("AuthorizeNet::ARB");
159 login => 'testdrive',
160 password => 'testpass', #or transaction key
161 action => 'Recurring Authorization',
162 interval => '7 days',
163 start => '2008-3-10',
168 description => 'Business::OnlinePayment test',
169 invoice_number => '1153B33F',
170 customer_id => 'vip',
171 first_name => 'Tofu',
172 last_name => 'Beast',
173 address => '123 Anystreet',
177 card_number => '4111111111111111',
178 expiration => '09/02',
182 if($tx->is_success()) {
183 print "Card processed successfully: ".$tx->order_number."\n";
185 print "Card was rejected: ".$tx->error_message."\n";
187 my $subscription = $tx->order_number
191 # Subscription change. Modestly more complicated.
196 subscription => '99W2C',
197 login => 'testdrive',
198 password => 'testpass', #or transaction key
199 action => 'Modify Recurring Authorization',
200 interval => '7 days',
201 start => '2008-3-10',
206 description => 'Business::OnlinePayment test',
207 invoice_number => '1153B340',
208 customer_id => 'vip',
209 first_name => 'Tofu',
210 last_name => 'Beast',
211 address => '123 Anystreet',
215 card_number => '4111111111111111',
216 expiration => '09/02',
220 if($tx->is_success()) {
221 print "Update processed successfully."\n";
223 print "Update was rejected: ".$tx->error_message."\n";
226 subscription => '99W2D',
227 login => 'testdrive',
228 password => 'testpass', # or transaction key
229 action => 'Cancel Recurring Authorization',
234 # Subscription cancellation. It happens.
237 if($tx->is_success()) {
238 print "Cancellation processed successfully."\n";
240 print "Cancellation was rejected: ".$tx->error_message."\n";
244 =head1 SUPPORTED TRANSACTION TYPES
246 =head2 CC, Visa, MasterCard, American Express, Discover
248 Content required: type, login, password, action, amount, first_name, last_name, card_number, expiration.
252 Content required: type, login, password, action, amount, first_name, last_name, account_number, routing_code, bank_name (non-subscription), account_type (subscription), check_type (subscription).
256 Additional content required: interval, start, periods.
260 For detailed information see L<Business::OnlinePayment>.
262 =head1 METHODS AND FUNCTIONS
264 See L<Business::OnlinePayment> for the complete list. The following methods either override the methods in L<Business::OnlinePayment> or provide additional functions.
268 Returns the response reason code (from the message.code field for subscriptions).
272 Returns the response reason text (from the message.text field for subscriptions.
274 =head2 server_response
276 Returns the complete response from the server.
278 =head1 Handling of content(%content) data:
282 The following actions are valid
289 recurring authorization
290 modify recurring authorization
291 cancel recurring authorization
295 Interval contains a number of digits, whitespace, and the units of days or months in either singular or plural form.
298 =head1 Setting AuthorizeNet ARB parameters from content(%content)
300 The following rules are applied to map data to AuthorizeNet ARB parameters
301 from content(%content):
303 # ARB param => $content{<key>}
304 merchantAuthentication
306 transactionKey => 'password',
310 length => \( the digits in 'interval' ),
311 unit => \( days or months gleaned from 'interval' ), startDate => 'start',
312 totalOccurrences => 'periods',
313 trialOccurrences => 'trialperiods',
315 trialAmount => 'trialamount',
318 cardNumber => 'card_number',
319 expiration => \( $year.'-'.$month ), # YYYY-MM from 'expiration'
321 accountType => 'account_type',
322 routingNumber => 'routing_code',
323 accountNumber => 'account_number,
324 nameOnAccount => 'name',
325 bankName => 'bank_name',
326 echeckType => 'check_type',
328 invoiceNumber => 'invoice_number',
329 description => 'description',
331 type => 'customer_org',
334 phoneNumber => 'phone',
337 number => 'license_num',
338 state => 'license_state',
339 dateOfBirth => 'license_dob',
340 taxid => 'customer_ssn',
342 firstName => 'first_name',
343 lastName => 'last_name',
344 company => 'company',
345 address => 'address',
349 country => 'country',
351 firstName => 'ship_first_name',
352 lastName => 'ship_last_name',
353 company => 'ship_company',
354 address => 'ship_address',
356 state => 'ship_state',
358 country => 'ship_country',
362 Use your transaction key in the password field.
364 Unlike Business::OnlinePayment or pre-3.0 verisons of
365 Business::OnlinePayment::AuthorizeNet, 3.1 requires separate first_name and
368 Business::OnlinePayment::AuthorizeNet uses Authorize.Net's "Advanced
369 Integration Method (AIM) (formerly known as ADC direct response)" and
370 "Automatic Recurring Billing (ARB)", sending a username and password (or
371 transaction_key) with every transaction. Therefore, Authorize.Net's
372 referrer "security" is not necessary. In your Authorize.Net interface at
373 https://secure.authorize.net/ make sure the list of allowable referers is
374 blank. Alternatively, set the B<referer> field in the transaction content.
376 To settle an authorization-only transaction (where you set action to
377 'Authorization Only'), submit the nine-digit transaction id code in
378 the field "order_number" with the action set to "Post Authorization".
379 You can get the transaction id from the authorization by calling the
380 order_number method on the object returned from the authorization.
381 You must also submit the amount field with a value less than or equal
382 to the amount specified in the original authorization.
384 For the subscription actions an authorization code is never returned by
385 the module. Instead it returns the value of subscriptionId in order_number.
386 This is the value to use for changing or cancelling subscriptions.
388 Authorize.Net has turned address verification on by default for all merchants
389 since 2002. If you do not have valid address information for your customer
390 (such as in an IVR application), you must disable address verification in the
391 Merchant Menu page at https://secure.authorize.net/ so that the transactions
392 aren't denied due to a lack of address information.
396 This module implements Authorize.Net's API using the Advanced Integration
397 Method (AIM) version 3.1, formerly known as ADC Direct Response and the
398 Automatic Recurring Billing version 1.0 using the XML interface. See
399 http://www.authorize.net/support/AIM_guide.pdf and http://www.authorize.net/support/ARB_guide.pdf for details.
403 Original author: Jason Kohles, jason@mediabang.com
405 Ivan Kohler <ivan-authorizenet@freeside.biz> updated it for Authorize.Net
406 protocol 3.0/3.1 and is the current maintainer. Please see the next section
407 for for information on contributing.
409 Jason Spence <jspence@lightconsulting.com> contributed support for separate
410 Authorization Only and Post Authorization steps and wrote some docs.
411 OST <services@ostel.com> paid for it.
413 Jeff Finucane <authorizenetarb@weasellips.com> added the ARB support.
414 ARB support sponsored by Plus Three, LP. L<http://www.plusthree.com>.
416 T.J. Mather <tjmather@maxmind.com> sent a number of CVV2 patches.
418 Mike Barry <mbarry@cos.com> sent in a patch for the referer field and a fix for
421 Yuri V. Mkrtumyan <yuramk@novosoft.ru> sent in a patch to add the void action.
423 Paul Zimmer <AuthorizeNetpm@pzimmer.box.bepress.com> sent in a patch for
424 card-less post authorizations.
426 Daemmon Hughes <daemmon@daemmonhughes.com> sent in a patch for "transaction
427 key" authentication as well support for the recurring_billing flag and the md5
428 method that returns the MD5 hash which is returned by the gateway.
430 Steve Simitzis contributed a patch for better compatibility with
431 eProcessingNetwork's AuthorizeNet compatability mode.
433 Michael G. Schwern contributed cleanups, test fixes, and more.
435 Erik Hollensbe implemented card-present data (track1/track2), the
436 duplicate_window parameter, and test fixes.
438 Paul Timmins added the check_number field.
440 Nate Nuss implemented the ("Additional Shipping Information (Level 2 Data)"
441 fields: tax, freight, duty, tax_exempt, po_number.
443 Michael Peters fixed a bug in email address handling.
445 =head1 CONTRIBUTIONS AND REPOSITORY
447 Please send patches as unified diffs (diff -u) to (in order of preference):
453 http://rt.cpan.org/Public/Bug/Report.html?Queue=Business-OnlinePayment-AuthorizeNet
455 =item The bop-devel mailing list
457 http://420.am/cgi-bin/mailman/listinfo/bop-devel
461 Ivan Kohler <ivan-authorizenet@freeside.biz>
465 The code is available from our public CVS repository:
467 export CVSROOT=":pserver:anonymous@cvs.freeside.biz:/home/cvs/cvsroot"
469 # The password for the user `anonymous' is `anonymous'.
470 cvs checkout Business-OnlinePayment-AuthorizeNet
474 http://freeside.biz/cgi-bin/viewvc.cgi/Business-OnlinePayment-AuthorizeNet/
478 perl(1). L<Business::OnlinePayment>.