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