[ic] help me hack out a custom GlobalSub for LinkPoint/CSI!

josh simpson naugahyde@earthlink.net
Wed, 11 Oct 2000 22:24:08 -0400


Hey all,

    I have been struggling mightily, with my underinformed,
blunt-instrument-style hacking methods, to coerce Interchange into
working with
CSI/LinkPoint creditcard processing.  We purchased their perl-wrapper
(consisting
of a perl module LPERL.pm, a binary, and an example script for
integrating into a
shoppingcart-type system), and I have spent a few sleep-deprived days
bludgeoning
this into some semblance of functionality.  "Some semblance" being the
operative
phrase, as there are a number of loose ends that, as we now know, could
turn out
to be very nasty means of unravelling the whole shebang.

     But I do have the hard-won satisifaction of knowing that I am
successfully
communicating with the CSI gateway, and that if all relevant + valid
field values
are passed, the gateway does indeed return APPROVED for the transaction
and
additionally sends back new key-values for AVSCode, orderID, etc.

     I suppose most of my questions at this point have to do with 1)
having
Interchange acknowledge and/or do something useful with the info
returned by the
CSI gateway, and, relatedly, 2) finessing Interchange into completing
the 'normal'
order process after completing my custom &charge GlobalSub.  Currently,
after
submitting an order which is successfully recieved & responded to by the
CSI
Gateway, the user is merely taken to the 'login' page, and if they
return to
checkout, it shows their Cart w/ the same items they just ordered, with
an error
message about missing information (the old "errors flagged in red", with
no visible
red items scenario).

     OK, time for a bit more detail: here's my GlobalSub, as defined in
minivend.cfg -
--------------------------------------------------
GlobalSub <<EOF
sub linkpt_charge {
package LPERL;
#use strict;
no strict;
use LPERL;
#use LPERL 'CapturePayment';
$lperl = new LPERL("/home/interchange/mvend/csi/lbin",
"$LPERL::EASYFUNCS");
my $hostname           = "secure.linkpt.net";
my $port               = "1139";
my $storename          = "453807";
my $keyfile            = "/home/interchange/mvend/csi/453807.pem";
my $transactionresult  = "GOOD";
my $testip   = "127.0.0.1";

$transaction_hash = {
     hostname        => $hostname,
     port            => $port,
     storename       => $storename,
     keyfile         => $keyfile,
     orderID         => '',
     result          => $transactionresult,
     cardNumber      => $_[0],
     cardExpMonth    => $_[1],
     cardExpYear     => $_[2],
     name            => $_[3],
     email           => $_[4],
     phone           => $_[5],
     address         => $_[6],
     city            => $_[7],
     state           => $_[8],
     zip             => $_[9],
     country         => $_[10],
     tax             => $_[11],
     shipping        => $_[12],
     subtotal        => $_[13],
     amount          => $_[14],
     saddr1          => $_[15],
     scity           => $_[16],
     sstate          => $_[17],
     szip            => $_[18],
     scountry        => $_[19],
     ip              => $testip,
 };

%ret = $lperl->CapturePayment($transaction_hash);
$neworderID = $ret{'neworderID'};
$statusCode = $ret{'statusCode'};
my %result;
if ($statusCode == 1) {
$result{MStatus} = 'success';
}
elsif ($statusCode == 0) {
$result{MStatus} = $statusMessage;
}
$result{order-id} = $neworderID;
::logDebug("CapturePayment: statusCode: $ret{'statusCode'}\n");
::logDebug("CapturePayment: statusMessage: $ret{'statusMessage'}\n");
::logDebug("CapturePayment: AVSCode: $ret{'AVSCode'}\n");
::logDebug("CapturePayment: trackingID: $ret{'trackingID'}\n");
::logDebug("CapturePayment: neworderID: $ret{'neworderID'}\n");
::logDebug("CapturePayment: statusApproval: $ret{'statusApproval'}\n");
::logDebug("CapturePayment: subtotal: $ret{'subtotal'}\n");
::logDebug("CapturePayment: tax: $ret{'tax'}\n");
::logDebug("CapturePayment: time: $ret{'time'}\n");
::logDebug("is the scalar neworderID intialized yet?\n $neworderID\n
how about statusCode?\n $statusCode\n");
#my %result = (
#  MStatus  => $mstatus,
#  order-id => $neworderID,
#  );
return %result;
}
EOF
----------------------------------------------------------

    And this is how I call it, inside the main order profile :

----------------------------------------------------------
[elsif variable MV_PAYMENT_MODE]
# &credit_card=standard keep __CREDIT_CARDS_ACCEPTED__
&charge=custom linkpt_charge '[value credit_card_number]' '[value
mv_credit_card_exp_month]'
'[value mv_credit_card_exp_year]' '[value fname] [value lname]' '[value
email]' '[value phone_day]'
'[value address1] [value address2]' '[value city]' '[value state]'
'[value zip]' '[value country]'
'[salestax noformat=1]' '[shipping noformat=1]' '[subtotal noformat=1]'
'[total-cost noformat=1]'
'[value b_address1] [value b_address2]' '[value b_city]' '[value
b_state]' '[value b_zip]' '[value b_country]'
&set=mv_payment Real-time ([var MV_PAYMENT_MODE]) Credit Card
&success=successful
[/elsif]
----------------------------------------------------

    In catalog.cfg, I have "Variable  MV_PAYMENT_MODE linkpt_charge", in
addition to
"Variable CreditCardAuto No", and the following 'default' subroutines :
-----------------------------------------------------
ActionMap  order   <<EOR
sub {
 #Log('in order action');
 if($CGI->{mv_nextpage} ne 'order') {
  # Do nothing
 }
 elsif($Values->{no_basket}) {
  $CGI->{mv_nextpage} = 'ord/nobasket';
 }
 else {
  $CGI->{mv_nextpage} = '__ORDER_STYLE__/basket';
 }
 $CGI->{mv_order_item} = $CGI->{mv_arg}
  if ! $CGI->{mv_order_item};
 $Tag->update('values');
 return 1;
}
EOR

ActionMap  deliver   <<EOR
sub {
 my $deliverable = shift;
 $Scratch->{deliverable} = $CGI->{mv_arg};
 $CGI->{mv_nextpage} = 'deliver';
 return 1;
}
EOR
-----------------------------------------------------------

     So, this is a typical entry in /tmp/mvdebug after I have submitted
an
order via the checkout page :

-----------------------------------------------------------

LPERL:debug: CapturePayment: statusCode: 1

LPERL:debug: CapturePayment: statusMessage:

LPERL:debug: CapturePayment: AVSCode: 12345612345678

LPERL:debug: CapturePayment: trackingID: 12345678

LPERL:debug: CapturePayment: neworderID:
24.25.81.245-971299676-4974-16330-14

LPERL:debug: CapturePayment: statusApproval: APPROVED

LPERL:debug: CapturePayment: subtotal: 118.50

LPERL:debug: CapturePayment: tax: 8.15

LPERL:debug: CapturePayment: time: Wed Oct 11 16:27:56 2000

LPERL:debug: is the scalar neworderID intialized yet?
 24.25.81.245-971299676-4974-16330-14
how about statusCode?
 1
---------------------------------------------------------

     And this is what shows up in the catalog directory's error log:

clt27-255-029.carolina.rr.com h6npk398:rr.com -
[11/October/2000:17:29:04 -0400] simply /cgi-bin/simply/process.html
Order id:


     It seems fairly clear based on this last piece of evidence that the

result hash that Interchange supposedly must get back from a custom
&charge sub
is NOT getting returned correctly from linkpt_charge.  I have followed a
couple
threads on this list related to the topic of %result, and designed my
subroutine
accordingly : to return a hash 'result' with at least the key-value
pairs
MStatus => 'success' and order-id => 'whatever'.  Anybody see some
glaring mistake
here (it wouldn't surprise me, given my weak Perl skills!)???

     You may have noticed that in my profiles.order call to
linkpt_charge,
I used [value credit_card_number], which of course is not a standard tag
-- I used
this because I could not figure out another way to circumvent the
immediate
voiding of [mv_credit_card_number] after its validation check, and I
must pass it
to linkpt_charge.  So I replaced the special [mv_credit_card_number]
variable in
checkout.html w/ [credit_card_number], and it seems to work, though I
understand this
is a security no-no.  Could this have something to do with why
Interchange doesn't
seem to accept/parse my "return %results;"?

     I guess a lot this boils down to the question "when one
'short-circuits' the
standard CyberCash routines w/ a custom sub, how much of the standard
order process
(emails, reports, logging) is going to be likewise short-circuited?".
If I manage
to get the result hash returned to Interchange in the form it wants it,
will these
other aspects of order routing work again as expected?  I have a fear
that serious
reconstruction of Order.pm may be required, but in the meantime, exactly
what
modifications do I need to make to send the user to an 'order success'
or, better
yet, a receipt page, even if it's not truly successful vis-a-vis
Interchange's
backend order processing?   None of the standard [mv_nextpage] tags seem
to be
utilized w/ the checkout page's forms.

     I'd be hugely appreciative of anybody's input on this, and will
gladly write
up a micro-HOWTO on this if I can get it working.  Thanks in advance,
(and apologies for any line-wrap problems w/ this message -- i haven't
had time
to figure out why Netscape keeps scrambling my format)

    Josh Simpson