Documentation: add country and email fields to example (closes: CPAN#80337)
[Business-OnlinePayment-AuthorizeNet.git] / AuthorizeNet.pm
1 package Business::OnlinePayment::AuthorizeNet;
2
3 use strict;
4 use Carp;
5 use Business::OnlinePayment;
6 use vars qw($VERSION @ISA $me);
7
8 @ISA = qw(Business::OnlinePayment);
9 $VERSION = '3.23';
10 $me = 'Business::OnlinePayment::AuthorizeNet';
11
12 sub set_defaults {
13     my $self = shift;
14
15     $self->build_subs(qw( order_number md5 avs_code cvv2_response
16                           cavv_response
17                      ));
18 }
19
20 sub _map_processor {
21     my($self) = @_;
22
23     my %content = $self->content();
24     my %processors = ('recurring authorization'          => 'ARB',
25                       'modify recurring authorization'   => 'ARB',
26                       'cancel recurring authorization'   => 'ARB',
27                      );
28     $processors{lc($content{'action'})} || 'AIM';
29 }
30
31 sub submit {
32     my($self) = @_;
33
34     my $processor = $me. "::". $self->_map_processor();
35
36     eval "use $processor";
37     croak("unknown processor $processor ($@)") if $@;
38     
39     my $object = bless $self, $processor;
40     $object->set_defaults();
41     $object->submit();
42     bless $self, $me;
43 }
44
45 1;
46 __END__
47
48 =head1 NAME
49
50 Business::OnlinePayment::AuthorizeNet - AuthorizeNet backend for Business::OnlinePayment
51
52 =head1 SYNOPSIS
53
54   use Business::OnlinePayment;
55
56   ####
57   # One step transaction, the simple case.
58   ####
59
60   my $tx = new Business::OnlinePayment("AuthorizeNet");
61   $tx->content(
62       type           => 'VISA',
63       login          => 'testdrive',
64       password       => '', #password or transaction key
65       action         => 'Normal Authorization',
66       description    => 'Business::OnlinePayment test',
67       amount         => '49.95',
68       invoice_number => '100100',
69       customer_id    => 'jsk',
70       email          => 'jason@example.com',
71       first_name     => 'Jason',
72       last_name      => 'Kohles',
73       address        => '123 Anystreet',
74       city           => 'Anywhere',
75       state          => 'UT',
76       zip            => '84058',
77       country        => 'US',
78       card_number    => '4007000000027',
79       expiration     => '09/02',
80       cvv2           => '1234', #optional
81       referer        => 'http://valid.referer.url/',
82   );
83   $tx->submit();
84
85   if($tx->is_success()) {
86       print "Card processed successfully: ".$tx->authorization."\n";
87   } else {
88       print "Card was rejected: ".$tx->error_message."\n";
89   }
90
91   ####
92   # Two step transaction, authorization and capture.
93   # If you don't need to review order before capture, you can
94   # process in one step as above.
95   ####
96
97   my $tx = new Business::OnlinePayment("AuthorizeNet");
98   $tx->content(
99       type           => 'VISA',
100       login          => 'testdrive',
101       password       => '',  #password or transaction key
102       action         => 'Authorization Only',
103       description    => 'Business::OnlinePayment test',
104       amount         => '49.95',
105       invoice_number => '100100',
106       customer_id    => 'jsk',
107       email          => 'jason@example.com',
108       first_name     => 'Jason',
109       last_name      => 'Kohles',
110       address        => '123 Anystreet',
111       city           => 'Anywhere',
112       state          => 'UT',
113       zip            => '84058',
114       country        => 'US',
115       card_number    => '4007000000027',
116       expiration     => '09/02',
117       cvv2           => '1234', #optional
118       referer        => 'http://valid.referer.url/',
119   );
120   $tx->submit();
121
122   if($tx->is_success()) {
123       # get information about authorization
124       $authorization = $tx->authorization
125       $ordernum = $tx->order_number;
126       $avs_code = $tx->avs_code; # AVS Response Code
127       $cvv2_response = $tx->cvv2_response; # CVV2/CVC2/CID Response Code
128       $cavv_response = $tx->cavv_response; # Cardholder Authentication
129                                            # Verification Value (CAVV) Response
130                                            # Code
131
132       # now capture transaction
133       my $capture = new Business::OnlinePayment("AuthorizeNet");
134
135       $capture->content(
136           type           => 'CC',
137           action         => 'Post Authorization',
138           login          => 'YOURLOGIN
139           password       => 'YOURPASSWORD', #or transaction key
140           order_number   => $ordernum,
141           amount         => '49.95',
142       );
143
144       $capture->submit();
145
146       if($capture->is_success()) { 
147           print "Card captured successfully: ".$capture->authorization."\n";
148       } else {
149           print "Card was rejected: ".$capture->error_message."\n";
150       }
151
152   } else {
153       print "Card was rejected: ".$tx->error_message."\n";
154   }
155
156   ####
157   # One step subscription, the simple case.
158   ####
159
160   my $tx = new Business::OnlinePayment("AuthorizeNet::ARB");
161   $tx->content(
162       type           => 'CC',
163       login          => 'testdrive',
164       password       => 'testpass', #or transaction key
165       action         => 'Recurring Authorization',
166       interval       => '7 days',
167       start          => '2008-3-10',
168       periods        => '16',
169       amount         => '99.95',
170       trialperiods   => '4',
171       trialamount    => '0',
172       description    => 'Business::OnlinePayment test',
173       invoice_number => '1153B33F',
174       customer_id    => 'vip',
175       first_name     => 'Tofu',
176       last_name      => 'Beast',
177       address        => '123 Anystreet',
178       city           => 'Anywhere',
179       state          => 'GA',
180       zip            => '84058',
181       card_number    => '4111111111111111',
182       expiration     => '09/02',
183   );
184   $tx->submit();
185
186   if($tx->is_success()) {
187       print "Card processed successfully: ".$tx->order_number."\n";
188   } else {
189       print "Card was rejected: ".$tx->error_message."\n";
190   }
191   my $subscription = $tx->order_number
192
193
194   ####
195   # Subscription change.   Modestly more complicated.
196   ####
197
198   $tx->content(
199       type           => 'CC',
200       subscription   => '99W2C',
201       login          => 'testdrive',
202       password       => 'testpass', #or transaction key
203       action         => 'Modify Recurring Authorization',
204       interval       => '7 days',
205       start          => '2008-3-10',
206       periods        => '16',
207       amount         => '29.95',
208       trialperiods   => '4',
209       trialamount    => '0',
210       description    => 'Business::OnlinePayment test',
211       invoice_number => '1153B340',
212       customer_id    => 'vip',
213       first_name     => 'Tofu',
214       last_name      => 'Beast',
215       address        => '123 Anystreet',
216       city           => 'Anywhere',
217       state          => 'GA',
218       zip            => '84058',
219       card_number    => '4111111111111111',
220       expiration     => '09/02',
221   );
222   $tx->submit();
223
224   if($tx->is_success()) {
225       print "Update processed successfully."\n";
226   } else {
227       print "Update was rejected: ".$tx->error_message."\n";
228   }
229   $tx->content(
230       subscription   => '99W2D',
231       login          => 'testdrive',
232       password       => 'testpass', # or transaction key
233       action         => 'Cancel Recurring Authorization',
234   );
235   $tx->submit();
236
237   ####
238   # Subscription cancellation.   It happens.
239   ####
240
241   if($tx->is_success()) {
242       print "Cancellation processed successfully."\n";
243   } else {
244       print "Cancellation was rejected: ".$tx->error_message."\n";
245   }
246
247
248 =head1 SUPPORTED TRANSACTION TYPES
249
250 =head2 CC, Visa, MasterCard, American Express, Discover
251
252 Content required: type, login, password, action, amount, first_name, last_name, card_number, expiration.
253
254 =head2 Check
255
256 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).
257
258 =head2 Subscriptions
259
260 Additional content required: interval, start, periods.
261
262 =head1 DESCRIPTION
263
264 For detailed information see L<Business::OnlinePayment>.
265
266 =head1 METHODS AND FUNCTIONS
267
268 See L<Business::OnlinePayment> for the complete list. The following methods either override the methods in L<Business::OnlinePayment> or provide additional functions.  
269
270 =head2 result_code
271
272 Returns the response reason code (from the message.code field for subscriptions).
273
274 =head2 error_message
275
276 Returns the response reason text (from the message.text field for subscriptions.
277
278 =head2 server_response
279
280 Returns the complete response from the server.
281
282 =head1 Handling of content(%content) data:
283
284 =head2 action
285
286 The following actions are valid
287
288   normal authorization
289   authorization only
290   credit
291   post authorization
292   void
293   recurring authorization
294   modify recurring authorization
295   cancel recurring authorization
296
297 =head2 interval
298
299   Interval contains a number of digits, whitespace, and the units of days or months in either singular or plural form.
300   
301
302 =head1 Setting AuthorizeNet ARB parameters from content(%content)
303
304 The following rules are applied to map data to AuthorizeNet ARB parameters
305 from content(%content):
306
307       # ARB param => $content{<key>}
308       merchantAuthentication
309         name                     =>  'login',
310         transactionKey           =>  'password',
311       subscription
312         paymentSchedule
313           interval
314             length               => \( the digits in 'interval' ),
315             unit                 => \( days or months gleaned from 'interval' ),          startDate              => 'start',
316           totalOccurrences       => 'periods',
317           trialOccurrences       => 'trialperiods',
318         amount                   => 'amount',
319         trialAmount              => 'trialamount',
320         payment
321           creditCard
322             cardNumber           => 'card_number',
323             expiration           => \( $year.'-'.$month ), # YYYY-MM from 'expiration'
324           bankAccount
325             accountType          => 'account_type',
326             routingNumber        => 'routing_code',
327             accountNumber        => 'account_number,
328             nameOnAccount        => 'name',
329             bankName             => 'bank_name',
330             echeckType           => 'check_type',
331         order
332           invoiceNumber          => 'invoice_number',
333           description            => 'description',
334         customer
335           type                   => 'customer_org',
336           id                     => 'customer_id',
337           email                  => 'email',
338           phoneNumber            => 'phone',
339           faxNumber              => 'fax',
340           driversLicense
341             number               => 'license_num',
342             state                => 'license_state',
343             dateOfBirth          => 'license_dob',
344           taxid                  => 'customer_ssn',
345         billTo
346           firstName              => 'first_name',
347           lastName               => 'last_name',
348           company                => 'company',
349           address                => 'address',
350           city                   => 'city',
351           state                  => 'state',
352           zip                    => 'zip',
353           country                => 'country',
354         shipTo
355           firstName              => 'ship_first_name',
356           lastName               => 'ship_last_name',
357           company                => 'ship_company',
358           address                => 'ship_address',
359           city                   => 'ship_city',
360           state                  => 'ship_state',
361           zip                    => 'ship_zip',
362           country                => 'ship_country',
363
364 =head1 NOTES
365
366 Use your transaction key in the password field.
367
368 Unlike Business::OnlinePayment or pre-3.0 versions of
369 Business::OnlinePayment::AuthorizeNet, 3.1 requires separate first_name and
370 last_name fields.
371
372 Business::OnlinePayment::AuthorizeNet uses Authorize.Net's "Advanced
373 Integration Method (AIM) (formerly known as ADC direct response)" and
374 "Automatic Recurring Billing (ARB)", sending a username and password (or
375 transaction key as password) with every transaction.  Therefore,
376 Authorize.Net's referrer "security" is not necessary.  In your Authorize.Net
377 interface at https://secure.authorize.net/ make sure the list of allowable
378 referers is blank.  Alternatively, set the B<referer> field in the transaction
379 content.
380
381 To settle an authorization-only transaction (where you set action to
382 'Authorization Only'), submit the nine-digit transaction id code in
383 the field "order_number" with the action set to "Post Authorization".
384 You can get the transaction id from the authorization by calling the
385 order_number method on the object returned from the authorization.
386 You must also submit the amount field with a value less than or equal
387 to the amount specified in the original authorization.
388
389 For the subscription actions an authorization code is never returned by
390 the module.  Instead it returns the value of subscriptionId in order_number.
391 This is the value to use for changing or cancelling subscriptions.
392
393 Authorize.Net has turned address verification on by default for all merchants
394 since 2002.  If you do not have valid address information for your customer
395 (such as in an IVR application), you must disable address verification in the
396 Merchant Menu page at https://secure.authorize.net/ so that the transactions
397 aren't denied due to a lack of address information.
398
399 =head1 COMPATIBILITY
400
401 This module implements Authorize.Net's API using the Advanced Integration
402 Method (AIM) version 3.1, formerly known as ADC Direct Response and the 
403 Automatic Recurring Billing version 1.0 using the XML interface.  See
404 http://www.authorize.net/support/AIM_guide.pdf and http://www.authorize.net/support/ARB_guide.pdf for details.
405
406 =head1 AUTHORS
407
408 Original author: Jason Kohles, jason@mediabang.com
409
410 Ivan Kohler <ivan-authorizenet@freeside.biz> updated it for Authorize.Net
411 protocol 3.0/3.1 and is the current maintainer.  Please see the next section
412 for for information on contributing.
413
414 Jason Spence <jspence@lightconsulting.com> contributed support for separate
415 Authorization Only and Post Authorization steps and wrote some docs.
416 OST <services@ostel.com> paid for it.
417
418 Jeff Finucane <authorizenetarb@weasellips.com> added the ARB support.
419 ARB support sponsored by Plus Three, LP. L<http://www.plusthree.com>.
420
421 T.J. Mather <tjmather@maxmind.com> sent a number of CVV2 patches.
422
423 Mike Barry <mbarry@cos.com> sent in a patch for the referer field and a fix for
424 ship_company.
425
426 Yuri V. Mkrtumyan <yuramk@novosoft.ru> sent in a patch to add the void action.
427
428 Paul Zimmer <AuthorizeNetpm@pzimmer.box.bepress.com> sent in a patch for
429 card-less post authorizations.
430
431 Daemmon Hughes <daemmon@daemmonhughes.com> sent in a patch for "transaction
432 key" authentication as well support for the recurring_billing flag and the md5
433 method that returns the MD5 hash which is returned by the gateway.
434
435 Steve Simitzis contributed a patch for better compatibility with
436 eProcessingNetwork's AuthorizeNet compatibility mode.
437
438 Michael G. Schwern contributed cleanups, test fixes, and more.
439
440 Erik Hollensbe implemented card-present data (track1/track2), the
441 duplicate_window parameter, and test fixes.
442
443 Paul Timmins added the check_number field.
444
445 Nate Nuss implemented the ("Additional Shipping Information (Level 2 Data)"
446 fields: tax, freight, duty, tax_exempt, po_number.
447
448 Michael Peters fixed a bug in email address handling.
449
450 Thomas Sibley <trs@bestpractical.com> wrote B:OP:AuthorizeNet::AIM::ErrorCodes
451 which was borged and used to provide more descriptive error messages.
452
453 Craig Pearlman <cpearlma@yahoo.com> sent in a patch to more accurately declare
454 required fields for E-check transcations.
455
456 =head1 CONTRIBUTIONS AND REPOSITORY
457
458 Please send patches as unified diffs (diff -u) to (in order of preference):
459
460 =over 4
461
462 =item CPAN RT
463
464 http://rt.cpan.org/Public/Bug/Report.html?Queue=Business-OnlinePayment-AuthorizeNet
465
466 =item The bop-devel mailing list
467
468 http://420.am/cgi-bin/mailman/listinfo/bop-devel
469
470 =item Ivan
471
472 Ivan Kohler <ivan-authorizenet@freeside.biz>
473
474 =back
475
476 The code is available from our public CVS repository:
477
478   export CVSROOT=":pserver:anonymous@cvs.freeside.biz:/home/cvs/cvsroot"
479   cvs login
480   # The password for the user `anonymous' is `anonymous'.
481   cvs checkout Business-OnlinePayment-AuthorizeNet
482
483 Or on the web:
484
485   http://freeside.biz/cgi-bin/viewvc.cgi/Business-OnlinePayment-AuthorizeNet/
486
487 =head1 A WORD FROM OUR SPONSOR
488
489 This module and the Business::OnlinePayment framework are maintained by by
490 Freeside Internet Services.  If you need a complete, open-source web-based
491 application to manage your customers, billing and trouble ticketing, please
492 visit http://freeside.biz/
493
494 =head1 COPYRIGHT & LICENSE
495
496 Copyright 2010 Freeside Internet Services, Inc.
497 Copyright 2008 Thomas Sibley
498 All rights reserved.
499
500 This program is free software; you can redistribute it and/or modify it
501 under the same terms as Perl itself.
502
503 =head1 SEE ALSO
504
505 perl(1). L<Business::OnlinePayment>.
506
507 =cut
508