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 as password) with every transaction. Therefore,
372 Authorize.Net's referrer "security" is not necessary. In your Authorize.Net
373 interface at https://secure.authorize.net/ make sure the list of allowable
374 referers is blank. Alternatively, set the B<referer> field in the transaction
377 To settle an authorization-only transaction (where you set action to
378 'Authorization Only'), submit the nine-digit transaction id code in
379 the field "order_number" with the action set to "Post Authorization".
380 You can get the transaction id from the authorization by calling the
381 order_number method on the object returned from the authorization.
382 You must also submit the amount field with a value less than or equal
383 to the amount specified in the original authorization.
385 For the subscription actions an authorization code is never returned by
386 the module. Instead it returns the value of subscriptionId in order_number.
387 This is the value to use for changing or cancelling subscriptions.
389 Authorize.Net has turned address verification on by default for all merchants
390 since 2002. If you do not have valid address information for your customer
391 (such as in an IVR application), you must disable address verification in the
392 Merchant Menu page at https://secure.authorize.net/ so that the transactions
393 aren't denied due to a lack of address information.
397 This module implements Authorize.Net's API using the Advanced Integration
398 Method (AIM) version 3.1, formerly known as ADC Direct Response and the
399 Automatic Recurring Billing version 1.0 using the XML interface. See
400 http://www.authorize.net/support/AIM_guide.pdf and http://www.authorize.net/support/ARB_guide.pdf for details.
404 Original author: Jason Kohles, jason@mediabang.com
406 Ivan Kohler <ivan-authorizenet@freeside.biz> updated it for Authorize.Net
407 protocol 3.0/3.1 and is the current maintainer. Please see the next section
408 for for information on contributing.
410 Jason Spence <jspence@lightconsulting.com> contributed support for separate
411 Authorization Only and Post Authorization steps and wrote some docs.
412 OST <services@ostel.com> paid for it.
414 Jeff Finucane <authorizenetarb@weasellips.com> added the ARB support.
415 ARB support sponsored by Plus Three, LP. L<http://www.plusthree.com>.
417 T.J. Mather <tjmather@maxmind.com> sent a number of CVV2 patches.
419 Mike Barry <mbarry@cos.com> sent in a patch for the referer field and a fix for
422 Yuri V. Mkrtumyan <yuramk@novosoft.ru> sent in a patch to add the void action.
424 Paul Zimmer <AuthorizeNetpm@pzimmer.box.bepress.com> sent in a patch for
425 card-less post authorizations.
427 Daemmon Hughes <daemmon@daemmonhughes.com> sent in a patch for "transaction
428 key" authentication as well support for the recurring_billing flag and the md5
429 method that returns the MD5 hash which is returned by the gateway.
431 Steve Simitzis contributed a patch for better compatibility with
432 eProcessingNetwork's AuthorizeNet compatability mode.
434 Michael G. Schwern contributed cleanups, test fixes, and more.
436 Erik Hollensbe implemented card-present data (track1/track2), the
437 duplicate_window parameter, and test fixes.
439 Paul Timmins added the check_number field.
441 Nate Nuss implemented the ("Additional Shipping Information (Level 2 Data)"
442 fields: tax, freight, duty, tax_exempt, po_number.
444 Michael Peters fixed a bug in email address handling.
446 =head1 CONTRIBUTIONS AND REPOSITORY
448 Please send patches as unified diffs (diff -u) to (in order of preference):
454 http://rt.cpan.org/Public/Bug/Report.html?Queue=Business-OnlinePayment-AuthorizeNet
456 =item The bop-devel mailing list
458 http://420.am/cgi-bin/mailman/listinfo/bop-devel
462 Ivan Kohler <ivan-authorizenet@freeside.biz>
466 The code is available from our public CVS repository:
468 export CVSROOT=":pserver:anonymous@cvs.freeside.biz:/home/cvs/cvsroot"
470 # The password for the user `anonymous' is `anonymous'.
471 cvs checkout Business-OnlinePayment-AuthorizeNet
475 http://freeside.biz/cgi-bin/viewvc.cgi/Business-OnlinePayment-AuthorizeNet/
479 perl(1). L<Business::OnlinePayment>.