From: ivan Date: Tue, 11 Jan 2005 07:10:23 +0000 (+0000) Subject: initial checkin X-Git-Tag: BUSINESS_ONLINEPAYMENT_SECUREHOSTINGUPG_0_01 X-Git-Url: http://git.freeside.biz/gitweb/?p=Business-OnlinePayment-SecureHostingUPG.git;a=commitdiff_plain;h=e68e78321174f709f909f3bad181191dd3f3e8db initial checkin --- e68e78321174f709f909f3bad181191dd3f3e8db diff --git a/Changes b/Changes new file mode 100644 index 0000000..c8c5e61 --- /dev/null +++ b/Changes @@ -0,0 +1,2 @@ +0.01 Mon Dec 27 03:00:58 2004 + - original version; created by ivan 1.0 diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..7b7be7c --- /dev/null +++ b/MANIFEST @@ -0,0 +1,14 @@ +Changes +MANIFEST +Makefile.PL +SecureHostingUPG.pm +README +htmlgood.html +htmlbad.html +t/load.t +t/crypt_load.t +t/credit_card.t +t/crypt_credit_card.t +t/bop.t +t/bad_card.t +t/crypt_bad_card.t diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..f62e54c --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,23 @@ +use ExtUtils::MakeMaker; +# See lib/ExtUtils/MakeMaker.pm for details of how to influence +# the contents of the Makefile that is written. +WriteMakefile( + 'NAME' => 'Business::OnlinePayment::SecureHostingUPG', + 'VERSION_FROM' => 'SecureHostingUPG.pm', # finds $VERSION + 'AUTHOR' => 'Ivan Kohler ', + #'NORECURS' => 1, # dont descend into subdirectories + 'PREREQ_PM' => { + 'Business::OnlinePayment' => 0, + + # for HTTPS (maybe it should be a separate dist?) + 'URI::Escape' => 0, + 'Tie::IxHash' => 0, + + # 'Net::SSLeay' => 0, + # or 'Crypt::SSLeay' => 0, + # 'URI + + }, + #'dist' => {CI => 'ci -l'}, +); + diff --git a/README b/README new file mode 100644 index 0000000..3c3a9c3 --- /dev/null +++ b/README @@ -0,0 +1,13 @@ +Copyright (c) 2004 Ivan Kohler +All rights reserved. This program is free software; you can redistribute it +and/or modify it under the same terms as Perl itself. + +This is Business::OnlinePayment::SecureHostingUPG, an Business::OnlinePayment +backend module for the SecureHosting Universal Payment Gateway. It is only +useful if you have a merchant account with SecureHosting: +http://www.securehosting.com/sh2/upg_payment_service_provider_uk.htm + +Business::OnlinePayment is a generic interface for processing payments through +online credit card processors, online check acceptance houses, etc. (If you +like buzzwords, call it an "multiplatform ecommerce-enabling middleware +solution"). diff --git a/SecureHostingUPG.pm b/SecureHostingUPG.pm new file mode 100644 index 0000000..2ab6d1e --- /dev/null +++ b/SecureHostingUPG.pm @@ -0,0 +1,250 @@ +package Business::OnlinePayment::SecureHostingUPG; + +use strict; +use Carp; +use Business::OnlinePayment 3; +use Business::OnlinePayment::HTTPS; +use vars qw($VERSION $DEBUG @ISA); + +@ISA = qw(Business::OnlinePayment::HTTPS); +$VERSION = '0.03'; +$DEBUG = 0; + +sub set_defaults { + my $self = shift; + + $self->server('www.secure-server-hosting.com'); + $self->port('443'); + $self->path('/secutran/transactionjs1.php'); + + $self->build_subs(qw( + order_number avs_code + )); + # order_type + # md5 cvv2_response cavv_response + +} + +sub submit { + my($self) = @_; + + #$self->map_fields(); + $self->remap_fields( + # => 'order_type', + # => 'transaction_type', + login => 'shreference', + password => 'checkcode', + #authorization => + #customer_ip => + name => 'cardholdersname', + #first_name => + #last_name => + #company => + address => 'cardholderaddr1', + # => 'cardholderaddr2', + city => 'cardholdercity', + state => 'cardholderstate', + zip => 'cardholderpostcode', + #country => + phone => 'cardholdertelephonenumber', + #fax => + email => 'cardholdersemail', + card_number => 'cardnumber', + # => 'cardexpiremonth', + # => 'cardexpireyear', + + 'amount' => 'transactionamount', + #invoice_number => + #customer_id => + #order_number => + + currency => 'transactioncurrency', + + #expiration => + cvv2 => 'cv2', + issue_number => 'switchnumber', + ); + + die "only Normal Authorization is currently supported" + unless $self->{_content}{'action'} =~ /^\s*normal\s*authorization\s*$/i; + + #cardexpiremonth & cardexpireyear + $self->{_content}{'expiration'} =~ /^(\d+)\D+\d*(\d{2})$/ + or croak "unparsable expiration ". $self->{_content}{expiration}; + my( $month, $year ) = ( $1, $2 ); + $month = '0'. $month if $month =~ /^\d$/; + $self->{_content}{cardexpiremonth} = $month; + $self->{_content}{cardexpireyear} = $year; + + #cardstartmonth & cardstartyear + $self->{_content}{'card_start'} =~ /^(\d+)\D+\d*(\d{2})$/ + or croak "unparsable card_start ". $self->{_content}{expiration}; + my( $smonth, $syear ) = ( $1, $2 ); + $smonth = '0'. $smonth if $smonth =~ /^\d$/; + $self->{_content}{cardstartmonth} = $smonth; + $self->{_content}{cardstartyear} = $syear; + + $self->required_fields(qw( + shreference checkcode transactionamount transactioncurrency + cardexpireyear cardexpiremonth cardstartyear cardstartmonth + switchnumber cv2 cardnumber cardholdersname cardholdersemail + )); + + my( $page, $response, @reply_headers) = + $self->https_post( $self->get_fields( $self->fields ) ); + #my( $page, $response, @reply_headers) = + # $self->https_get( $self->get_fields( $self->fields ) ); + + #my %reply_headers = @reply_headers; + #warn join('', map { " $_ => $reply_headers{$_}\n" } keys %reply_headers ) + # if $DEBUG; + + #XXX check $response and die if not 200? + + # avs_code + # is_success + # result_code + # authorization + #md5 cvv2_response cavv_response ...? + + $self->server_response($page); + + my $result = $self->GetXMLProp($page, 'result'); + + if ( defined($result) && $result eq 'success' ) { + $self->is_success(1); + $self->avs_code( $self->GetXMLProp($page, 'cv2asvresult') ); + } elsif ( defined($result) && $result eq 'failed' ) { + $self->is_success(0); + my $error = ''; + my $tranerrdesc = $self->GetXMLProp($page, 'tranerrdesc'); + my $tranerrdetail = $self->GetXMLProp($page, 'tranerrdetail'); + $error = $tranerrdesc if defined $tranerrdesc; + $error .= " - $tranerrdetail" + if defined $tranerrdetail && length $tranerrdetail; + $self->error_message($error); + } else { + die "unparsable response received from gateway". + ( $DEBUG ? ": $page" : '' ); + } + +} + + +sub fields { + my $self = shift; + + qw( + shreference + checkcode + transactionamout + transactioncurrency + cardexpireyear + cardexpiremonth + cardstartyear + cardstartmonth + switchnumber + cv2 + cardnumber + cardholdersname + cardholdersemail + cardholderaddr1 + cardholderaddr2 + cardholdercity + cardholderstate + cardholderpostcode + cardholdertelephonenumber + ); +} + +sub GetXMLProp { + my( $self, $raw, $prop ) = @_; + local $^W=0; + + my $data; + ($data) = $raw =~ m"<$prop>(.*?)"gsi; + #$data =~ s/<.*?>/ /gs; + chomp $data; + return $data; +} + +1; + +__END__ + +=head1 NAME + +Business::OnlinePayment::SecureHostingUPG - SecureHosting UPG backend module for Business::OnlinePayment + +=head1 SYNOPSIS + + use Business::OnlinePayment; + + #### + # One step transaction, the simple case. + #### + + my $tx = new Business::OnlinePayment("SecureHostingUPG"); + $tx->content( + type => 'VISA', + login => 'SecureHosting Reference', + password => 'SecureHosting Checkcode value', + action => 'Normal Authorization', + description => 'Business::OnlinePayment test', + amount => '49.95', + currency => 'GBP', + name => 'Tofu Beast', + address => '123 Anystreet', + city => 'Anywhere', + state => 'UT', + zip => '84058', + phone => '420-867-5309', + email => 'tofu.beast@example.com', + card_number => '4005550000000019', + expiration => '08/06', + card_start => '05/04', + cvv2 => '1234', #optional + issue_number => '5678', + ); + $tx->submit(); + + if($tx->is_success()) { + print "Card processed successfully: ".$tx->authorization."\n"; + } else { + print "Card was rejected: ".$tx->error_message."\n"; + } + +=head1 SUPPORTED TRANSACTION TYPES + +=head2 CC, Visa, MasterCard, American Express, Discover + +Content required: type, login, password, action, amount, first_name, last_name, card_number, expiration. + +=head1 PREREQUISITES + + URI::Escape + Tie::IxHash + + Net::SSLeay _or_ ( Crypt::SSLeay and LWP ) + + The included htmlgood.html and htmlbad.html files must be uploaded to your + Secure Hosting account (Settings | File Manager). + +=head1 DESCRIPTION + +For detailed information see L. + +=head1 NOTE + +Only "Normal Authorization" is supported by the gateway. + +=head1 AUTHOR + +Ivan Kohler + +=head1 SEE ALSO + +perl(1). L. + +=cut + diff --git a/htmlbad.html b/htmlbad.html new file mode 100644 index 0000000..dceb58c --- /dev/null +++ b/htmlbad.html @@ -0,0 +1,5 @@ + + failed + $tranerrdesc + $tranerrdetail + diff --git a/htmlgood.html b/htmlgood.html new file mode 100644 index 0000000..cdcda5f --- /dev/null +++ b/htmlgood.html @@ -0,0 +1,4 @@ + + success + $cv2avsresult + diff --git a/t/bad_card.t b/t/bad_card.t new file mode 100644 index 0000000..da64193 --- /dev/null +++ b/t/bad_card.t @@ -0,0 +1,47 @@ +BEGIN {$| = 1; print "1..1\n"; } + +eval "use Net::SSLeay;"; +if ( $@ ) { + print "ok 1 # Skipped: Net::SSLeay is not installed\n"; exit; +} + +use Business::OnlinePayment; + +my $tx = new Business::OnlinePayment("SecureHostingUPG"); + +#$Business::OnlinePayment::HTTPS::DEBUG = 1; +#$Business::OnlinePayment::HTTPS::DEBUG = 1; +#$Business::OnlinePayment::SecureHostingUPG::DEBUG = 1; +#$Business::OnlinePayment::SecureHostingUPG::DEBUG = 1; + +$tx->content( + type => 'VISA', + login => 'SH207361', #SecureHosting Reference + password => '495376', #SecureHosting Checkcode value + action => 'Normal Authorization', + description => 'Business::OnlinePayment visa test', + amount => '49.95', + currency => 'GBP', + name => 'Tofu Beast', + address => '123 Anystreet', + city => 'Anywhere', + state => 'UT', + zip => '84058', + phone => '420-543-2199', + email => 'tofu.beast@example.com', + card_number => '4005550000000020', + expiration => '08/06', + card_start => '05/04', + cvv2 => '1234', #optional + issue_number => '5678', +); +$tx->test_transaction(1); # test, dont really charge +$tx->submit(); + +if($tx->is_success()) { + print "not ok 1\n"; +} else { + #warn $tx->server_response."\n"; + #warn $tx->error_message. "\n"; + print "ok 1\n"; +} diff --git a/t/bop.t b/t/bop.t new file mode 100644 index 0000000..64332c5 --- /dev/null +++ b/t/bop.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n"; } +END {print "not ok 1\n" unless $loaded;} +use Business::OnlinePayment; +$loaded = 1; +print "ok 1\n"; diff --git a/t/credit_card.t b/t/credit_card.t new file mode 100644 index 0000000..d111585 --- /dev/null +++ b/t/credit_card.t @@ -0,0 +1,49 @@ +BEGIN { $| = 1; print "1..1\n"; } + +eval "use Net::SSLeay;"; +if ( $@ ) { + print "ok 1 # Skipped: Net::SSLeay is not installed\n"; exit; +} + +use Business::OnlinePayment; + +my $tx = new Business::OnlinePayment("SecureHostingUPG"); + +#$Business::OnlinePayment::HTTPS::DEBUG = 1; +#$Business::OnlinePayment::HTTPS::DEBUG = 1; +#$Business::OnlinePayment::SecureHostingUPG::DEBUG = 1; +#$Business::OnlinePayment::SecureHostingUPG::DEBUG = 1; + +$tx->content( + type => 'VISA', + login => 'SH207361', #SecureHosting Reference + password => '495376', #SecureHosting Checkcode value + action => 'Normal Authorization', + description => 'Business::OnlinePayment visa test', + amount => '49.95', + currency => 'GBP', + name => 'Tofu Beast', + address => '123 Anystreet', + city => 'Anywhere', + state => 'UT', + zip => '84058', + phone => '420-543-2199', + email => 'tofu.beast@example.com', + #card_number => '4005550000000019', + card_number => '4242424242424242', + expiration => '01/06', + card_start => '05/04', + cvv2 => '1234', #optional + issue_number => '5678', +); +$tx->test_transaction(1); # test, dont really charge +$tx->submit(); + +if($tx->is_success()) { + print "ok 1\n"; +} else { + #warn $tx->server_response."\n"; + warn $tx->error_message. "\n"; + print "not ok 1\n"; +} + diff --git a/t/crypt_bad_card.t b/t/crypt_bad_card.t new file mode 100644 index 0000000..1f8384b --- /dev/null +++ b/t/crypt_bad_card.t @@ -0,0 +1,47 @@ +BEGIN { + $| = 1; print "1..1\n"; + $Business::OnlinePayment::HTTPS::skip_NetSSLeay=1; + $Business::OnlinePayment::HTTPS::skip_NetSSLeay=1; +} + +eval "use Crypt::SSLeay;"; +if ( $@ ) { + print "ok 1 # Skipped: Crypt::SSLeay is not installed\n"; exit; +} + +use Business::OnlinePayment; + +my $tx = new Business::OnlinePayment("SecureHostingUPG"); + +$tx->content( + type => 'VISA', + login => 'SH207361', #SecureHosting Reference + password => '495376', #SecureHosting Checkcode value + action => 'Normal Authorization', + description => 'Business::OnlinePayment visa test', + amount => '49.95', + currency => 'GBP', + name => 'Tofu Beast', + address => '123 Anystreet', + city => 'Anywhere', + state => 'UT', + zip => '84058', + phone => '420-543-2199', + email => 'tofu.beast@example.com', + card_number => '4005550000000020', + expiration => '08/06', + card_start => '05/04', + cvv2 => '1234', #optional + issue_number => '5678', +); +$tx->test_transaction(1); # test, dont really charge +$tx->submit(); + +if($tx->is_success()) { + print "not ok 1\n"; +} else { + #warn $tx->server_response."\n"; + #warn $tx->error_message. "\n"; + print "ok 1\n"; +} + diff --git a/t/crypt_credit_card.t b/t/crypt_credit_card.t new file mode 100644 index 0000000..8799603 --- /dev/null +++ b/t/crypt_credit_card.t @@ -0,0 +1,46 @@ +BEGIN { + $| = 1; print "1..1\n"; + $Business::OnlinePayment::HTTPS::skip_NetSSLeay=1; + $Business::OnlinePayment::HTTPS::skip_NetSSLeay=1; +} + +eval "use Crypt::SSLeay;"; +if ( $@ ) { + print "ok 1 # Skipped: Crypt::SSLeay is not installed\n"; exit; +} + +use Business::OnlinePayment; + +my $tx = new Business::OnlinePayment("SecureHostingUPG"); +$tx->content( + type => 'VISA', + login => 'SH207361', #SecureHosting Reference + password => '495376', #SecureHosting Checkcode value + action => 'Normal Authorization', + description => 'Business::OnlinePayment visa test', + amount => '49.95', + currency => 'GBP', + name => 'Tofu Beast', + address => '123 Anystreet', + city => 'Anywhere', + state => 'UT', + zip => '84058', + phone => '420-543-2199', + email => 'tofu.beast@example.com', + card_number => '4005550000000019', + expiration => '08/06', + card_start => '05/04', + cvv2 => '1234', #optional + issue_number => '5678', +); +$tx->test_transaction(1); # test, dont really charge +$tx->submit(); + +if($tx->is_success()) { + print "ok 1\n"; +} else { + #warn $tx->server_response."\n"; + warn $tx->error_message. "\n"; + print "not ok 1\n"; +} + diff --git a/t/crypt_load.t b/t/crypt_load.t new file mode 100644 index 0000000..03bca03 --- /dev/null +++ b/t/crypt_load.t @@ -0,0 +1,13 @@ +BEGIN { + $| = 1; print "1..1\n"; + eval "use Crypt::SSLeay;"; + if ( $@ ) { + print "ok 1 # Skipped: Crypt::SSLeay is not installed\n"; exit; + } + $Business::OnlinePayment::HTTPS::skip_NetSSLeay=1; + $Business::OnlinePayment::HTTPS::skip_NetSSLeay=1; +} +END {print "not ok 1\n" unless $loaded;} +use Business::OnlinePayment::SecureHostingUPG; +$loaded = 1; +print "ok 1\n"; diff --git a/t/load.t b/t/load.t new file mode 100644 index 0000000..1d6d6bc --- /dev/null +++ b/t/load.t @@ -0,0 +1,12 @@ +BEGIN { + $| = 1; print "1..1\n"; + eval "use Net::SSLeay;"; + if ( $@ ) { + print "ok 1 # Skipped: Net::SSLeay is not installed\n"; exit; + } + +} +END {print "not ok 1\n" unless $loaded;} +use Business::OnlinePayment::SecureHostingUPG; +$loaded = 1; +print "ok 1\n";