- minor cleanup of test drivers
[Business-OnlinePayment.git] / OnlinePayment.pm
1 package Business::OnlinePayment;
2
3 use strict;
4 use vars qw($VERSION);
5 use Carp;
6 use Symbol;
7
8 require 5.005;
9
10 $VERSION = '3.00_04';
11 $VERSION = eval $VERSION; # modperlstyle: convert the string into a number
12
13 # Remember subclasses we have "wrapped" submit() with _pre_submit()
14 my %WrappedSubmitClassMethod = ();
15
16 my %fields = (
17     authorization    => undef,
18     error_message    => undef,
19     failure_status   => undef,
20     fraud_detect     => undef,
21     is_success       => undef,
22     maximum_risk     => undef,
23     path             => undef,
24     port             => undef,
25     require_avs      => undef,
26     result_code      => undef,
27     server           => undef,
28     server_response  => undef,
29     test_transaction => undef,
30     transaction_type => undef,
31 );
32
33 sub new {
34     my($class,$processor,%data) = @_;
35
36     Carp::croak("unspecified processor") unless $processor;
37
38     my $subclass = "${class}::$processor";
39     if(!defined(&$subclass)) {
40         eval "use $subclass";
41         Carp::croak("unknown processor $processor ($@)") if $@;
42     }
43
44     my $self = bless {processor => $processor}, $subclass;
45     $self->build_subs(keys %fields);
46
47     if($self->can("set_defaults")) {
48         $self->set_defaults();
49     }
50
51     foreach(keys %data) {
52         my $key = lc($_);
53         my $value = $data{$_};
54         $key =~ s/^\-+//;
55         $self->build_subs($key);
56         $self->$key($value);
57     }
58
59     unless ( $subclass->can('submit') eq $class->can('submit') ) {
60         my $submit = qualify_to_ref('submit', $subclass);
61
62         # "wrap" submit ONLY once, cache info for later calls to new()
63         if ( ! exists $WrappedSubmitClassMethod{$subclass} ) {
64             no warnings 'redefine';
65             no strict 'refs';
66
67             $WrappedSubmitClassMethod{$subclass} = \&$submit;
68             *{"${subclass}::submit"} = sub {
69                 my $self = shift;
70                 $self->_pre_submit();
71             }
72         }
73         $self->{_child_submit} = $WrappedSubmitClassMethod{$subclass};
74     }
75
76     return $self;
77 }
78
79 sub _risk_detect {
80     my ($self, $risk_transaction) = @_;
81
82     my %parent_content = $self->content();
83     $parent_content{action} = 'Fraud Detect';
84     $risk_transaction->content( %parent_content );
85     $risk_transaction->submit();
86     if ($risk_transaction->is_success()) {
87         if ( $risk_transaction->fraud_score <= $self->maximum_fraud_score()) {
88             $self->{_child_submit}->($self);
89         } else {
90             $self->is_success(0);
91             $self->error_message('Excessive risk from risk management');
92         }
93     } else {
94         $self->error_message('Error in risk detection stage: ' .  $risk_transaction->error_message);
95         $self->is_success(0);
96     }
97 }
98
99 sub _pre_submit {
100     my ($self) = @_;
101     my $fraud_detection = $self->fraud_detect();
102
103     # early return if user does not want optional risk mgt
104     return $self->{_child_submit}->($self,@_) unless $fraud_detection && length $fraud_detection;
105
106     # Search for an appropriate FD module
107     foreach my $subclass ( q(Business::OnlinePayment::) . $fraud_detection,
108                            q(Business::FraudDetect::) . $fraud_detection) {
109
110         if (!defined(&$subclass)) {
111             eval "use $subclass";
112             if ($@) {
113                 Carp::croak("serious problem loading fraud_detection module ($@)") unless
114                     $@ =~ m/^Can\'t locate/;
115             } else {
116                 my $risk_tx = bless ( { processor => $fraud_detection } , $subclass );
117                 $risk_tx->build_subs(keys %fields);
118                 if ($risk_tx->can('set_defaults')) {
119                     $risk_tx->set_defaults();
120                 }
121                 $risk_tx->_glean_parameters_from_parent($self);
122                 return $self->_risk_detect($risk_tx);
123             }
124         }
125     }
126 };
127
128 sub content {
129     my($self,%params) = @_;
130
131     if(%params) {
132         if($params{'type'}) { $self->transaction_type($params{'type'}); }
133         %{$self->{'_content'}} = %params;
134     }
135     return exists $self->{'_content'} ? %{$self->{'_content'}} : ();
136 }
137
138 sub required_fields {
139     my($self,@fields) = @_;
140
141     my @missing;
142     my %content = $self->content();
143     foreach(@fields) {
144         push(@missing, $_) unless exists $content{$_};
145     }
146
147     Carp::croak("missing required field(s): " . join(", ", @missing) . "\n")
148           if(@missing);
149 }
150
151 sub get_fields {
152     my($self, @fields) = @_;
153
154     my %content = $self->content();
155
156     #my %new = ();
157     #foreach(@fields) { $new{$_} = $content{$_}; }
158     #return %new;
159     map { $_ => $content{$_} } grep defined $content{$_}, @fields;
160 }
161
162 sub remap_fields {
163     my($self,%map) = @_;
164
165     my %content = $self->content();
166     foreach( keys %map ) {
167         $content{$map{$_}} = $content{$_};
168     }
169     $self->content(%content);
170 }
171
172 sub submit {
173     my($self) = @_;
174
175     Carp::croak("Processor subclass did not override submit function");
176 }
177
178 sub dump_contents {
179     my($self) = @_;
180
181     my %content = $self->content();
182     my $dump = "";
183     foreach(sort keys %content) {
184         $dump .= "$_ = $content{$_}\n";
185     }
186     return $dump;
187 }
188
189 # didnt use AUTOLOAD because Net::SSLeay::AUTOLOAD passes right to
190 # AutoLoader::AUTOLOAD, instead of passing up the chain
191 sub build_subs {
192     my $self = shift;
193
194     foreach(@_) {
195         next if($self->can($_));
196         eval "sub $_ { my \$self = shift; if(\@_) { \$self->{$_} = shift; } return \$self->{$_}; }";
197     }
198 }
199
200 1;
201
202 __END__
203
204 =head1 NAME
205
206 Business::OnlinePayment - Perl extension for online payment processing
207
208 =head1 SYNOPSIS
209
210   use Business::OnlinePayment;
211   
212   my $transaction = new Business::OnlinePayment($processor, %processor_info);
213   $transaction->content(
214                         type        => 'Visa',
215                         amount      => '49.95',
216                         card_number => '1234123412341238',
217                         expiration  => '0100',
218                         name        => 'John Q Doe',
219                        );
220   $transaction->submit();
221   
222   if($transaction->is_success()) {
223     print "Card processed successfully: ", $transaction->authorization(), "\n";
224   } else {
225     print "Card was rejected: ", $transaction->error_message(), "\n";
226   }
227
228 =head1 DESCRIPTION
229
230 Business::OnlinePayment is a generic module for processing payments
231 through online credit card processors, electronic cash systems, etc.
232
233 =head1 METHODS AND FUNCTIONS
234
235 =head2 new($processor, %processor_options);
236
237 Create a new Business::OnlinePayment object, $processor is required,
238 and defines the online processor to use.  If necessary, processor
239 options can be specified, currently supported options are 'Server',
240 'Port', and 'Path', which specify how to find the online processor
241 (https://server:port/path), but individual processor modules should
242 supply reasonable defaults for this information, override the defaults
243 only if absolutely necessary (especially path), as the processor
244 module was probably written with a specific target script in mind.
245
246 =head2 content(%content);
247
248 The information necessary for the transaction, this tends to vary a
249 little depending on the processor, so we have chosen to use a system
250 which defines specific fields in the frontend which get mapped to the
251 correct fields in the backend.  The currently defined fields are:
252
253 =over 4
254
255 =item * type
256
257 Transaction type, supported types are:
258 Visa, MasterCard, American Express, Discover, Check (not all
259 processors support all these transaction types).
260
261 =item * login
262
263 Your login name to use for authentication to the online processor.
264
265 =item * password
266
267 Your password to use for authentication to the online processor.
268
269 =item * action
270
271 What to do with the transaction (currently available are: Normal
272 Authorization, Authorization Only, Credit, Post Authorization)
273
274 =item * description
275
276 A description of the transaction (used by some processors to send
277 information to the client, normally not a required field).
278
279 =item * amount
280
281 The amount of the transaction, most processors don't want dollar signs
282 and the like, just a floating point number.
283
284 =item * invoice_number
285
286 An invoice number, for your use and not normally required, many
287 processors require this field to be a numeric only field.
288
289 =item * customer_id
290
291 A customer identifier, again not normally required.
292
293 =item * name
294
295 The customers name, your processor may not require this.
296
297 =item * address
298
299 The customers address (your processor may not require this unless you
300 are requiring AVS Verification).
301
302 =item * city
303
304 The customers city (your processor may not require this unless you are
305 requiring AVS Verification).
306
307 =item * state
308
309 The customers state (your processor may not require this unless you
310 are requiring AVS Verification).
311
312 =item * zip
313
314 The customers zip code (your processor may not require this unless you
315 are requiring AVS Verification).
316
317 =item * country
318
319 Customer's country.
320
321 =item * phone
322
323 Customer's phone number.
324
325 =item * fax
326
327 Customer's fax number.
328
329 =item * email
330
331 Customer's email address.
332
333 =item * card_number
334
335 Credit card number (obviously not required for non-credit card
336 transactions).
337
338 =item * expiration
339
340 Credit card expiration (obviously not required for non-credit card
341 transactions).
342
343 =item * account_number
344
345 Bank account number for electronic checks or electronic funds transfer.
346
347 =item * routing_code
348
349 Bank's routing code for electronic checks or electronic funds transfer.
350
351 =item * bank_name
352
353 Bank's name for electronic checks or electronic funds transfer.
354
355 =back
356
357 =head2 submit();
358
359 Submit the transaction to the processor for completion
360
361 =head2 is_success();
362
363 Returns true if the transaction was submitted successfully, false if
364 it failed (or undef if it has not been submitted yet).
365
366 =head2 failure_status();
367
368 If the transaction failed, it can optionally return a specific
369 failure status (normalized, not gateway-specific).  Currently defined
370 statuses are: "expired", "nsf" (non-sufficient funds), "stolen",
371 "pickup", "blacklisted" and "declined" (card/transaction declines
372 only, not other errors).
373
374 Note that (as of Aug 2006) this is only supported by some of the
375 newest processor modules, and that, even if supported, a failure
376 status is an entirely optional field that is only set for specific
377 kinds of failures.
378
379 =head2 result_code();
380
381 Returns the precise result code that the processor returned, these are
382 normally one letter codes that don't mean much unless you understand
383 the protocol they speak, you probably don't need this, but it's there
384 just in case.
385
386 =head2 test_transaction();
387
388 Most processors provide a test mode, where submitted transactions will
389 not actually be charged or added to your batch, calling this function
390 with a true argument will turn that mode on if the processor supports
391 it, or generate a fatal error if the processor does not support a test
392 mode (which is probably better than accidentally making real charges).
393
394 =head2 require_avs();
395
396 Providing a true argument to this module will turn on address
397 verification (if the processor supports it).
398
399 =head2 transaction_type();
400
401 Retrieve the transaction type (the 'type' argument to contents();).
402 Generally only used internally, but provided in case it is useful.
403
404 =head2 error_message();
405
406 If the transaction has been submitted but was not accepted, this
407 function will return the provided error message (if any) that the
408 processor returned.
409
410 =head2 authorization();
411
412 If the transaction has been submitted and accepted, this function will
413 provide you with the authorization code that the processor returned.
414
415 =head2 server();
416
417 Retrieve or change the processor submission server address (CHANGE AT
418 YOUR OWN RISK).
419
420 =head2 port();
421
422 Retrieve or change the processor submission port (CHANGE AT YOUR OWN RISK).
423
424 =head2 path();
425
426 Retrieve or change the processor submission path (CHANGE AT YOUR OWN RISK).
427
428 =head1 AUTHORS
429
430 Jason Kohles, email@jasonkohles.com
431
432 (v3 rewrite) Ivan Kohler <ivan-business-onlinepayment@420.am>
433
434 Phil Lobbes E<lt>phil at perkpartners dot comE<gt>
435
436 =head1 DISCLAIMER
437
438 THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
439 WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
440 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
441
442 =head1 SEE ALSO
443
444 http://420.am/business-onlinepayment/
445
446 For verification of credit card checksums, see L<Business::CreditCard>.
447
448 =cut