debian package for 3.24 release
[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.24_01';
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 information on contributing.
413
414 Jonathan Prykop <jonathan@freeside.biz> is currently a co-maintainer.
415
416 Jason Spence <jspence@lightconsulting.com> contributed support for separate
417 Authorization Only and Post Authorization steps and wrote some docs.
418 OST <services@ostel.com> paid for it.
419
420 Jeff Finucane <authorizenetarb@weasellips.com> added the ARB support.
421 ARB support sponsored by Plus Three, LP. L<http://www.plusthree.com>.
422
423 T.J. Mather <tjmather@maxmind.com> sent a number of CVV2 patches.
424
425 Mike Barry <mbarry@cos.com> sent in a patch for the referer field and a fix for
426 ship_company.
427
428 Yuri V. Mkrtumyan <yuramk@novosoft.ru> sent in a patch to add the void action.
429
430 Paul Zimmer <AuthorizeNetpm@pzimmer.box.bepress.com> sent in a patch for
431 card-less post authorizations.
432
433 Daemmon Hughes <daemmon@daemmonhughes.com> sent in a patch for "transaction
434 key" authentication as well support for the recurring_billing flag and the md5
435 method that returns the MD5 hash which is returned by the gateway.
436
437 Steve Simitzis contributed a patch for better compatibility with
438 eProcessingNetwork's AuthorizeNet compatibility mode.
439
440 Michael G. Schwern contributed cleanups, test fixes, and more.
441
442 Erik Hollensbe implemented card-present data (track1/track2), the
443 duplicate_window parameter, and test fixes.
444
445 Paul Timmins added the check_number field.
446
447 Nate Nuss implemented the ("Additional Shipping Information (Level 2 Data)"
448 fields: tax, freight, duty, tax_exempt, po_number.
449
450 Michael Peters fixed a bug in email address handling.
451
452 Thomas Sibley <trs@bestpractical.com> wrote B:OP:AuthorizeNet::AIM::ErrorCodes
453 which was borged and used to provide more descriptive error messages.
454
455 Craig Pearlman <cpearlma@yahoo.com> sent in a patch to more accurately declare
456 required fields for E-check transcations.
457
458 =head1 CONTRIBUTIONS AND REPOSITORY
459
460 Please send patches as unified diffs (diff -u) to (in order of preference):
461
462 =over 4
463
464 =item CPAN RT
465
466 http://rt.cpan.org/Public/Bug/Report.html?Queue=Business-OnlinePayment-AuthorizeNet
467
468 =item The bop-devel mailing list
469
470 http://perl.business/cgi-bin/mailman/listinfo/bop-devel
471
472 =item Ivan
473
474 Ivan Kohler <ivan-authorizenet@freeside.biz>
475
476 =back
477
478 The code is available from our public git repository:
479
480   git clone git://git.freeside.biz/Business-OnlinePayment-AuthorizeNet.git
481
482 Or on the web:
483
484   http://freeside.biz/gitweb/?p=Business-OnlinePayment-AuthorizeNet.git
485
486 =head1 A WORD FROM OUR SPONSOR
487
488 This module and the Business::OnlinePayment framework are maintained by by
489 Freeside Internet Services.  If you need a complete, open-source web-based
490 application to manage your customers, billing and trouble ticketing, please
491 visit http://freeside.biz/
492
493 =head1 COPYRIGHT & LICENSE
494
495 Copyright 2010-2016 Freeside Internet Services, Inc.
496 Copyright 2008 Thomas Sibley
497 All rights reserved.
498
499 This program is free software; you can redistribute it and/or modify it
500 under the same terms as Perl itself.
501
502 =head1 SEE ALSO
503
504 perl(1). L<Business::OnlinePayment>.
505
506 =cut
507