[Date Prev][Date Next][Thread Prev][Thread Next][Interchange by date
][Interchange by thread
]
[ic] Updated Signio globalsub for PayflowPro Version 3.0 - DONE
Attached you will find the updated globalsub for Verisign's PayflowPro
verision 3.0. This sub is also upgraded to work with Interchange 4.7.5.
In the sub I've documented my changes. In short, I moved the variables
into the variable.txt file. Plus, with the new version of PayflowPro some
additonal variables were added. I'm sure it could use some more tweeking
if someone else would like to look at it and add to it.
Michelle
michelle@wilant.com
# This is how you can use Verisign's PayflowPro (version 3.0) with Interchange.
#
Variable SIGNIO_HELP <<EOV
1. Modify interchange.cfg to use this file.
#include globalsub/signio (your path to this signio file)
(with interchange 4.7 and above may be with (ConfigParseComments Yes)
or without # sign in front (ConfigParseComments No))
2. Modify CATROOT/products/variable.txt to set the server and your PayflowPro (signio) account info
Variable MV_PAYMENT_ID YourPayflowProID (you create with verisign)
Variable MV_PAYMENT_SECRET YourPayflowProPassword (you create with verisign)
Variable MV_PAYMENT_SERVER payflow.verisign.com
# Use test-payflow.verisign.com for testing
Variable MV_PAYMENT_VENDOR YourPayflowProVendor (or YourPayflowProID)
Variable MV_PAYMENT_PARTNER YourPayflowProPartner (verisign provides)
Variable MV_PAYMENT_MODE signio
Variable MV_PAYMENT_TRANS_TYPE Transaction type (look at list below)
Transaction Types:
sale S
credit C
authorization A
delayed capture D
void V
voice authorization F
inqury I
Variable MV_PAYMENT_PFPRO_AVS Y or N - Should AVS be used for U.S. Card holders
Variable MV_PAYMENT_TENDER_TYPE C for credit - look in Payflow Pro's docs for others
Variable MV_PAYMENT_PFPRO_CERT_PATH Path to the cert that came with your download of Payflow Pro
Variable MV_PAYMENT_PFPRO_EXE_PATH Path to the pfpro executable
Variable MV_PAYMENT_PFPRO_PORT Port for pfpro - usually 443
Variable MV_PAYMENT_PRECISION how many digits do you want after the decimal for the dollar amount - US=2
3. Set CreditCardAuto is off (default) in the catalog.cfg file
If not there add:
CreditCardAuto no
4. set subroutine in CATROOT/etc/profiles.order
replace &charge=[var MV_PAYMENT_MODE][cgi mv_payment_test]
with
&charge=signio
6. Restart Interchange.
7. Strongly suggest to use the logDebug function to help with testing. In interchange.cfg set Variable DEBUG to 1 then
set DebugFile to where you want the output to go. Default is /tmp/icdebug. Then uncomment the needed logDebugs
below.
Changes:
- PayflowPro 3.0 requires additonal values to be passed. These are: partner and vendor.
SOLUTION: Added MV_PAYMENT_VENDOR and MV_PAYMENT_PARTNER to the catalog.cfg file.
- The use of a cert (included with PayflowPro) is also required.
SOLUTION: set variable in variable.txt to where the cert is located
- Also added function to combine address1 or badddress1 for submission to PayflowPro as ADDRESS.
- Also added AVS fuctionality as an option for submission for US customers.
NOTE: AVS RESPONSE IS NOT USED IN THIS SCRIPT
- that functionality needs to be added for how you want to use the AVS response.
- Updated the TRXTYPE codes below to PayfloPro's listing:
sale S
credit C
authorization A
delayed capture D
void V
voice authorization F
inquiry I
- Placed all variables in the variable.txt file.
*ANY ADDITONS/ROBUSTIFING/CLEANUP is greatly appreciated.
michelle\@wilant.com
EOV
GlobalSub <<EOS
sub signio {
#::logDebug("\n\n***********\npayflow pro subroutine called - logDebug");
my ($user, $secret, $amount, $vendor,
$partner, $exe, $cert, $mode, $trans_type,
$avs, $tender_type, $server,
$precision, $port, $acct) = @_;
$user = "";
my %query = "";
my (%actual) = Vend::Order::map_actual();
if(! $user ) {
$user = $::Variable->{MV_PAYMENT_ID}
or return undef;
}
#::logDebug("pfpro user $user");
if(! $secret ) {
$secret = $::Variable->{MV_PAYMENT_SECRET}
or return undef;
}
if(! $server ) {
$server = $::Variable->{MV_PAYMENT_SERVER}
or return undef;
}
if(! $vendor ) {
$vendor = $::Variable->{MV_PAYMENT_VENDOR}
or return undef;
}
if(! $partner ) {
$partner = $::Variable->{MV_PAYMENT_PARTNER}
or return undef;
}
if(! $mode ) {
$mode = $::Variable->{MV_PAYMENT_MODE}
or return undef;
}
#::logDebug("pfpro payment mode $mode");
if(! $tender_type ) {
$tender_type = $::Variable->{MV_PAYMENT_TENDER_TYPE}
or return undef;
}
#::logDebug("pfpro tender type $tender_type");
if(! $trans_type ) {
$trans_type = $::Variable->{MV_PAYMENT_TRANS_TYPE}
or return undef;
}
#::logDebug("pfpro transaction type $trans_type");
if(! $avs ) {
$avs = $::Variable->{MV_PAYMENT_PFPRO_AVS}
or return undef;
}
#::logDebug("pfpro avs being used: $avs");
$ENV{"PFPRO_CERT_PATH"} = $::Variable->{MV_PAYMENT_PFPRO_CERT_PATH}
or return undef;
#::logDebug("path for pfpro cert: $ENV{\"PFPRO_CERT_PATH\"}");
if(! $exe ) {
$exe = $::Variable->{MV_PAYMENT_PFPRO_EXE_PATH}
or return undef;
}
#::logDebug("path for pfpro executable: $exe");
if (! $port) {
$port = $::Variable->{MV_PAYMENT_PFPRO_PORT}
or return undef;
}
#::logDebug("port: $port");
if (! $precision ){
$precision = $::Variable->{MV_PAYMENT_PRECISION}
or return undef;
}
#::logDebug("precision: $precision");
$actual{mv_credit_card_exp_month} =~ s/\D//g;
$actual{mv_credit_card_exp_month} =~ s/^0+//;
$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;
my $exp = sprintf '%02d%02d',
$actual{mv_credit_card_exp_month},
$actual{mv_credit_card_exp_year};
my %type_map = (
qw/
sale S
credit C
authorization A
delayed_capture D
void V
voice_authorization F
inqury I
S S
C C
A A
D D
V V
F F
I I
/
);
if(! $amount ) {
$amount = Vend::Interpolate::total_cost();
$amount = sprintf("%.${precision}f", $amount);
}
my($orderID);
my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time());
# We'll make an order ID based on date, time, and Interchange session
# $mon is the month index where Jan=0 and Dec=11, so we use
# $mon+1 to get the more familiar Jan=1 and Dec=12
$orderID = sprintf("%02d%02d%02d%02d%02d%05d%s",
$year + 1900,$mon + 1,$mday,$hour,$min,$Vend::SessionName);
my %varmap = ( qw/
ACCT mv_credit_card_number
ZIP zip
STREET address
STREET1 address1
STREET2 address2
BSTREET1 b_address1
BSTREET2 b_address2
COUNTRY country
/
);
my %query = (
USER => $user,
VENDOR => $vendor,
PARTNER => $partner,
AMT => $amount,
EXPDATE => $exp,
TENDER => $tender_type,
ORIGID => $orderID,
PWD => $secret,
TRXTYPE => $trans_type
);
if($avs eq "Y" && $actual{$varmap{'COUNTRY'}} eq "US"){
if($actual{$varmap{'BSTREET1'}} ne ""){
$actual{$varmap{'STREET'}} = $actual{$varmap{'BSTREET1'}};
}elsif($actual{$varmap{'STREET1'}} ne ""){
$actual{$varmap{'STREET'}} = $actual{$varmap{'STREET1'}};
}
#::logDebug(qq{AVS LOOP WORKS\n});
for (keys %varmap) {
if($_ eq "STREET1"||$_ eq "STREET2"||$_ eq "BSTREET1"||$_ eq "BSTREET2"||$_ eq "COUNTRY"){
next;
}else{
$query{$_} = $actual{$varmap{$_}};
#::logDebug(qq{*$query{$_} = $actual{$varmap{$_}}\n});
}
}
}else{
#::logDebug(qq{NON-AVS LOOP WORKS\n});
for (keys %varmap) {
if($_ eq "STREET1"||$_ eq "STREET2"||$_ eq "BSTREET1"||$_ eq "BSTREET2"||
$_ eq "STREET"||$_ eq "ZIP"||$_ eq "COUNTRY"){
next;
}else{
$query{$_} = $actual{$varmap{$_}};
#::logDebug(qq{*$query{$_} = $actual{$varmap{$_}}\n});
}
}
}
my @query;
for (keys %query) {
my $key = $_;
my $val = $query{$key};
$val =~ s/["\$\n\r]//g;
$val =~ s/\$//g;
$val =~ tr/ /+/;
my $len = length($val);
if($val =~ /[&=]/) {
$key .= "[$len]";
}
push @query, "$key=$val";
#::logDebug("***\$key=$val\n");
}
my $string = join '&', @query;
#::logDebug(qq{***pfprosub call: $exe $server $port "$string" |\n});
open(CONNECT, qq{$exe $server $port "$string" |})
or die "can't fork: $!\n";
my $msg = undef;
local($/);
my $result = <CONNECT>;
#::logDebug(qq{*** my $result = <CONNECT>\n\n});
close CONNECT;
my $decline = $?;
#::logDebug(qq{signio decline = $decline\n result: $result\n});
my %result_map = ( qw/
MStatus RESULT
pop.status RESULT
MErrMsg RESPMSG
pop.error-message RESPMSG
order-id PNREF
pop.order-id PNREF
pop.auth-code AUTHCODE
pop.avs_code AVSZIP
pop.avs_zip AVSZIP
pop.avs_addr AVSADDR
pop.cvv2match CVV2MATCH
/
);
my %result = split /[&=]/, $result;
for (keys %result_map) {
$result{$_} = $result{$result_map{$_}}
if defined $result{$result_map{$_}};
#::logDebug(qq{ $_=$result{$result_map{$_}}\n});
}
$Vend::Session->{payment_result} = \%result;
#::logDebug(qq{payment_result: $Vend::Session->{payment_result}\n}):
delete $Vend::Session->{payment_error};
#::logDebug(qq{payment_error: $Vend::Session->{payment_error}\n});
if ($decline) {
$decline = $decline >> 8;
$result{'pop.status'} =
$result{'MStatus'} = 'failed';
#::logDebug(qq{decline = $decline\n});
$Vend::Session->{payment_error} = $result{RESPMSG};
#::logDebug(qq{result{respmsg} = $result{RESPMSG}\n});
my $msg = errmsg("Payment error: " . $result{RESULT} . " " . $result{RESPMSG} ." ". "Please call in your order or try again.");
#::logDebug(qq{$msg\n});
$Vend::Session->{errors}{mv_credit_card_valid} = $msg;
}else {
$result{'pop.status'} =
$result{'MStatus'} = 'success';
$Vend::Session->{payment_id} = $result{'pop.order-id'};
$Vend::Session->{payment_error} = $result{RESPMSG};
}
#::logDebug(qq{signio decline=$decline result:\n } . ::uneval( \%result));
return %result;
}
EOS