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