1 package Business::OnlinePayment;
10 $VERSION = eval $VERSION; # modperlstyle: convert the string into a number
12 # Remember subclasses we have "wrapped" submit() with _pre_submit()
13 my %Presubmit_Added = ();
16 authorization => undef,
17 error_message => undef,
18 failure_status => undef,
19 fraud_detect => undef,
21 maximum_risk => undef,
27 server_response => undef,
28 test_transaction => undef,
29 transaction_type => undef,
33 my($class,$processor,%data) = @_;
35 Carp::croak("unspecified processor") unless $processor;
37 my $subclass = "${class}::$processor";
38 if(!defined(&$subclass)) {
40 Carp::croak("unknown processor $processor ($@)") if $@;
43 my $self = bless {processor => $processor}, $subclass;
44 $self->build_subs(keys %fields);
46 if($self->can("set_defaults")) {
47 $self->set_defaults();
52 my $value = $data{$_};
54 $self->build_subs($key);
58 # "wrap" submit with _pre_submit only once
59 unless ( $Presubmit_Added{$subclass} ) {
60 my $real_submit = $subclass->can('submit');
62 no warnings 'redefine';
65 *{"${subclass}::submit"} = sub {
67 return unless $self->_pre_submit(@_);
68 return $real_submit->($self, @_);
76 my ($self, $risk_transaction) = @_;
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()) {
87 $self->error_message('Excessive risk from risk management');
90 $self->error_message('Error in risk detection stage: ' . $risk_transaction->error_message);
97 my $fraud_detection = $self->fraud_detect();
99 # early return if user does not want optional risk mgt
100 return 1 unless $fraud_detection;
102 # Search for an appropriate FD module
103 foreach my $subclass ( q(Business::OnlinePayment::) . $fraud_detection,
104 q(Business::FraudDetect::) . $fraud_detection) {
106 if (!defined(&$subclass)) {
107 eval "use $subclass";
109 Carp::croak("serious problem loading fraud_detection module ($@)") unless
110 $@ =~ m/^Can\'t locate/;
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();
117 $risk_tx->_glean_parameters_from_parent($self);
118 return $self->_risk_detect($risk_tx);
125 my($self,%params) = @_;
128 if($params{'type'}) { $self->transaction_type($params{'type'}); }
129 %{$self->{'_content'}} = %params;
131 return exists $self->{'_content'} ? %{$self->{'_content'}} : ();
134 sub required_fields {
135 my($self,@fields) = @_;
138 my %content = $self->content();
140 push(@missing, $_) unless exists $content{$_};
143 Carp::croak("missing required field(s): " . join(", ", @missing) . "\n")
148 my($self, @fields) = @_;
150 my %content = $self->content();
153 #foreach(@fields) { $new{$_} = $content{$_}; }
155 map { $_ => $content{$_} } grep defined $content{$_}, @fields;
161 my %content = $self->content();
162 foreach( keys %map ) {
163 $content{$map{$_}} = $content{$_};
165 $self->content(%content);
171 Carp::croak("Processor subclass did not override submit function");
177 my %content = $self->content();
179 foreach(sort keys %content) {
180 $dump .= "$_ = $content{$_}\n";
185 # didnt use AUTOLOAD because Net::SSLeay::AUTOLOAD passes right to
186 # AutoLoader::AUTOLOAD, instead of passing up the chain
191 next if($self->can($_));
192 eval "sub $_ { my \$self = shift; if(\@_) { \$self->{$_} = shift; } return \$self->{$_}; }";
202 Business::OnlinePayment - Perl extension for online payment processing
206 use Business::OnlinePayment;
208 my $transaction = new Business::OnlinePayment($processor, %processor_info);
209 $transaction->content(
212 card_number => '1234123412341238',
213 expiration => '0100',
214 name => 'John Q Doe',
216 $transaction->submit();
218 if($transaction->is_success()) {
219 print "Card processed successfully: ", $transaction->authorization(), "\n";
221 print "Card was rejected: ", $transaction->error_message(), "\n";
226 Business::OnlinePayment is a generic module for processing payments
227 through online credit card processors, electronic cash systems, etc.
229 =head1 METHODS AND FUNCTIONS
231 =head2 new($processor, %processor_options);
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.
242 =head2 content(%content);
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:
253 Transaction type, supported types are:
254 Visa, MasterCard, American Express, Discover, Check (not all
255 processors support all these transaction types).
259 Your login name to use for authentication to the online processor.
263 Your password to use for authentication to the online processor.
267 What to do with the transaction (currently available are: Normal
268 Authorization, Authorization Only, Credit, Post Authorization)
272 A description of the transaction (used by some processors to send
273 information to the client, normally not a required field).
277 The amount of the transaction, most processors don't want dollar signs
278 and the like, just a floating point number.
280 =item * invoice_number
282 An invoice number, for your use and not normally required, many
283 processors require this field to be a numeric only field.
287 A customer identifier, again not normally required.
291 The customers name, your processor may not require this.
295 The customers address (your processor may not require this unless you
296 are requiring AVS Verification).
300 The customers city (your processor may not require this unless you are
301 requiring AVS Verification).
305 The customers state (your processor may not require this unless you
306 are requiring AVS Verification).
310 The customers zip code (your processor may not require this unless you
311 are requiring AVS Verification).
319 Customer's phone number.
323 Customer's fax number.
327 Customer's email address.
331 Credit card number (obviously not required for non-credit card
336 Credit card expiration (obviously not required for non-credit card
339 =item * account_number
341 Bank account number for electronic checks or electronic funds transfer.
345 Bank's routing code for electronic checks or electronic funds transfer.
349 Bank's name for electronic checks or electronic funds transfer.
355 Submit the transaction to the processor for completion
359 Returns true if the transaction was submitted successfully, false if
360 it failed (or undef if it has not been submitted yet).
362 =head2 failure_status();
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).
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
375 =head2 result_code();
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
382 =head2 test_transaction();
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).
390 =head2 require_avs();
392 Providing a true argument to this module will turn on address
393 verification (if the processor supports it).
395 =head2 transaction_type();
397 Retrieve the transaction type (the 'type' argument to contents();).
398 Generally only used internally, but provided in case it is useful.
400 =head2 error_message();
402 If the transaction has been submitted but was not accepted, this
403 function will return the provided error message (if any) that the
406 =head2 authorization();
408 If the transaction has been submitted and accepted, this function will
409 provide you with the authorization code that the processor returned.
413 Retrieve or change the processor submission server address (CHANGE AT
418 Retrieve or change the processor submission port (CHANGE AT YOUR OWN RISK).
422 Retrieve or change the processor submission path (CHANGE AT YOUR OWN RISK).
426 Jason Kohles, email@jasonkohles.com
428 (v3 rewrite) Ivan Kohler <ivan-business-onlinepayment@420.am>
430 Phil Lobbes E<lt>phil at perkpartners dot comE<gt>
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.
440 http://420.am/business-onlinepayment/
442 For verification of credit card checksums, see L<Business::CreditCard>.