From e68e78321174f709f909f3bad181191dd3f3e8db Mon Sep 17 00:00:00 2001 From: ivan Date: Tue, 11 Jan 2005 07:10:23 +0000 Subject: [PATCH 1/1] initial checkin --- Changes | 2 + MANIFEST | 14 +++ Makefile.PL | 23 +++++ README | 13 +++ SecureHostingUPG.pm | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++ htmlbad.html | 5 + htmlgood.html | 4 + t/bad_card.t | 47 ++++++++++ t/bop.t | 5 + t/credit_card.t | 49 ++++++++++ t/crypt_bad_card.t | 47 ++++++++++ t/crypt_credit_card.t | 46 ++++++++++ t/crypt_load.t | 13 +++ t/load.t | 12 +++ 14 files changed, 530 insertions(+) create mode 100644 Changes create mode 100644 MANIFEST create mode 100644 Makefile.PL create mode 100644 README create mode 100644 SecureHostingUPG.pm create mode 100644 htmlbad.html create mode 100644 htmlgood.html create mode 100644 t/bad_card.t create mode 100644 t/bop.t create mode 100644 t/credit_card.t create mode 100644 t/crypt_bad_card.t create mode 100644 t/crypt_credit_card.t create mode 100644 t/crypt_load.t create mode 100644 t/load.t 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"; -- 2.11.0