From 571a80a1110fe12a52eb9295bc91567413336ee3 Mon Sep 17 00:00:00 2001 From: ivan Date: Tue, 10 May 2005 10:16:53 +0000 Subject: [PATCH 1/1] initial import --- Changes | 2 + MANIFEST | 13 +++ Makefile.PL | 24 ++++++ PXPost.pm | 220 ++++++++++++++++++++++++++++++++++++++++++++++++++ README | 14 ++++ t/bad_card.t | 36 +++++++++ t/bop.t | 5 ++ t/credit_card.t | 37 +++++++++ t/crypt_bad_card.t | 36 +++++++++ t/crypt_credit_card.t | 35 ++++++++ t/crypt_load.t | 13 +++ t/load.t | 12 +++ 12 files changed, 447 insertions(+) create mode 100644 Changes create mode 100644 MANIFEST create mode 100644 Makefile.PL create mode 100644 PXPost.pm create mode 100644 README 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..9e8d640 --- /dev/null +++ b/Changes @@ -0,0 +1,2 @@ +0.01 Tue May 10 00:43:32 PDT 2005 + - original version; created by ivan 1.0 diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..ea85d25 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,13 @@ +Changes +MANIFEST +Makefile.PL +PXPost.pm +README +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..5fae476 --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,24 @@ +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::PXPost', + 'VERSION_FROM' => 'PXPost.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/PXPost.pm b/PXPost.pm new file mode 100644 index 0000000..8bcae96 --- /dev/null +++ b/PXPost.pm @@ -0,0 +1,220 @@ +package Business::OnlinePayment::PXPost; + +use strict; +use Carp; +use Tie::IxHash; +use Business::OnlinePayment 3; +use Business::OnlinePayment::HTTPS 0.03; +use vars qw($VERSION $DEBUG @ISA); + +@ISA = qw(Business::OnlinePayment::HTTPS); +$VERSION = '0.01'; +$DEBUG = 0; + +sub set_defaults { + my $self = shift; + + $self->server('www.paymentexpress.com'); + $self->port('443'); + $self->path('/pxpost.asp'); + + $self->build_subs(qw( order_number )); + #avs_code order_type md5 cvv2_response cavv_response +} + +sub submit { + my($self) = @_; + + $self->remap_fields( + 'login' => 'PostUsername', + 'password' => 'PostPassword', + 'name' => 'CardHolderName', + 'card_number' => 'CardNumber', + #'expiration' => 'DateExpiry', + 'amount' => 'Amount', + 'cvv2' => 'Cvc2', + 'action' => 'TxnType', + 'currency' => 'InputCurrency', + #'' => 'TxnId', + #'' => 'MerchantReference', + #'' => 'TxnData1', + #'' => 'TxnData2', + #'' => 'TxnData3', + #'' => 'DpsTxnRef', #XXX + #'' => 'DpsBillingId', + #'' => 'BillingId', + #'' => 'EnableAddBillCard', + ); + + my $action = $self->{_content}{'TxnType'}; + if ( $action =~ /^\s*normal\s*authorization\s*$/i ) { + $action = 'Purchase'; + } elsif ( $action =~ /^\s*authorization\s*only\s*$/i ) { + $action = 'Auth'; + } elsif ( $action =~ /^\s*post\s*authorization\s*$/i ) { + $action = 'Complete'; + } elsif ( $action =~ /^\s*void\s*$/i ) { + die "DPS PXPost does not support void transactions\n"; + } elsif ( $action =~ /^\s*credit\s*$/i ) { + $action = 'Refund'; + } + $self->{_content}{'TxnType'} = $action; + + if ( $action =~ /^(Purchase|Auth)$/ ) { +# + $self->required_fields( + qw( login password name card_number expiration amount ) + ); + + #exp + $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}{'DateExpiry'} = $month.$year; + + } elsif ( $action eq 'Complete' || $action eq 'Refund' ) { + + $self->required_fields( + qw( login password name order_number amount ) + ); + + } + + + tie my %fields, 'Tie::IxHash', $self->get_fields( $self->fields ); + my $post_data = join("\n", + '', + ( map "<$_>$fields{$_}", keys %fields ), + '', + ). "\n"; + + warn $post_data if $DEBUG > 1; + + my( $page, $response, @reply_headers ) = $self->https_post( $post_data ); + + $self->server_response($page); + + my $result = $self->GetXMLProp($page, 'Authorized'); + + if ( $result =~ /^\s*1\s*$/ ) { + $self->is_success(1); + $self->result_code( $self->GetXMLProp( $page, 'ReCo' ) ); + $self->authorization( $self->GetXMLProp( $page, 'AuthCode' ) ); + $self->order_number( $self->GetXMLProp( $page, 'DpsTxnRef' ) ); + } elsif ( $result =~ /^\s*0\s*$/ ) { + $self->is_success(0); + $self->result_code( $self->GetXMLProp( $page, 'ReCo' ) ); + $self->error_message( $self->GetXMLProp( $page, 'ResponseText' ). ': '. + $self->GetXMLProp( $page, 'HelpText' ) + ); + } else { + die "unparsable response received from gateway (response $result)". + ( $DEBUG ? ": $page" : '' ); + } + +} + +sub fields { + my $self = shift; + + #order is important to this processor + qw( + PostUsername + PostPassword + CardHolderName + CardNumber + DateExpiry + Amount + Cvc2 + TxnType + InputCurrency + TxnId + MerchantReference + TxnData1 + TxnData2 + TxnData3 + DpsTxnRef + DpsBillingId + BillingId + EnableAddBillCard + ); +} + +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::PXPost - Direct Payment Solutions PX Post backend module for Business::OnlinePayment + +=head1 SYNOPSIS + + use Business::OnlinePayment; + + #### + # One step transaction, the simple case. + #### + + my $tx = new Business::OnlinePayment("PXPost"); + $tx->content( + type => 'VISA', + login => 'PXPost Username', + password => 'PXPost Password', + action => 'Normal Authorization', + #description => 'Business::OnlinePayment test', + amount => '49.95', + name => 'Tofu Beast', + card_number => '4005550000000019', + expiration => '08/06', + cvv2 => '1234', #optional + ); + $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, card_number, expiration, name. + +=head1 PREREQUISITES + + URI::Escape + Tie::IxHash + + Net::SSLeay _or_ ( Crypt::SSLeay and LWP ) + +=head1 DESCRIPTION + +For detailed information see L. + +=head1 NOTE + +=head1 AUTHOR + +Ivan Kohler + +=head1 SEE ALSO + +perl(1). L. + +=cut + diff --git a/README b/README new file mode 100644 index 0000000..39a70ce --- /dev/null +++ b/README @@ -0,0 +1,14 @@ +Copyright (c) 2005 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::PXPost, an Business::OnlinePayment +backend module for the Direct Payment Solutions Payment Express gateway. It is +only useful if you have a merchant account with DPS and are activated on the +"PX Post" product: http://www.paymentexpress.com/default.asp?id=p_pxpost + +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/t/bad_card.t b/t/bad_card.t new file mode 100644 index 0000000..92e3462 --- /dev/null +++ b/t/bad_card.t @@ -0,0 +1,36 @@ +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("PXPost"); + +#$Business::OnlinePayment::HTTPS::DEBUG = 1; +#$Business::OnlinePayment::HTTPS::DEBUG = 1; +#$Business::OnlinePayment::PXPost::DEBUG = 1; +#$Business::OnlinePayment::PXPost::DEBUG = 1; + +$tx->content( + type => 'VISA', + login => 'Unicalldev', + password => 'ds4gj7', + action => 'Normal Authorization', + name => 'Tofu Beast', + amount => '32.32', + card_number => '4242424242424243', + expiration => '08/06', +); +$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..305125c --- /dev/null +++ b/t/credit_card.t @@ -0,0 +1,37 @@ +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("PXPost"); + +#$Business::OnlinePayment::HTTPS::DEBUG = 1; +#$Business::OnlinePayment::HTTPS::DEBUG = 1; +#$Business::OnlinePayment::PXPost::DEBUG = 1; +#$Business::OnlinePayment::PXPost::DEBUG = 1; + +$tx->content( + type => 'VISA', + login => 'Unicalldev', + password => 'ds4gj7', + action => 'Normal Authorization', + name => 'Tofu Beast', + amount => '54.01', + card_number => '4111111111111111', + expiration => '01/06', +); +$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..1105f23 --- /dev/null +++ b/t/crypt_bad_card.t @@ -0,0 +1,36 @@ +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("PXPost"); + +$tx->content( + type => 'VISA', + login => 'Unicalldev', + password => 'ds4gj7', + action => 'Normal Authorization', + name => 'Tofu Beast', + amount => '32.32', + card_number => '4242424242424243', + expiration => '08/06', +); +$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..39a8c00 --- /dev/null +++ b/t/crypt_credit_card.t @@ -0,0 +1,35 @@ +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("PXPost"); +$tx->content( + type => 'VISA', + login => 'Unicalldev', + password => 'ds4gj7', + action => 'Normal Authorization', + name => 'Tofu Beast', + amount => '54.01', + card_number => '4111111111111111', + expiration => '08/06', +); +$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..0433f92 --- /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::PXPost; +$loaded = 1; +print "ok 1\n"; diff --git a/t/load.t b/t/load.t new file mode 100644 index 0000000..3116820 --- /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::PXPost; +$loaded = 1; +print "ok 1\n"; -- 2.11.0