[interchange-cvs] interchange - racke modified 2 files

interchange-cvs at icdevgroup.org interchange-cvs at icdevgroup.org
Sat Nov 22 18:32:01 EST 2003


User:      racke
Date:      2003-11-22 23:32:01 GMT
Modified:  .        WHATSNEW
Added:     lib/Vend/Payment Linkpoint.pm
Log:
Add Linkpoint payment module.

Revision  Changes    Path
2.163     +5 -0      interchange/WHATSNEW


rev 2.163, prev_rev 2.162
Index: WHATSNEW
===================================================================
RCS file: /var/cvs/interchange/WHATSNEW,v
retrieving revision 2.162
retrieving revision 2.163
diff -u -r2.162 -r2.163
--- WHATSNEW	22 Nov 2003 14:53:35 -0000	2.162
+++ WHATSNEW	22 Nov 2003 23:32:01 -0000	2.163
@@ -50,6 +50,11 @@
 
 * Change Newfoundland from NF to NL in "state" table.
 
+Payment
+-------
+
+* Add Linkpoint payment module.
+
 
 ------------------------------------------------------------------------------
 



1.1                  interchange/lib/Vend/Payment/Linkpoint.pm


rev 1.1, prev_rev 1.0
Index: Linkpoint.pm
===================================================================
# Vend::Payment::Linkpoint - Interchange Linkpoint support
#
# $Id: Linkpoint.pm,v 1.1 2003/11/22 23:32:01 racke Exp $
#
# Copyright (C) 2002 Stefan Hornburg (Racke) <racke at linuxia.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA  02111-1307  USA.

package Vend::Payment::Linkpoint;

=head1 NAME

Vend::Payment::Linkpoint - Interchange Linkpoint Support

=head1 SYNOPSIS

    &charge=linkpoint
 
        or
 
    [charge mode=linkpoint param1=value1 param2=value2]

=head1 PREREQUISITES

    LPERL

=head1 DESCRIPTION

The Vend::Payment::Linkpoint module implements the linkpoint() routine
for use with Interchange. It is compatible on a call level with the other
Interchange payment modules -- in theory (and even usually in practice) you
could switch from CyberCash to Linkpoint with a few configuration 
file changes.

To enable this module, place this directive in C<interchange.cfg>:

    Require module Vend::Payment::Linkpoint

This I<must> be in interchange.cfg or a file included from it.

Make sure CreditCardAuto is off (default in Interchange demos).

The mode can be named anything, but the C<gateway> parameter must be set
to C<linkpoint>. To make it the default payment gateway for all credit
card transactions in a specific catalog, you can set in C<catalog.cfg>:

    Variable MV_PAYMENT_MODE linkpoint

It uses several of the standard settings from Interchange payment. Any time
we speak of a setting, it is obtained either first from the tag/call options,
then from an Interchange order Route named for the mode, then finally a
default global payment variable, For example, the C<id> parameter would
be specified by:

    [charge mode=linkpoint id=YourLinkpointID]

or

    Route linkpoint id YourLinkpointID

or 

    Variable LINKPOINT_ID YourLinkpointID

Required settings are C<host>, C<keyfile> and C<bin>.

The active settings are:

=over 4

=item host

Your LinkPoint Secure Payment Gateway (LSPG) hostname. Usually secure.linkpt.net (production) or staging.linkpt.net (testing).

=item keyfile

File name of the merchant security certificate. This file should contain the
RSA private key and the certificate, otherwise you get an error like
"Unable to open/parse client certificate file."

=item bin

File name of the LinkPoint binary. You get an "Unknown error" if you
specify another executable.

=item id

Store number assigned to your merchant account.

=item transaction

The type of transaction to be run. Valid values are:

    Interchange         Linkpoint
    ----------------    -----------------
        auth            preauth
        sale            sale

Default is C<sale>.

=back

=head2 Troubleshooting

If nothing works:

=over 4

=item *

Make sure you "Require"d the module in interchange.cfg:

    Require module Vend::Payment::Linkpoint

=item *

Make sure LPERL is installed and working. You can test to see
whether your Perl thinks they are:

    perl -MLPERL -e 'print "It works.\n"'

If it "It works." and returns to the prompt you should be OK (presuming
they are in working order otherwise).

=item *

Check the error logs, both catalog and global.

=item *

Make sure you set your payment parameters properly.  

=item *

Try an order, then put this code in a page:

    <XMP>
    [calc]
        my $string = $Tag->uneval( { ref => $Session->{payment_result} });
        $string =~ s/{/{\n/;
        $string =~ s/,/,\n/g;
        return $string;
    [/calc]
    </XMP>

That should show what happened.

=back

=head1 BUGS

There is actually nothing *in* Vend::Payment::Linkpoint. It changes
packages to Vend::Payment and places things there.

=head1 AUTHOR

Stefan Hornburg (Racke) <racke at linuxia.de>

=cut
						
BEGIN {
	eval {
		package Vend::Payment;
        	require LPERL or die __PACKAGE__ . " requires LPERL";
	};

	if ($@) {
		$msg = __PACKAGE__ . ' requires LPERL';
		::logGlobal ($msg);
		die $msg;
	}
	
	::logGlobal("%s payment module initialized", __PACKAGE__)
		unless $Vend::Quiet;
}

package Vend::Payment;

sub linkpoint {
	my ($user, $amount) = @_;

	my $opt;
	my $keyfile;
	
	if(ref $user) {
		$opt = $user;
		$user = $opt->{id} || undef;
		$keyfile = $opt->{keyfile} || undef;
		$bin = $opt->{bin} || undef;
	}
	else {
		$opt = {};
	}
	
	my $actual;
	if($opt->{actual}) {
		$actual = $opt->{actual};
	}
	else {
		my (%actual) = map_actual();
		$actual = \%actual;
	}

#::logDebug("actual map result: " . ::uneval($actual));

	# we need to check for customer id, keyfile and binary
	# location, as these are the required parameters
	
	if (! $user ) {
		$user = charge_param('id')
			or return (
					   MStatus => 'failure-hard',
					   MErrMsg => errmsg('No customer id'),
					  );
	}

	if (! $keyfile ) {
		$keyfile = charge_param('keyfile')
			or return (
					   MStatus => 'failure-hard',
					   MErrMsg => errmsg('No certificate file'),
					  );
	}

	if (! $bin ) {
		$bin = charge_param('bin')
			or return (
					   MStatus => 'failure-hard',
					   MErrMsg => errmsg('No LinkPoint binary'),
					  );
	}

	unless (-x $bin) {
		return (
				MStatus => 'failure-hard',
				MErrMsg => errmsg('LinkPoint binary not executable'),
			   );
	
	}
	
	unless ($opt->{host}) {
		$opt->{host} = charge_param('host') || 'secure.linkpt.net';
	}
	
	my $precision = $opt->{precision} || 2;

	my $referer   =  $opt->{referer}
					|| charge_param('referer');

	$actual->{mv_credit_card_exp_month} =~ s/\D//g;
	$actual->{mv_credit_card_exp_year} =~ s/\D//g;
	$actual->{mv_credit_card_exp_year} =~ s/\d\d(\d\d)/$1/;
	$actual->{mv_credit_card_number} =~ s/\D//g;
	$actual->{b_zip} =~ s/\D//g;

	my $exp = sprintf '%02d%02d', $actual->{mv_credit_card_exp_month},
		$actual->{mv_credit_card_exp_year};

	my $transtype = $opt->{transaction} || charge_param('transaction') || 'sale';

	my %type_map = (
		auth		 	=>	'preauth',
		authorize		=>	'preauth',
		mauthcapture 	=>	'sale',
		mauthonly		=>	'preauth',
		sale	 		=>	'sale',
	);
	
	if (defined $type_map{$transtype}) {
		$transtype = $type_map{$transtype};
	}

	$amount = $opt->{total_cost} unless $amount;
	
	if(! $amount) {
		$amount = Vend::Interpolate::total_cost();
		$amount = Vend::Util::round_to_frac_digits($amount,$precision);
	}
    $amount =~ s/\D//g;

	$amount = int ($amount / 100) . '.' . ($amount % 100);
	$shipping = Vend::Interpolate::tag_shipping();
	$subtotal = Vend::Interpolate::subtotal();
	$salestax = Vend::Interpolate::salestax();
	$order_id = gen_order_id($opt);
	
	my %varmap = ( qw /
				   baddr1 b_address1
				   baddr2 b_address2
				   bcity b_city
				   bcountry b_country
				   bname b_name
				   bstate b_state
				   bzip b_zip
				   email email
				   phone phone_day
				   saddr1 address1
				   saddr2 address2
				   scity city
				   scountry country
				   sname name
				   sstate state
				   szip zip
				   / );

	my %query =
		(hostname => $opt->{host},
		 port => '1139',
		 storename => $user,
		 keyfile => $keyfile,		 
		 shipping => $shipping,
		 chargetotal => $amount,
		 subtotal => $subtotal,
		 tax => $salestax,
		 cardnumber	=> $actual->{mv_credit_card_number},
		 expmonth => sprintf ("%02d", $actual->{mv_credit_card_exp_month}),
		 expyear => sprintf ("%02d", $actual->{mv_credit_card_exp_year}),
		 bcompany => $Values->{company},
		 scompany => $Values->{company},
		 debuglevel => $opt->{debuglevel},
		);

	for (keys %varmap) {
        $query{$_} = $actual->{$varmap{$_}};
    }
	
    # delete query keys with undefined values
	for (keys %query) {
        	delete $query{$_} unless $query{$_};
	}

#::logDebug("linkpoint query: " . ::uneval(\%query));

    my $tempfile = "$Vend::Cfg->{ScratchDir}/linkpoint.$order_id";
	my $lperl = new LPERL($bin, "FILE", $tempfile);

	my %result;

	if ($transtype eq 'preauth') {
		%result = $lperl -> CapturePayment (\%query);
	} elsif ($transtype eq 'sale') {
		%result = $lperl->ApproveSale(\%query);
	} else {
		return (
				MStatus => 'failure-hard',
				MErrMsg => errmsg('Unrecognized transaction: %s', $transtype),
			   );
	}
	
	# Interchange names are on the left, Linkpoint on the right
	my %result_map = ( qw/
					   order-id       neworderID
					   pop.order-id   neworderID
					   pop.auth-code  code
					   pop.avs_code   AVSCode
	/
	);

#::logDebug("linkpoint response: " . ::uneval(\%result));

	for (keys %result_map) {
		$result{$_} = $result{$result_map{$_}}
			if defined $result{$result_map{$_}};
	}

	if ($result{statusCode}) {
		$result{MStatus} = 'success';
	}
	else {
		$result{MStatus} = 'failure';
	   	$result{MErrMsg} = $result{statusMessage} || 'Unknown error';
	}

#::logDebug("result given to interchange " . ::uneval(\%result));

	return (%result);
}

package Vend::Payment::Linkpoint;

1;








More information about the interchange-cvs mailing list