--- /dev/null
+package Business::OnlinePayment::eSelectPlus;\r
+\r
+use strict;\r
+use Carp;\r
+use Tie::IxHash;\r
+use Business::OnlinePayment 3;\r
+use Business::OnlinePayment::HTTPS;\r
+use vars qw($VERSION $DEBUG @ISA);\r
+\r
+@ISA = qw(Business::OnlinePayment::HTTPS);\r
+$VERSION = '0.01';\r
+$DEBUG = 0;\r
+\r
+sub set_defaults {\r
+ my $self = shift;\r
+\r
+ $self->server('esqa.moneris.com');\r
+ $self->port('443');\r
+ $self->path('/gateway2/servlet/MpgRequest');\r
+\r
+ $self->build_subs(qw( order_number ));\r
+ # avs_code order_type md5 cvv2_response cavv_response\r
+}\r
+\r
+sub submit {\r
+ my($self) = @_;\r
+\r
+ #$self->map_fields();\r
+ $self->remap_fields(\r
+ # => 'order_type',\r
+ # => 'transaction_type',\r
+ #login => 'store_id',\r
+ #password => 'api_token',\r
+ #authorization => \r
+ #customer_ip =>\r
+ #name =>\r
+ #first_name =>\r
+ #last_name =>\r
+ #company =>\r
+ #address => \r
+ #city => \r
+ #state => \r
+ #zip => \r
+ #country =>\r
+ phone => \r
+ #fax =>\r
+ email =>\r
+ card_number => 'pan',\r
+ #expiration =>\r
+ # => 'expdate',\r
+\r
+ 'amount' => 'amount',\r
+ #invoice_number =>\r
+ #customer_id =>\r
+ order_number => 'order_id',\r
+ authorization => 'txn_number'\r
+\r
+ #cvv2 =>\r
+ );\r
+\r
+ my $action = $self->{_content}{'action'};\r
+ if ( $self->{_content}{'action'} =~ /^\s*normal\s*authorization\s*$/i ) {\r
+ $action = 'purchase';\r
+ } elsif ( $self->{_content}{'action'} =~ /^\s*authorization\s*only\s*$/i ) {\r
+ $action = 'preauth';\r
+ } elsif ( $self->{_content}{'action'} =~ /^\s*post\s*authorization\s*$/i ) {\r
+ $action = 'completion';\r
+ } elsif ( $self->{_content}{'action'} =~ /^\s*void\s*$/i ) {\r
+ $action = 'void';\r
+ } elsif ( $self->{_content}{'action'} =~ /^\s*credit\s*$/i ) {\r
+ if ( $self->{_content}{'authorization'} ) {\r
+ $action = 'refund';\r
+ } else {\r
+ $action = 'ind_refund';\r
+ }\r
+ }\r
+\r
+ if ( $action =~ /^(purchase|preauth|ind_refund)$/ ) {\r
+\r
+ $self->required_fields(\r
+ qw( login password amount card_number expiration )\r
+ );\r
+\r
+ #cardexpiremonth & cardexpireyear\r
+ $self->{_content}{'expiration'} =~ /^(\d+)\D+\d*(\d{2})$/\r
+ or croak "unparsable expiration ". $self->{_content}{expiration};\r
+ my( $month, $year ) = ( $1, $2 );\r
+ $month = '0'. $month if $month =~ /^\d$/;\r
+ $self->{_content}{expdate} = $year.$month;\r
+\r
+ $self->generate_order_id;\r
+\r
+ $self->{_content}{amount} = sprintf('%.2f', $self->{_content}{amount} );\r
+\r
+ } elsif ( $action eq 'completion' || $action eq 'void' ) {\r
+\r
+ $self->required_fields( qw( login password order_number authorization ) );\r
+\r
+ } elsif ( $action eq 'refund' ) {\r
+\r
+ $self->required_fields(\r
+ qw( login passowrd order_number authorization )\r
+ );\r
+\r
+ }\r
+\r
+ $self->{_content}{'crypt_type'} ||= 7;\r
+\r
+ #no, values aren't escaped for XML. their "mpgClasses.pl" example doesn't\r
+ #appear to do so, i dunno\r
+ tie my %fields, 'Tie::IxHash', $self->get_fields( $self->fields );\r
+ my $post_data =\r
+ '<?xml version="1.0"?>'.\r
+ '<request>'.\r
+ '<store_id>'. $self->{_content}{'login'}. '</store_id>'.\r
+ '<api_token>'. $self->{_content}{'password'}. '</api_token>'.\r
+ "<$action>".\r
+ join('', map "<$_>$fields{$_}</$_>", keys %fields ).\r
+ "</$action>".\r
+ '</request>';\r
+\r
+ warn $post_data if $DEBUG > 1;\r
+\r
+ my( $page, $response, @reply_headers) = $self->https_post( $post_data );\r
+\r
+ #my %reply_headers = @reply_headers;\r
+ #warn join('', map { " $_ => $reply_headers{$_}\n" } keys %reply_headers )\r
+ # if $DEBUG;\r
+\r
+ #XXX check $response and die if not 200?\r
+\r
+ # avs_code\r
+ # is_success\r
+ # result_code\r
+ # authorization\r
+ #md5 cvv2_response cavv_response ...?\r
+\r
+ $self->server_response($page);\r
+\r
+ my $result = $self->GetXMLProp($page, 'ResponseCode');\r
+\r
+ die "gateway error: ". $self->GetXMLProp( $page, 'Message' )\r
+ if $result =~ /^null$/i;\r
+\r
+ if ( $result =~ /^\d+$/ && $result < 50 ) {\r
+ $self->is_success(1);\r
+ $self->result_code( $self->GetXMLProp( $page, 'ISO' ) );\r
+ $self->authorization( $self->GetXMLProp( $page, 'Txn_number' ) );\r
+ $self->order_number( $self->GetXMLProp( $page, 'order_id') );\r
+ } elsif ( $result =~ /^\d+$/ ) {\r
+ $self->is_success(0);\r
+ $self->error_message( $self->GetXMLProp( $page, 'Message' ) );\r
+ } else {\r
+ die "unparsable response received from gateway (response $result)".\r
+ ( $DEBUG ? ": $page" : '' );\r
+ }\r
+\r
+}\r
+\r
+use vars qw(@oidset);\r
+@oidset = ( 'A'..'Z', '0'..'9' );\r
+sub generate_order_id {\r
+ my $self = shift;\r
+ #generate an order_id if order_number not passed\r
+ unless ( exists ($self->{_content}{order_id})\r
+ && defined($self->{_content}{order_id})\r
+ && length ($self->{_content}{order_id})\r
+ ) {\r
+ $self->{_content}{'order_id'} =\r
+ join('', map { $oidset[int(rand(scalar(@oidset)))] } (1..23) );\r
+ }\r
+}\r
+\r
+sub fields {\r
+ my $self = shift;\r
+\r
+ #order is important to this processor\r
+ qw(\r
+ order_id\r
+ cust_id\r
+ amount\r
+ comp_amount\r
+ txn_number\r
+ pan\r
+ expdate\r
+ crypt_type\r
+ cavv\r
+ );\r
+}\r
+\r
+sub GetXMLProp {\r
+ my( $self, $raw, $prop ) = @_;\r
+ local $^W=0;\r
+\r
+ my $data;\r
+ ($data) = $raw =~ m"<$prop>(.*?)</$prop>"gsi;\r
+ #$data =~ s/<.*?>/ /gs;\r
+ chomp $data;\r
+ return $data;\r
+}\r
+\r
+1;\r
+\r
+__END__\r
+\r
+=head1 NAME\r
+\r
+Business::OnlinePayment::eSelectPlus - Moneris eSelect Plus backend module for Business::OnlinePayment\r
+\r
+=head1 SYNOPSIS\r
+\r
+ use Business::OnlinePayment;\r
+\r
+ ####\r
+ # One step transaction, the simple case.\r
+ ####\r
+\r
+ my $tx = new Business::OnlinePayment("eSelectPlus");\r
+ $tx->content(\r
+ type => 'VISA',\r
+ login => 'eSelect Store ID,\r
+ password => 'eSelect API Token',\r
+ action => 'Normal Authorization',\r
+ description => 'Business::OnlinePayment test',\r
+ amount => '49.95',\r
+ name => 'Tofu Beast',\r
+ address => '123 Anystreet',\r
+ city => 'Anywhere',\r
+ state => 'UT',\r
+ zip => '84058',\r
+ phone => '420-867-5309',\r
+ email => 'tofu.beast@example.com',\r
+ card_number => '4005550000000019',\r
+ expiration => '08/06',\r
+ cvv2 => '1234', #optional\r
+ );\r
+ $tx->submit();\r
+\r
+ if($tx->is_success()) {\r
+ print "Card processed successfully: ".$tx->authorization."\n";\r
+ } else {\r
+ print "Card was rejected: ".$tx->error_message."\n";\r
+ }\r
+\r
+=head1 SUPPORTED TRANSACTION TYPES\r
+\r
+=head2 CC, Visa, MasterCard, American Express, Discover\r
+\r
+Content required: type, login, password, action, amount, card_number, expiration.\r
+\r
+=head1 PREREQUISITES\r
+\r
+ URI::Escape\r
+ Tie::IxHash\r
+\r
+ Net::SSLeay _or_ ( Crypt::SSLeay and LWP )\r
+\r
+=head1 DESCRIPTION\r
+\r
+For detailed information see L<Business::OnlinePayment>.\r
+\r
+=head1 NOTE\r
+\r
+=head1 AUTHOR\r
+\r
+Ivan Kohler <ivan-eselectplus@420.am>\r
+\r
+=head1 SEE ALSO\r
+\r
+perl(1). L<Business::OnlinePayment>.\r
+\r
+=cut\r
+\r