[Date Prev][Date Next][Thread Prev][Thread Next][Interchange by date
][Interchange by thread
]
[ic] Trying to make new Payment Module for Card Services perl wrapper.
Hello,
How do I get interchange payment modules to find and load a perl module in
interchange_location/lib/LPERL/ lperl.pm . What I am doing does not seem
to be working. The test programs all work using lperl in the
interchange_location/lib/LPERL directory.
If I copy lperl.pm to my perl site_perl/5.6.1/ directory, interchange load
just fine, but when I try to place a CC order I get...
(linkpt): Charge failed, reason: payment routine 'linkpt' returned error:
Undefined subroutine &lperl::new called at
/linux/usr/local/interchange.new/lib/Vend/Payment/linkpt.pm line 324.
or
(linkpt): Charge failed, reason: payment routine 'linkpt' returned error:
Can't locate object method "new" via package "lperl" (perhaps you forgot
to load "lperl"?) at
/linux/usr/local/interchange.new/lib/Vend/Payment/linkpt.pm line 317.
The lperl.pm module can not be distributed in any form.
If I do not copy it to my perl site_perl/5.6.1 directory I get
Required Perl module Vend::Payment::linkpt not present. Aborting catalog.
In line 5 of the configuration file 'interchange.cfg':
Require module Vend::Payment::linkpt
So I know that when interchange starts and finds the lperl.pm module
interchange is able to start. So now I need to some how make interchange
use the interchange_directory/lib/LPERL to do everything. I missed
something going through the code and I am not sure exactly what.
Maybe one of you interchange and perl Guru's can quicly spot what I am
doing wrong. Below is linkpt.pm that I put in the lib/Vend/Payment
directory. This is a work in progress so please do not rely on it working
at this time. When I finish this and passes all tests I will glady let
any one with interchange use it and if Red Hat wants to add it to their
Payment modules I think they will be able to use it. Where I am requiring
people to purchase from Card Service the Perl Wrapper and I am not
distributing any part of it.
Thanks for any and all help.
--
Boyd Gerber <gerberb@zenez.com>
ZENEZ 3748 Valley Forge Road, Magna Utah 84044
---------------------------------linkpt.pm--------------------------
# Vend::Payment::linkpt - Interchange linkpt Support
#
# $Id: linkpt.pm,v 2.0 2002/04/13 02:23:16 jon Exp $
#
# Copyright (C) 1999-2001 Red Hat, Inc. <interchange@redhat.com>
#
# LinkPoint CardService using the lperl that must be purchased
# From Card Server.
# by Boyd Gerber <gerberb@zenez.com> inspired and resused by
# based on code by Mike Heins <mheins@redhat.com>
# 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::linkpt;
=head1 Interchange linkpt Support
Vend::Payment::linkpt $Revision: 2.0 $
=head1 SYNOPSIS
&charge=linkpt
or
[charge mode=linkpt param1=value1 param2=value2]
=head1 PREREQUISITES
lperl
lbin
Purchase the perl wrapper from Card Service.
=head1 DESCRIPTION
The Vend::Payment::linkpt module implements the linkpt() routine
for use with Interchange. It is compatible on a call level with the other
Interchange payment modules.
To enable this module, place this directive in C<interchange.cfg>:
Require module Vend::Payment::linkpt
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<linkpt>. 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 linkpt
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=linkpt id=YourStoreName]
or
Route linkpt id YourStoreName
or
Variable MV_PAYMENT_ID YourStoreName
The active settings are:
=over 4
=item id
Your Card Service store Name, supplied by Card Service when you sign up.
Global parameter is MV_PAYMENT_ID.
That should show what happened.
Variable MV_PAYMENT_ID YourStoreNymber
# Use staging.linkpt.new for testing
Variable MV_PAYMENT_SERVER secure.linkpt.net
transactionresult needs to be set to GOOD for testing and LIVE for normal processing.
3. Copy your Card Service Perl software to interchange/lib/LPERL.
4. Copy your Digital certificate .pem file for LinkPoint API client:
to YourStoreNumber.pem in the interchange/lib/LPERL directory.
5. Create a temp directory in your interchange/lib/LPERL directory,
mkdir temp
=item remap
This remaps the form variable names to the ones needed by linkpt. See
the C<Payment Settings> heading in the Interchange documentation for use.
=back
=head2 Troubleshooting
Try the instructions above, then enable test mode. A test order should complete.
Then move to live mode and try a sale with the card number C<4111 1111 1111 1111
>
and a valid expiration date. The sale should be denied, and the reason should
be in [data session payment_error].
If nothing works:
=over 4
=item *
Make sure you "Require"d the module in interchange.cfg:
Require module Vend::Payment::linkpt
=item *
Make sure you have installed your perl wrapper in the your interchange
directory in lib/LPERL. Make sure it is working with the tests provided.
You can test to see whether your Perl can access lbin and lperl. The commands
are:
Edit these programs to reflect your store name and cert and then run perl filename.
lptest_ApproveSale_VoidSale_Track.pl
lptest_ApproveSale_VoidSale_card.pl
lptest_BillOrder.pl
lptest_CalculateShipping.pl
lptest_CalculateTax.pl
lptest_PeriodicBilling.pl
lptest_ReturnCard.pl
lptest_Shipping_Tax_ApproveSale.pl
lptest_VirtualCheck.pl
lptest_minimum.pl
If either one prints "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 account ID 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.
=item *
If all else fails, Red Hat and other consultants are available to help
with integration for a fee.
=back
=head1 BUGS
There is actually nothing *in* Vend::Payment::linkpt. It changes packages
to Vend::Payment and places things there.
=head1 AUTHORS
Boyd Gerber <gerberb@zenez.com>, based on original code by
Mike Heins <mheins@redhat.com> and other from the Payment directory.
=cut
BEGIN {
my $selected;
package Vend::Payment;
eval {
package LPERL::lperl;
require lperl;
import lperl qw($REVISION $VERSION @ISA @EXPORT);
@ISA = qw(Exporter);
@EXPORT = qw(&process &new &add_item &add_option @Items);
$selected = "lperl";
};
$Vend::Payment::Have_LPERL_lperl = 1 unless $@;
unless ($Vend::Payment::Have_LPERL_lperl) {
die __PACKAGE__ . " requires lperl";
}
::logGlobal("%s payment module initialized, using %s", __PACKAGE__, $selected)
unless $Vend::Quiet;
}
package Vend::Payment;
sub linkpt {
use lperl;
#::logDebug("linkpt called");
my $exe;
my @try = split /:/, $ENV{PATH};
unshift @try,
"$Global::VendRoot/lib",
"$Global::VendRoot/bin",
"$Global::VendRoot",
;
my $stdin;
for(@try) {
if(-f "$_/lib/LPERL/lbin" and -x _) {
$exe = "$_/lib/LPERL/lbin";
$stdin = 1;
last;
}
next unless -f "$_/lib/LPERL/lbin" and -x _;
$exe = "$_/lib/LPERL/lbin";
last;
}
if(! $exe ) {
return (
MStatus => 'failure-hard',
MErrMsg => errmsg('lbin executable not found.'),
);
}
# set loadable module path so not needed in /usr/lib
@try = split /:/, (charge_param('library_path') || $ENV{LD_LIBRARY_PATH}
);
unshift @try,
"$Global::VendRoot/lib",
"$Global::VendRoot/bin",
"$Global::VendRoot",
;
$ENV{LD_LIBRARY_PATH} = join ':', @try;
# set certificat path for modern lbin
$ENV{LINKPT_CERT_PATH} ||= charge_param('cert_path');
if(! -d $ENV{LINKPT_CERT_PATH} ) {
@try = (
"$Global::VendRoot",
"$Global::VendRoot/lib",
"$Global::VendRoot/lib/LPERL",
'/usr/local/ssl',
'/usr/lib/ssl',
);
for(@try) {
next unless -d "$_/certs";
$ENV{LINKPT_CERT_PATH} = "$_/certs";
last;
}
}
my %actual;
if($opt->{actual}) {
%actual = %{$opt->{actual}};
}
else {
%actual = map_actual();
}
if(! $user ) {
$user = charge_param('id')
or return (
MStatus => 'failure-hard
',
MErrMsg => errmsg('No ac
count id'),
);
}
#::logDebug("linkpt user $user");
my $server;
my $port;
if(! $opt->{host} and charge_param('test')) {
$server = 'staging.linkpt.net';
$port = 1139;
}
else {
# We won't read from MV_PAYMENT_SERVER because that would rarely
# be right and might often be wrong
# this is normally secure.linkpt.net
$server = $opt->{host} || 'staging.linkpt.net';
$port = $opt->{port} || '1139';
}
my $exe = "$Global::VendRoot/lib/LPERL/lbin";
#my $lperl = new lperl("my$exe", "FILE", "/linux/usr/lib/interchange/lib/LPERL/temp/");
#
# use this just to make sure this is not where it is failing.
#
my $lperl = new lperl("/linux/usr/lib/interchange/lib/LPERL/lbin", "FILE", "/linux/usr/lib/interchange/lib/LPERL/temp/");
#::logDebug("linkpt srcipt $script");
# my $server = $::Variable->{MV_PAYMENT_SERVER} ||
# $::Variable->{CYBER_SERVER} ||
# 'staging.linkpt.net';
# 'secure.linkpt.net';
my $hostname = "$server";
#::logDebug("linkpt server $hostname");
#my $port = "$::Variable->{MV_PAYMENT_PORT}" ||
# "$::Variable->{CYBER_PORT}" ||
# "1139";
#::logDebug("linkpt port $port");
if(! $storename ) {
$storename = "$::Variable->{MV_PAYMENT_ID}" ||
"$::Variable->{CYBER_ID}"
or return undef;
}
#
# use this just to make sure this is not where it is faling.
#
my $storename="800153";
#::logDebug("linkpt store $storename");
#my $keyfile = "$Global::VendRoot/lib/LPERL/800153.pem";
#
# use this just to make sure this is not where it is faling.
#
my $keyfile = "/linux/usr/lib/interchange/lib/LPERL/800153.pem";
# Change to LIVE for normal processing
#
# use this just to make sure this is not where it is faling.
#
my $transactionresult = "GOOD";
my $testip = "127.0.0.1";
my %actual = Vend::Order::map_actual();
my $transaction_hash = {
hostname => $hostname,
port => $port,
storename => $storename,
keyfile => $keyfile,
# if this param is empty or missing
# a CSI order number will be assigned
orderID => "",
amount => Vend::Interpolate::total_cost(),
result => $transactionresult,
cardNumber => $actual{mv_credit_card_number},
cardExpMonth => $actual{mv_credit_card_exp_month},
cardExpYear => $actual{mv_credit_card_exp_year},
name => "$actual{fname} $actual{lname}",
email => $actual{email},
phone => $actual{phone_day},
address => $actual{address},
city => $actual{city},
state => $actual{state},
zip => $actual{zip},
country => $actual{country},
ip => $testip,
};
my %ret = $lperl->CapturePayment($transaction_hash);
# ---------------------------------------------
# capture the order ID so we can bill the order
# ---------------------------------------------
my $neworderID = $ret{'neworderID'};
my %result;
#::logDebug("linkpt CapturePayment: statusCode $statusCode");
if ( $ret{'statusCode'} eq 0 ) {
# the transaction failed. print the reason.
$result{MStatus} = 'failure';
$result{MErrMsg} = "$ret{'statusMessage'} ";
#::logDebug("linkpt failure:");
#::logDebug("linkpt CapturePayment: statusMessage $statusCode");
#::logDebug("linkpt ChargeTotal: $actual{'total-cost'}");
#::logDebug(qq{linkpt decline=$statusCode result: } . ::uneval( \%result));
}
else
{
# the transaction succeeded. print the results.
#::logDebug("linkpt CapturePayment: statusMessage:'AVSCode'");
# ------------------
# now bill the order
# ------------------
$transaction_hash = {
hostname => $hostname,
port => $port,
storename => $storename,
keyfile => $keyfile,
result => $transactionresult,
orders => ([
# multiple entries could be used for more orders
{orderID => $neworderID,
amount => $actual{'total-cost'},
backOrdered => '0',
}
])
};
%ret = $lperl->BillOrders($transaction_hash);
#::logDebug("linkpt Successfully billed $ret of 1 order\n");
#::logDebug("Order statusMessage: $transaction_hash->{'orders'}[0]->{'statusMessage'}\n";
$result{MStatus} = 'success';
$result{'order-id'} = $neworderID;
}
return %result;
}
package Vend::Payment::linkpt;
1;
-----------------------------------end_file--------------------------