[interchange-cvs] interchange - heins modified lib/Vend/Payment.pm

interchange-cvs at icdevgroup.org interchange-cvs at icdevgroup.org
Tue May 3 13:41:42 EDT 2005


User:      heins
Date:      2005-05-03 17:41:42 GMT
Modified:  lib/Vend Payment.pm
Log:
* We are having frequent problems with terminated output with
  Authorizenet and other payment modules using LWP. Symptom is
  a 500 server error from AuthorizeNet, which should be their
  problem, but they claim this is not happening and payment
  is actually being maded despite 500 response from LWP.

* Add "use_wget" option to Vend::Payment routine post_data(). This
  allows use of the ubiquitous GNU wget program to send the transaction.

* Slight security risk in that the credit card is put in a file for
  posting -- there is no way for wget to use STDIN or a pipe, as
  it doesn't accept a content-length setting. Storing in a file
  or passing on command line, take your pick for security problems.

  We unlink the file except when in debug mode, so should be fairly
  secure.

* To implement, just add in catalog.cfg:

	Route authorizenet use_wget 1

  If your wget is not in the standard PATH, put its location there:

	Route authorizenet use_wget /usr/local/bin/wget

* Tested with at least AuthorizeNet. Should work with any.

* Obviously requires wget be linked against an SSL library, which is
  standard for modern Linux.

* Developed with and tested against wget 1.9 on Fedora, but with the
  stability of GNU programs will probably work with others.

Revision  Changes    Path
2.15      +72 -5     interchange/lib/Vend/Payment.pm


rev 2.15, prev_rev 2.14
Index: Payment.pm
===================================================================
RCS file: /var/cvs/interchange/lib/Vend/Payment.pm,v
retrieving revision 2.14
retrieving revision 2.15
diff -u -r2.14 -r2.15
--- Payment.pm	27 Apr 2004 19:25:14 -0000	2.14
+++ Payment.pm	3 May 2005 17:41:42 -0000	2.15
@@ -1,6 +1,6 @@
 # Vend::Payment - Interchange payment processing routines
 #
-# $Id: Payment.pm,v 2.14 2004/04/27 19:25:14 mheins Exp $
+# $Id: Payment.pm,v 2.15 2005/05/03 17:41:42 mheins Exp $
 #
 # Copyright (C) 2002-2003 Interchange Development Group
 # Copyright (C) 1996-2002 Red Hat, Inc.
@@ -23,7 +23,7 @@
 package Vend::Payment;
 require Exporter;
 
-$VERSION = substr(q$Revision: 2.14 $, 10);
+$VERSION = substr(q$Revision: 2.15 $, 10);
 
 @ISA = qw(Exporter);
 
@@ -572,7 +572,7 @@
 sub post_data {
 	my ($opt, $query) = @_;
 
-	unless ($Have_Net_SSLeay or $Have_LWP) {
+	unless ($opt->{use_wget} or $Have_Net_SSLeay or $Have_LWP) {
 		die "No Net::SSLeay or Crypt::SSLeay found.\n";
 	}
 
@@ -608,7 +608,74 @@
 	}
 
 	my %result;
-	if($Have_Net_SSLeay) {
+	if($opt->{use_wget}) {
+		## Don't worry about OS independence with UNIX wget
+		my $bdir = "$Vend::Cfg->{ScratchDir}/wget";
+		my $filebase = "$Vend::SessionID.wget";
+		my $statfile = Vend::File::get_filename("$filebase.stat", 1, 1, $bdir);
+		my $outfile  = Vend::File::get_filename("$filebase.out", 1, 1, $bdir);
+		my $infile   = Vend::File::get_filename("$filebase.in", 1, 1, $bdir);
+		my $cmd = $opt->{use_wget} =~ m{/} ? $opt->{use_wget} : 'wget';
+
+		my @post;
+		while( my ($k,$v) = each %$query ) {
+			$k = hexify($k);
+			$v = hexify($v);
+			push @post, "$k=$v";
+		}
+		my $post = join "&", @post;
+		open WIN, "> $infile"
+			or die errmsg("Cannot create wget post input file %s: %s", $infile, $!) . "\n";
+		print WIN $post;
+		close WIN
+			or die errmsg("Cannot close wget post input file %s: %s", $infile, $!) . "\n";
+		local($/);
+
+		my @args = $cmd;
+		push @args, "--output-file=$statfile";
+		push @args, "--output-document=$outfile";
+		push @args, "--server-response";
+		push @args, "--post-file=$infile";
+		push @args, $submit_url;
+		system @args;
+#::logDebug("wget cmd line: " . join(" ", @args));
+		if($?) {
+			$result{reply_os_error} = $!;
+			$result{reply_os_status} = $?;
+			$result{result_page} = 'FAILED';
+		}
+		else {
+#::logDebug("wget finished.");
+			open WOUT, "< $outfile"
+				or die errmsg("Cannot read wget output from %s: %s", $outfile, $!) . "\n";
+			$result{result_page} = <WOUT>;
+			close WOUT
+				or die errmsg("Cannot close wget output %s: %s", $outfile, $!) . "\n";
+			unlink $outfile unless $opt->{debug};
+		}
+		unlink $infile unless $opt->{debug};
+		open WSTAT, "< $statfile"
+			or die errmsg("Cannot read wget status from %s: %s", $statfile, $!) . "\n";
+		my $err = <WSTAT>;
+		close WSTAT
+			or die errmsg("Cannot close wget status %s: %s", $statfile, $!) . "\n";
+
+		unlink $statfile unless $opt->{debug};
+		$result{wget_output} = $err;
+		$err =~ s/.*HTTP\s+request\s+sent,\s+awaiting\s+response[.\s]*//s;
+		my @raw = split /\r?\n/, $err;
+		my @head;
+		for(@raw) {
+			s/^\s*\d+\s*//
+				or last;
+			push @head, $_;
+		}
+		$result{status_line} = shift @head;
+		$result{status_line} =~ /^HTTP\S+\s+(\d+)/
+			and $result{response_code} = $1;
+		$result{header_string} = join "\n", @head;
+	}
+	elsif($opt->{use_net_ssleay} or ! $opt->{use_crypt_ssl} && $Have_Net_SSLeay) {
 #::logDebug("placing Net::SSLeay request: host=$server, port=$port, script=$script");
 #::logDebug("values: " . ::uneval($query) );
 		my ($page, $response, %reply_headers)
@@ -643,7 +710,7 @@
 #::logDebug("received LWP header: $header_string");
 		$result{result_page} = $resp->content();
 	}
-#::logDebug("returning thing: " . ::uneval_it(\%result) );
+#::logDebug("returning thing: " . ::uneval(\%result) );
 	return \%result;
 }
 








More information about the interchange-cvs mailing list