[Date Prev][Date Next][Thread Prev][Thread Next][Interchange by date
][Interchange by thread
]
[ic] Skip Skipjack?
--=-yMvq6mbzEY2LWvhOoJu+
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
On Fri, 2002-02-08 at 11:22, Michael Stearne wrote:
Kari Suomela wrote:
> Has someone actually been able to get 4.8.3 working with Skipjack?
> We've now fiddled with it and investigated for a couple of weeks, and
> received nothing but contradicting instructions. We would pay someone,
> if they can get it working.
Maybe buy the support license from RedHat and get them to get it to work
for you. No one has seemed to have had any luck with 4.8.2/3.
<snip>
I've attached a working Skipjack.pm. The one that ships with 8.2/3
doesn't work correctly. It's been a while since I played with this, so
I don't remember the exact errors, but I believe it had to do with an
incorrect post url... I hope to have some time this weekend to fix this
up and have a diff to post, but until then....
Matt
--=-yMvq6mbzEY2LWvhOoJu+
Content-Disposition: attachment; filename=Skipjack.pm
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1
# Vend::Payment::Skipjack - Interchange Skipjack support
#
# $Id: Skipjack.pm,v 2.0 2001/07/18 02:23:16 jon Exp $
#
# Copyright (C) 1999-2001 Red Hat, Inc. <interchange@redhat.com>
#
# Written by Cameron Prince <cprince@redhat.com> and
# Mark Johnson <markj@redhat.com>,
# 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::Skipjack;
=3Dhead1 Interchange Skipjack Support
Vend::Payment::Skipjack $Revision: 2.0 $
=3Dhead1 SYNOPSIS
&charge=3Dskipjack
or
[charge mode=3Dskipjack param1=3Dvalue1 param2=3Dvalue2]
=3Dhead1 PREREQUISITES
Net::SSLeay
=20
or
=20
LWP::UserAgent and Crypt::SSLeay
Only one of these need be present and working.
=3Dhead1 DESCRIPTION
The Vend::Payment::Skipjack module implements the skipjack() routine for us=
ing
Skipjack IC payment services with Interchange. It is compatible on a call l=
evel
with the other Interchange payment modules -- in theory (and even usually i=
n
practice) you could switch from CyberCash to Skipjack with a few configurat=
ion
file changes.
To enable this module, place this directive in C<interchange.cfg>:
Require module Vend::Payment::Skipjack
This I<must> be in interchange.cfg or a file included from it.
NOTE: 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<skipjack>. 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 skipjack
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 option=
s,
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=3Dskipjack id=3DYourSkipjackID]
or
Route skipjack id YourSkipjackID
or with only Skipjack as a payment provider
Variable MV_PAYMENT_ID YourskipjackID
A fully valid catalog.cfg entry to work with the standard demo would be:
Variable MV_PAYMENT_MODE skipjack
Route skipjack id YourSkipjackID
Route skipjack vendor YourSkipjackVendor
The active settings are:
=3Dover 4
=3Ditem id
Your account ID number, supplied by Skipjack when you sign up.
Global parameter is MV_PAYMENT_ID.
=3Ditem vendor
The developer ID of the system which interfaces with Skipjack.
Global parameter is MV_PAYMENT_VENDOR.
=3Ditem transaction
The type of transaction to be run. Valid values are:
Interchange Skipjack
---------------- -----------------
sale sale
recurring recurring
Default is C<sale>.
If you wish to do a recurring charge, you will have to ensure that the
following Interchange values are set properly:
Interchange variable Skipjack variable
-------------------- -----------------
recurring_item rtItemNumber
recurring_desc rtItemDescription
recurring_start_date rtStartingDate
recurring_frequency rtFrequency
recurring_transactions rtTotalTransactions
recurring_comment rtComment
=3Ditem test
If you set the C<test> parameter, Interchange will remap some values and
the URL for the transaction to point to the Skipjack test server.
It will return a valid transaction if all is working.
=3Ditem generate_error
To generate errors in test mode only, set the parameter C<generate_error>
to one of the following values (error it generates in parenthesese):
number (invalid credit card number)
avs (will succeed, but generate AVS message)
exp (expired card)
id (invalid Skipjack account?)
vendor (invalid vendor?)
=3Dback
The following should rarely be used, as the supplied defaults are
usually correct.
=3Dover 4
=3Ditem remap
This remaps the form variable names to the ones needed by Skipjack. See
the C<Payment Settings> heading in the Interchange documentation for use.
=3Ditem submit_url
The Skipjack URL to submit to. Default is:
https://www.skipjackic.com/scripts/evolvcc.dll?Authorize
=3Dback
=3Dhead2 Troubleshooting
Try the instructions above, then enable test mode:
Route skipjack test 1
A test order should complete.
Then set a generate error
Route skipjack test 1
Route skipjack generate_error number
and try a sale. The sale should be denied, and the reason should
be in [data session payment_error].
If nothing works:
=3Dover 4
=3Ditem *
Make sure you "Require"d the module in interchange.cfg:
Require module Vend::Payment::iTransact
=3Ditem *
Make sure either Net::SSLeay or Crypt::SSLeay and LWP::UserAgent are instal=
led
and working. You can test to see whether your Perl thinks they are:
perl -MNet::SSLeay -e 'print "It works\n"'
or
perl -MLWP::UserAgent -MCrypt::SSLeay -e 'print "It works\n"'
If either one prints "It works." and returns to the prompt you should be OK
(presuming they are in working order otherwise).
=3Ditem *
Check the error logs, both catalog and global.
=3Ditem *
Make sure you set your account ID properly. =20
=3Ditem *
Try an order, then put this code in a page:
<XMP>
[calc]
my $string =3D $Tag->uneval( { ref =3D> $Session->{payment_result} =
});
$string =3D~ s/{/{\n/;
$string =3D~ s/,/,\n/g;
return $string;
[/calc]
</XMP>
That should show what happened.
=3Ditem *
If all else fails, Red Hat and other consultants are available to help
with integration for a fee.
=3Dback
=3Dhead1 BUGS
There is actually nothing *in* Vend::Payment::Skipjack. It changes packages
to Vend::Payment and places things there.
=3Dhead1 AUTHORS
Originally developed by New York Connect Net (http://nyct.net)
Michael Bacarella <mbac@nyct.net>
Modified for GetCareer.com by Slipstream.com by Troy Davis <troy@slipstream=
.com>
LWP/Crypt::SSLeay interface code by Matthew Schick,
<mschick@brightredproductions.com>.
Interchange implementation by Mike Heins, <mheins@redhat.com>.
=3Dcut
BEGIN {
my $selected;
eval {
package Vend::Payment;
require Net::SSLeay;
import Net::SSLeay qw(post_https make_form make_headers);
$selected =3D "Net::SSLeay";
};
$Vend::Payment::Have_Net_SSLeay =3D 1 unless $@;
unless ($Vend::Payment::Have_Net_SSLeay) {
eval {
package Vend::Payment;
require LWP::UserAgent;
require HTTP::Request::Common;
require Crypt::SSLeay;
import HTTP::Request::Common qw(POST);
$selected =3D "LWP and Crypt::SSLeay";
};
$Vend::Payment::Have_LWP =3D 1 unless $@;
}
unless ($Vend::Payment::Have_Net_SSLeay or $Vend::Payment::Have_LWP) {
die __PACKAGE__ . " requires Net::SSLeay or Crypt::SSLeay";
}
::logGlobal("%s payment module initialized, using %s", __PACKAGE__, $selec=
ted)
unless $Vend::Quiet;
}
package Vend::Payment;
use vars qw/%SJ_ERRORS %SJ_AVS_CODES %SJ_RT_FREQ %SJ_RC_ERRORS/;
use vars qw/$Have_LWP $Have_Net_SSLeay/;
%SJ_ERRORS =3D (
'1' =3D> 'Authorization failed, card declined (1)',
'-1' =3D> 'Invalid length (-1)',
'-35' =3D> 'Invalid credit card number (-35)',
'-37' =3D> 'Failed communication (-37)',
'-39' =3D> 'Serial number is too short (-39)',
'-51' =3D> 'The zip code is invalid',
'-52' =3D> 'The shipto zip code is invalid',
'-53' =3D> 'Length of expiration date (-53)',
'-54' =3D> 'Length of account number date (-54)',
'-55' =3D> 'Length of street address (-55)',
'-56' =3D> 'Length of shipto street address (-56)',
'-57' =3D> 'Length of transaction amount (-57)',
'-58' =3D> 'Length of name (-58)',
'-59' =3D> 'Length of location (-59)',
'-60' =3D> 'Length of state (-60)',
'-61' =3D> 'Length of shipto state (-61)',
'-62' =3D> 'Length of order string (-62)',
'-64' =3D> 'Invalid phone number (-64)',
'-65' =3D> 'Empty name (-65)',
'-66' =3D> 'Empty email (-66)',
'-67' =3D> 'Empty street address (-66)',
'-68' =3D> 'Empty city (-68)',
'-69' =3D> 'Empty state (-69)',
'-70' =3D> 'Empty zip code (-70)',
'-71' =3D> 'Empty order number (-71)',
'-72' =3D> 'Empty account number (-72)',
'-73' =3D> 'Empty expiration month (-73)',
'-74' =3D> 'Empty expiration year (-74)',
'-75' =3D> 'Empty serial number (-75)',
'-76' =3D> 'Empty transaction amount (-76)',
'-79' =3D> 'Length of customer name (-79)',
'-80' =3D> 'Length of shipto customer name (-80)',
'-81' =3D> 'Length of customer location (-81)',
'-82' =3D> 'Length of customer state (-82)',
'-83' =3D> 'Length of shipto phone (-83)',
'-84' =3D> 'Pos Error duplicate ordernumber (-84)',
'-91' =3D> 'Pos Error CVV2 (-91)',
'-92' =3D> 'Pos Error Approval Code (-92)',
'-93' =3D> 'Pos Error Blind Credits Not Allowed (-93)',
'-94' =3D> 'Pos Error Blind Credits Failed (-94)',
'-95' =3D> 'Pos Error Voice Authorizations Not Allowed (-95)=
',
);
%SJ_AVS_CODES =3D (
'X' =3D> 'Exact match, 9 digit zip',
'Y' =3D> 'Exact match, 5 digit zip',
'A' =3D> 'Address match only',
'W' =3D> '9 digit match only',
'Z' =3D> '5 digit match only',
'N' =3D> 'No address or zip match',
'U' =3D> 'Address unavailable',
'R' =3D> 'Issuer system unavailable',
'E' =3D> 'Not a mail/phone order',
'S' =3D> 'Service not supported'
);
%SJ_RT_FREQ =3D ( # Logic used for the frequency of recurring transactions
'Weekly' =3D> '0', # Starting Date + 7 Days
'Biweekly' =3D> '1', # Starting Date + 14 Days
'Twice Monthly' =3D> '2', # Starting Date + 15 Days
'Monthly' =3D> '3', # Every month
'Every Four Weeks' =3D> '4', # Every fourth week
'Bimonthly' =3D> '5', # Every other month
'Quarterly' =3D> '6', # Every third month
'Biannually' =3D> '7', # Semiannually / Twice per year
'Annually' =3D> '8', # Once a year
'0' =3D> '0',
'1' =3D> '1',
'2' =3D> '2',
'3' =3D> '3',
'4' =3D> '4',
'5' =3D> '5',
'6' =3D> '6',
'7' =3D> '7',
'8' =3D> '8'
);
%SJ_RC_ERRORS =3D (
'1' =3D> 'CALL FAILED (1)',
'-1' =3D> 'INVALID COMMAND (-1)',
'-2' =3D> 'PARAMETER MISSING (-2)',
'-3' =3D> 'FAILED RETRIEVING RESPONSE (-3)',
'-4' =3D> 'INVALID STATUS (-4)',
'-5' =3D> 'FAILED READING SECURITY FLAGS (-5)',
'-6' =3D> 'DEVELOPER SERIAL NUMBER NOT FOUND (-6)',
'-7' =3D> 'INVALID SERIAL NUMBER (-7)',
'-8' =3D> 'EXPIRATION YEAR IS NOT FOUR CHARECTERS (-8)',
'-9' =3D> 'CREDIT CARD EXPIRED (-9)',
'-10' =3D> 'INVALID STARTING DATE (-10)',
'-11' =3D> 'FAILED ADDING RECURRING PAYMENT (-11)',
'-12' =3D> 'INVALID FREQUENCY (-12)'
);
sub sj_test_values {
my ($inopt, $inval) =3D @_;
my $opt =3D {
id =3D> '000658076426',
submit_url =3D>
'https://developer.skipjackic.com/scripts/evolvcc.dll?Authorize',
vendor =3D> '111222333444',
};
my $val =3D {
mv_credit_card_number =3D> '4445999922225',
mv_credit_card_cvv2 =3D> '999',
mv_credit_card_exp_month =3D> '09',
mv_credit_card_exp_year =3D> '02',
b_address =3D> '8320 Rocky Road',
b_zip =3D> '85284',
};
my $gen;
if($inopt and $gen =3D $inopt->{generate_error}) {
$opt->{id} =3D '1111000011111' if $gen eq /\bid\b/i;
$opt->{vendor} =3D '1111000011111' if $gen =3D~ /vendor/i;
$val->{mv_credit_card_number} =3D '4111111111111112' if $gen =3D~ /number=
/i;
$val->{b_zip} =3D '45056' if $gen =3D~ /avs/i;
$val->{mv_credit_card_exp_year} =3D '00' if $gen =3D~ /exp/i;
}
if($inopt) {
for (keys %$opt) {
$inopt->{$_} =3D $opt->{$_};
}
}
if($inval) {
for (keys %$val) {
$inval->{$_} =3D $val->{$_};
}
}
return ($opt, $val);
}
sub skipjack {
my ($opt, $amount) =3D @_;
my $user =3D $opt->{id} || charge_param('id');
my %actual;
if($opt->{actual}) {
%actual =3D %{$opt->{actual}};
}
else {
%actual =3D map_actual();
}
if($opt->{test} || charge_param('test')) {
sj_test_values($opt, \%actual);
}
my $ccem =3D $actual{mv_credit_card_exp_month};
$ccem =3D~ s/\D//g;
$ccem =3D~ s/^0+//;
$ccem =3D sprintf('%02d', $ccem);
my $ccey =3D $actual{mv_credit_card_exp_year};
$ccey +=3D 2000 unless $ccem =3D~ /\d{4}/;
$actual{mv_credit_card_number} =3D~ s/\D//g;
$actual{phone_day} =3D~ s/\D//g;
my $precision =3D $opt->{precision} || charge_param('precision') || 2;
$amount =3D $opt->{total_cost} || undef;
$opt->{transaction} =3D charge_param('transaction') || 'sale';
my $transtype =3D $opt->{transaction};
# Skipjack doesn't do transaction types?
my %type_map =3D (
);
=09
if (defined $type_map{$transtype}) {
$transtype =3D $type_map{$transtype};
}
if(! $amount) {
$amount =3D Vend::Interpolate::total_cost();
$amount =3D Vend::Util::round_to_frac_digits($amount,$precision);
}
my %values;
if($transtype eq 'sale') {
%values =3D (
Sjname =3D> $actual{b_name},
Email =3D> $actual{email},
Streetaddress =3D> $actual{b_address},
City =3D> $actual{b_city},
State =3D> $actual{b_state},
Zipcode =3D> $actual{b_zip},
Ordernumber =3D> $opt->{order_id},
Accountnumber =3D> $actual{mv_credit_card_number},
Month =3D> $ccem,
Year =3D> $ccey,
Serialnumber =3D> $user,
Transactionamount =3D> $amount,
Orderstring =3D> "0001~Generic Order String~$amount~1~N~||",
Shiptophone =3D> $actual{phone_day}
);
}
elsif($transtype eq 'recurring') {
%values =3D (
szSerialNumber =3D> $user,
szDeveloperSerialNumber =3D> $opt->{vendor},
rtName =3D> $actual{b_name},
rtEmail =3D> $actual{b_email},
rtAddress1 =3D> $actual{b_address},
rtCity =3D> $actual{b_city},
rtState =3D> $actual{b_state},
rtPostalCode =3D> $actual{b_zip},
rtCountry =3D> $actual{b_country},
rtPhone =3D> $actual{phone_day},
rtAccountnumber =3D> $actual{mv_credit_card_number},
rtExpMonth =3D> $ccem,
rtExpYear =3D> $ccey,
rtItemNumber =3D> $opt->{item_code},
rtItemDescription =3D> $opt->{item_description},
rtAmount =3D> $amount,
rtStartingDate =3D> $opt->{start_date},
rtFrequency =3D> $SJ_RT_FREQ{$opt->{frequency}},
rtTotalTransactions =3D> $opt->{total_transactions},
rtOrderNumber =3D> $opt->{order_id},
rtComment =3D> $actual{gift_note},
);
}
#my $submit_url =3D $opt->{submit_url} || 'https://www.skipjackic.com/scri=
pts/evolvcc.dll?Authorize';
$opt->{submit_url} =3D 'https://www.skipjackic.com/scripts/evolvcc.dll?Aut=
horize';
#::logDebug("URL: $submit_url");
my $thing =3D post_data($opt, \%values);
#::logDebug("Sending: " . ::uneval(\%values) . ::uneval($opt) );
## check for errors
my $error;
#::logDebug("request returned: $thing->{result_page}");
my %result;
if($transtype eq 'sale') {
my @lines =3D split /</, $thing->{result_page};
@lines =3D grep /\!-+/, @lines;
for (@lines) {
#::logDebug("found response line=3D$_");
s/-->.*//s;
if (/^!--(.*)/) {
my ($name, $val) =3D split(/=3D/,$1);
#::logDebug("name=3D$name value=3D$val");
$result{$name} =3D $val;
}
}
if ($result{szAuthorizationResponseCode} ne "") {
$result{MStatus} =3D $result{'pop.status'} =3D 'success';
$result{'order-id'} =3D $opt->{order_id};
}
else {
$result{MStatus} =3D 'failed';
$result{MErrMsg} =3D $SJ_ERRORS{$result{szReturnCode}}
}
}
elsif ($transtype eq 'recurring') {
$thing->{result_page} =3D~ s/\"//g;
my ($ron,$rc,$rn) =3D split(/\,/, $thing->{result_page});
$result{szAuthorizationResponseCode} =3D $ron || '';
if($rc =3D=3D 0) {
$result{MStatus} =3D 'success';
$result{'order-id'} =3D $ron;
}
else {
$result{MStatus} =3D 'failed';
$result{MErrMsg} =3D $SJ_RC_ERRORS{$rc}
}
}
else {
return (
MStatus =3D> 'failure-hard',
MErrMsg =3D> ::errmsg('unknown transction type: %s',$transtype),
);
}
# Interchange names are on the left, Skipjack on the right
my %result_map =3D ( qw/
pop.ref-code szSerialNumber
pop.auth-code szAuthorizationResponseCode
pop.avs_code szAVSResponseCode
pop.avs_reason szAVSResponseMessage
pop.txn-id szOrderNumber
pop.price szTransactionAmount
pop.error-message szAuthorizationResponseCode
pop.cvv2_code szCVV2ResponseCode
pop.cvv2_reason szCVV2ResponseMessage
icp_ref_code szSerialNumber
icp_auth_code szAuthorizationResponseCode
icp_avs_code szAVSResponseCode
icp_avs_reason szAVSResponseMessage
icp_txn_id szOrderNumber
icp_price szTransactionAmount
icp_error_message szAuthorizationResponseCode
icp_cvv2_code szCVV2ResponseCode
icp_cvv2_reason szCVV2ResponseMessage
/
);
for (keys %result_map) {
$result{$_} =3D $result{$result_map{$_}}
if defined $result{$result_map{$_}};
}
#::logDebug("Skipjack request result: " . ::uneval(\%result) );
return %result;
}
package Vend::Payment::Skipjack;
1;
--=-yMvq6mbzEY2LWvhOoJu+--