[ic] SUrEPay IntegraTIon

ben schlaver ben@closetgenius.com
Fri, 20 Apr 2001 13:28:26 -0700


any care to critique and correct?

# This is how you can use Surepay with Interchange.
#
Variable SUREPAY_HELP <<EOV

 1. Modify interchange.cfg to use this file.

 #include globalsub/surepay

 2. Modify catalog.cfg to set the server and your Signio account info

 # Username and password
 Variable MV_PAYMENT_ID      YourSurePayID
 Variable MV_PAYMENT_SECRET  YourSurePayPassword
 # Use xml.test.surepay.com for testing
 Variable MV_PAYMENT_SERVER  xml.surepay.com

 3. Set the payment mode in catalog.cfg:

 Variable MV_PAYMENT_MODE    custom surepay

 4. Make sure CreditCardAuto is off (default)

 5. Restart Interchange.

EOV

GlobalSub <<EOS
sub surepay {
#::logDebug("surepayo called");
    my ($cspmid, $password, $amount) = @_;
    my $exe = "$Global::VendRoot/lib/PurePaymentsSDK.pl";

    my (%actual) = Vend::Order::map_actual();

    if(! $cspmid  ) {
        $cspmid    =  $::Variable->{MV_PAYMENT_ID} ||
                    $::Variable->{CYBER_ID}
                    or return undef;
    }
#::logDebug("surepay user $user");
    if(! $secret) {
        $password  =  $::Variable->{MV_PAYMENT_SECRET} ||
                    $::Variable->{CYBER_SECRET}
                    or return undef;
    }
#::logDebug("surepay secret $secret");

    my $host_live  =   $::Variable->{MV_PAYMENT_SERVER} ||
                    $::Variable->{CYBER_SERVER} ||
                    'xml.surepay.cgi';

    my $port_live    =   $::Variable->{MV_PAYMENT_PORT} ||
                    $::Variable->{CYBER_PORT} ||
                    443;

    my $securityopt = $::Variable->{MV_PAYMENT_PRECISION} ||
                    $::Variable->{CYBER_PRECISION} ||
                    2;


	$in{gtype}    ||= 'https';  # (http|https|test)
	$in{numitems} ||= 5;        # Max number of line items to allow
	$in{dumpxml}  ||= 'N';      # Display request/response xml if eq 'Y'
	$in{debug}    ||= 0;        # Additional debug info if > 0

    $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};

    $actual{cyber_mode} = 'S'
        unless $actual{cyber_mode};

    my %type_map = (
        qw/
                        mauthcapture  S
                        mauthonly     C
                        mauthdelay    D
                        mauthreturn   V
                        S             S
                        C             C
                        D             D
                        V             V
        /
    );

	$sdkversion = "PERL";
	$sdktype = 1.4;
	$ecommerce = "true";

    if (defined $type_map{$actual{cyber_mode}}) {
        $actual{cyber_mode} = $type_map{$actual{cyber_mode}};
    }
    else {
        $actual{cyber_mode} = 'S';
    }

    if(! $amount) {
        $amount = Vend::Interpolate::total_cost();
        $amount = sprintf("%.${2}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 $reqManager = RequestManager::new($in{gtype},$in{'data session
host'},$in{port},$in{path},$in{debug},'');
    my $billAddress = Address::new('billing',
                   'fullname' => $in{'b_fname b_lname'},
			       'email'    => $in{email},
			       'eveningphone' => $in{b_phone},
			       'fax'      => $in{fax},
			       'address1' => $in{b_address1},
			       'address2' => $in{b_address2},
			       'address3' => $in{b_address3},
			       'city'     => $in{b_city},
			       'state'    => $in{b_state},
			       'country'  => $in{b_country},
			       'zip'      => $in{b_zip});
    my $shipAddress = Address::new('shipping',
                   'fullname' => $in{'fname lname'},
                   'email'    => $in{email},
			       'eveningphone' => $in{phone_day},
			       'fax'      => $in{fax},
			       'address1' => $in{address1},
			       'address2' => $in{address2},
			       'address3' => $in{address3},
			       'city'     => $in{city},
			       'state'    => $in{state},
			       'country'  => $in{country},
			       'zip'      => $in{zip});

    my %varmap = ( qw/
                            ccn         mv_credit_card_number
                            bzip        zip
                            baddress1   address1
                            baddress2   address2
                            baddress3   address3
                            ptype       cyber_mode
        /
    );

    my %query = (
                    totalAmt     => $amount,
                    exp      =>
$'mv_credit_card_exp_month/mv_credit_card_exp_year',
                    ptype        => 'cc',
                    ordernumber  => $orderID,
                    password     => $MV_PAYMENT_SECRET,
                    cspmid       => $MV_PAYMENT_ID,
    );

    for (keys %varmap) {
        $query{$_} = $actual{$varmap{$_}};
    }

my ($pi);
if ($in{ptype} eq 'cc') # CreditCard
{
  $pi =
CreditCard::new($in{mv_credit_card_number},$in{'mv_credit_card_exp_month/mv_
credit_card_exp_year'},$in{0},$in{0},$billAddress);  #
number,expiration,address
}
else # CreditCard or TeleCheck
{
  $obj =
Auth::new($in{order_number},$in{description},$in{ponumber},'',$in{authcode},
		   $in{'data session host'},$in{refurl},$in{browser},
		   $in{shipping},$in{tax}, $in{ecommerce}, $in{securitytype},
		   $shipAddress,$pi);
}

print "<PRE>\n" if $in{debug} > 0;
my $req  =
Request::new($in{csp},$in{sdkversion},$in{sdktype},$in{cspmid},$in{password}
,$obj);
print $req->toString  if $in{debug} > 0;

alarm $timeout;
my $res  = $reqManager->submit($req);
alarm 0;

print $res->toString if $in{debug} > 0;
print "</PRE>\n" if $in{debug} > 0;


#::logDebug(qq{surepay call: $exe $server $port "$string" |});
    open(CONNECT, qq{$exe $server $port "$string" |})
        or die "can't fork: $!\n";
    local($/);
    my $result = <CONNECT>;
    close CONNECT;

    my $decline = $?;

#::logDebug(qq{surepay decline=$decline result: $result});

    my %result_map = ( qw/

            MStatus               status
            pop.status            status
            MErrMsg               failureMSG
            pop.error-message     failureMSG
            order-id              tid
            pop.order-id          tid
            pop.auth-code         authCode

    /
    );

	my $ores = $res->getFirstResponse;
$pres = ref $ores;
$failure    = $ores->getFailure;        # true/false
$failureMsg = $ores->getFailureMsg;     # message if failure=true
if ($pres eq 'AuthResponse')
{
  $status   = $ores->getAuthStatus;     # status  if failure=false
  $authCode = $ores->getAuthCode;       # authorization code if transaction
approved
  $avs      = $ores->getAVS;            # avs
  $cvv2result = $ores->getcvv2result;	# CVV2 result
  $tid      = $ores->getTransactionID;  # transaction id
  $status ||= 'ERROR';
  $status  .= ": " . $failureMsg if $failure eq 'true';
}

    my %result = split /[&=]/, $result;

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

    $Vend::Session->{cybercash_result} =
    $Vend::Session->{payment_result} = \%result;

    delete $Vend::Session->{cybercash_error};
    delete $Vend::Session->{payment_error};

    if ($decline) {
        $decline = $decline >> 8;
        $result{'pop.status'} =
        $result{'MStatus'} = 'failed';

        $Vend::Session->{cybercash_error}   =
            $Vend::Session->{payment_error} = $result{failureMSG};

		my $msg = errmsg("Surepay error: %s %s. Please call in your order or try
again.",
			$result{status} ,
			$result{failureMSG},
		);

		$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->{cybercash_error}   =
            $Vend::Session->{payment_error} = $result{failureMSG};
    }

#::logDebug(qq{surepay decline=$decline result: } . ::uneval( \%result));

    return %result;
}
EOS