Sagepay错误5068:不支持加密方法(从2.22升级到3.00)



我已经查看了Sagepay协议从2.22升级到3.00的其他问题的答案,包括我自己之前问题的答案。

我正在尝试将加密方法从Xor更新为AES,以便3.00协议可以工作,但到目前为止,我一直被Sagepay错误5068卡住:该协议不支持加密方法。我公司的三个需要更新的网站都基于JShop电子商务平台,该平台已经非常过时,不再提供支持。

我已经实现了两个作为答案给出的解决方案,其中一个来自他们网站上的Sagepay php文档,但我仍然收到这个错误。

我很感激你能告诉我哪里出了问题。

我已经联系了Sagepay,但他们没有太多帮助,之前曾指导我在这里或他们的合作伙伴页面。

Protx(Sagepay)文件:

    <?php

    function startProcessor($orderNumber) {
        global $dbA,$orderArray,$jssStoreWebDirHTTP,$jssStoreWebDirHTTPS,$cartMain;

        $callBack = "$jssStoreWebDirHTTPS"."gateways/response/protx.php";

        $cDetails = returnCurrencyDetails($orderArray["currencyID"]);

        $gatewayOptions = retrieveGatewayOptions("PROTX");
        switch ($gatewayOptions["testMode"]) {
            case "S":
                $myAction = "https://test.sagepay.com/Simulator/VSPFormGateway.asp";
                break;
            case "Y":
                $myAction = "https://test.sagepay.com/gateway/service/vspform-register.vsp";
                break;
            case "N":
                $myAction = "https://live.sagepay.com/gateway/service/vspform-register.vsp";
                break;
        }
        $myVendor = $gatewayOptions["vendor"];
        $myEncryptionPassword = $gatewayOptions["encryptionPassword"];

        $billingAddress  = $orderArray["address1"]."n";
        if ($orderArray["address2"] != "") {
            $billingAddress .= $orderArray["address2"]."n";
        }
        $billingAddress .= $orderArray["town"]."n";
        $billingAddress .= $orderArray["county"]."n";
        $billingAddress .= $orderArray["country"];

        $deliveryAddress  = $orderArray["deliveryAddress1"]."n";
        if ($orderArray["deliveryAddress2"] != "") {
            $deliveryAddress .= $orderArray["deliveryAddress2"]."n";
        }
        $deliveryAddress .= $orderArray["deliveryTown"]."n";
        $deliveryAddress .= $orderArray["deliveryCounty"]."n";
        $deliveryAddress .= $orderArray["deliveryCountry"];


        $crypt = "VendorTxCode=$orderNumber";
        $crypt .= "&Amount=".number_format($orderArray["orderTotal"],$cDetails["decimals"],'.','');
        $crypt .= "&Currency=".@$cDetails["code"];
        $crypt .= "&Description=".$gatewayOptions["description"];
        $crypt .= "&SuccessURL=$callBack?xOid=$orderNumber&xRn=".$orderArray["randID"];
        $crypt .= "&FailureURL=$callBack?xOid=$orderNumber&xRn=".$orderArray["randID"];
        $crypt .= "&BillingSurname=".$orderArray["surname"];
        $crypt .= "&BillingFirstnames=".$orderArray["forename"];
        $crypt .= "&BillingAddress1=".$orderArray["address1"];
        $crypt .= "&BillingCity=".$orderArray["town"];
        $crypt .= "&BillingPostCode=".preg_replace("/[^s-a-zA-Z0-9]/", "", $orderArray["postcode"]);
        $crypt .= "&BillingCountry=".$orderArray["country"];
        $crypt .= "&DeliverySurname=".$orderArray["surname"];
        $crypt .= "&DeliveryFirstnames=".$orderArray["forename"];
    if ($orderArray["deliveryPostcode"] != "") {
        $crypt .= "&DeliveryAddress1=".$orderArray["deliveryAddress1"];
        $crypt .= "&DeliveryCity=".$orderArray["deliveryTown"];
        $crypt .= "&DeliveryPostCode=".preg_replace("/[^s-a-zA-Z0-9]/", "", $orderArray["deliveryPostcode"]);
        $crypt .= "&DeliveryCountry=".$orderArray["deliveryCountry"]; }
    else {
        $crypt .= "&DeliveryAddress1=".$orderArray["address1"];
        $crypt .= "&DeliveryCity=".$orderArray["town"];
        $crypt .= "&DeliveryPostCode=".preg_replace("/[^s-a-zA-Z0-9]/", "", $orderArray["postcode"]);
        $crypt .= "&DeliveryCountry=".$orderArray["country"]; }
        $crypt .= "&BillingPhone=".preg_replace("/[^sa-zA-Z0-9]/", "", $orderArray["telephone"]);
        if ($gatewayOptions["sendEmail"] == 1) {
        $crypt .= "&CustomerEmail=".$orderArray["email"]; }

        $crypt .= "&VendorEmail=".$gatewayOptions["vendorEmail"];
        $crypt .= "&ApplyAVSCV2=".$gatewayOptions["cvvCheck"];
        $crypt .= "&Apply3dSecure=".$gatewayOptions["3DSecure"];


        $crypt = base64_encode(encryptAes($crypt, $myEncryptionPassword));
        $tpl = createTSysObject(templatesCreatePath($cartMain["templateSet"]),"gatewaytransfer.html",$requiredVars,0);

        $gArray["method"] = "POST";
        $gArray["action"] = $myAction;
        $gArray["fields"][] = array("name"=>"VPSProtocol","value"=>"3.00");
        $gArray["fields"][] = array("name"=>"Vendor","value"=>$myVendor);
        $gArray["fields"][] = array("name"=>"TxType","value"=>$gatewayOptions["txType"]);
        $gArray["fields"][] = array("name"=>"Crypt","value"=>$crypt);

        $mArray = $gArray;

        $gArray["process"] = "document.automaticForm.submit();";

        $tpl->addVariable("shop",templateVarsShopRetrieve());
        $tpl->addVariable("labels",templateVarsLabelsRetrieve());

        $tpl->addVariable("automaticForm",$gArray);
        $tpl->addVariable("manualForm",$mArray);
        $tpl->showPage();
    }
    function addPKCS5Padding($input)
    {
         $blockSize = 16;
         $padd = "";
         $length = $blockSize - (strlen($input) % $blockSize);
         for ($i = 1; $i <= $length; $i++)
    {
         $padd .= chr($length);
    }
         return $input . $padd;
    }
    function removePKCS5Padding($input)
    {
        $blockSize = 16;
        $padChar = ord($input[strlen($input) - 1]);
        $unpadded = substr($input, 0, (-1) * $padChar);
        return $unpadded;
    }

    function encryptAes($string, $key)
    {
        $string = addPKCS5Padding($string);
        $crypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $string, MCRYPT_MODE_CBC, $key);
        return  strtoupper(bin2hex($crypt));
    }

    function decryptAes($strIn, $myEncryptionPassword)
    {
    #Sagepay specific - remove the '@'
    $strIn = substr($strIn,1);
        $strInitVector = $myEncryptionPassword;
        $strIn = pack('H*', $hex);
        $string = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $myEncryptionPassword, $strIn, MCRYPT_MODE_CBC,$strInitVector);
        return removePKCS5Padding($string);
    }
?>

响应文件:

 <?php
    define("IN_JSHOP", TRUE);
    include("../../static/config.php");
    include("../../routines/dbAccess_".$databaseType.".php");
    include("../../routines/tSys.php");
    include("../../routines/general.php");
    include("../../routines/stockControl.php");
    include("../../routines/emailOutput.php");
    require_once 'SagepayUtil.php';

    dbConnect($dbA);

    $orderID = makeSafe(getFORM("xOid"));
    $newOrderID = $orderID;
    $randID = makeSafe(getFORM("xRn"));
    $crypt = makeSafe(getFORM("crypt"));

    $gatewayOptions = retrieveGatewayOptions("PROTX");

    $orderID = makeInteger($orderID) - retrieveOption("orderNumberOffset");

    $result =  $dbA->query("select * from $tableOrdersHeaders where orderID=$orderID and randID='$randID'");
    if ($dbA->count($result) == 0 || $crypt=="") {
        doRedirect_JavaScript($jssStoreWebDirHTTP."index.php");
        exit;
    }
    $orderArray = $dbA->fetch($result);
    $ccResult = $dbA->query("select * from $tablePaymentOptions where paymentID=".$orderArray["paymentID"]);
    $poRecord = $dbA->fetch($ccResult);
    $paidStatus = $poRecord["statusID"];

    $crypt = str_replace(" ","+",$crypt);
    //$crypt = protx_simpleXor(base64_decode($crypt),$gatewayOptions["encryptionPassword"]);
    $crypt = decryptAes(base64_decode($crypt), $gatewayOptions["encryptionPassword"]);

    $nameValues = explode("&",$crypt);
    $resultCode = "";
    for ($f = 0; $f < count($nameValues); $f++) {
        $thisCode = explode("=",$nameValues[$f]);
        $resultCode[$thisCode[0]] = $thisCode[1];
    }

    if ($resultCode["VendorTxCode"] != $newOrderID) {
        doRedirect_JavaScript($jssStoreWebDirHTTP."index.php");
        exit;
    }

    $authResponse = "&Status Result=".$resultCode["Status"]."&AVS/CV2 Check=".@$resultCode["AVSCV2"]."&Address Result=".@$resultCode["AddressResult"]."&Postcode Result=".@$resultCode["PostCodeResult"]."&CV2 Result=".@$resultCode["CV2Result"]."&3d Secure Status=".@$resultCode["3DSecureStatus"];

    $randID = $orderArray["randID"];
    if ($orderArray["status"] != $paidStatus) {
            $dt=date("YmdHis",createOffsetTime());
            switch ($resultCode["Status"]) {
                case "OK":
                case "AUTHENTICATED":
                case "REGISTERED":
                    $authResponse="Gateway=Sage Pay&Authorisation Code=".$resultCode["TxAuthNo"]."&Sage Pay Transaction ID=".$resultCode["VPSTxId"]."&Status=Payment Confirmed".$authResponse;
                    $dbA->query("update $tableOrdersHeaders set status=$paidStatus, authInfo="$authResponse", paymentDate="$dt" where orderID=$orderID");
                    $orderArray["status"] = $paidStatus;
                    //ok, this is where we should do the stock control then.
                    include("process/paidProcessList.php");
                    doRedirect_JavaScript($jssStoreWebDirHTTPS."process.php?xOid=$newOrderID&xRn=$randID");
                    break;
                case "REJECTED":
                    $authResponse="Gateway=Sage Pay&Status=Payment Rejected Due To Rules".$authResponse;
                    $dbA->query("update $tableOrdersHeaders set status=3, authInfo="$authResponse", paymentDate="$dt" where orderID=$orderID");
                    include("process/failProcessList.php");
                    doRedirect_JavaScript($jssStoreWebDirHTTPS."process.php?xOid=$newOrderID&xRn=$randID");
                    break;
                default:
                    if ($orderArray["status"] == 1) {
                        $authResponse="Gateway=Sage Pay&Status=Payment Failed".$authResponse;
                        $dbA->query("update $tableOrdersHeaders set status=3, authInfo="$authResponse", paymentDate="$dt" where orderID=$orderID");
                        include("process/failProcessList.php");
                }
                    doRedirect_JavaScript($jssStoreWebDirHTTPS."process.php?xOid=$newOrderID&xRn=$randID");
                    break;
            }
    } else {
            doRedirect_JavaScript($jssStoreWebDirHTTPS."process.php?xOid=$newOrderID&xRn=$randID");
    }

    function addPKCS5Padding($input)
    {
         $blockSize = 16;
         $padd = "";
         $length = $blockSize - (strlen($input) % $blockSize);
         for ($i = 1; $i <= $length; $i++)
    {
         $padd .= chr($length);
    }
         return $input . $padd;
    }
    function removePKCS5Padding($input)
    {
        $blockSize = 16;
        $padChar = ord($input[strlen($input) - 1]);
        $unpadded = substr($input, 0, (-1) * $padChar);
        return $unpadded;
    }

    function encryptAes($string, $key)
    {
        $string = addPKCS5Padding($string);
        $crypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $string, MCRYPT_MODE_CBC, $key);
        return  strtoupper(bin2hex($crypt));
    }

    function decryptAes($strIn, $myEncryptionPassword)
    {
    #Sagepay specific - remove the '@'
    $strIn = substr($strIn,1);
        $strInitVector = $myEncryptionPassword;
        $strIn = pack('H*', $hex);
        $string = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $myEncryptionPassword, $strIn, MCRYPT_MODE_CBC,$strInitVector);
        return removePKCS5Padding($string);
    }
?>

确保先备份文件,然后更改此行:

$crypt =base64_encode(encryptAes($crypt, $myEncryptionPassword));

$crypt = "@".encryptAes($crypt, $myEncryptionPassword);

和:

$crypt = decryptAes(base64_decode($crypt), $gatewayOptions["encryptionPassword"]);

收件人:

$crypt = decryptAes($crypt, $gatewayOptions["encryptionPassword"]);

查看了解密位后,"@"的删除已经存在。我不是一个PHP的家伙,所以这可能不是完美的!

在不使用base64加密的情况下尝试一下,并确保在编码时将'@'添加到密码的开头(在解密事务结果时将其从密码中删除)。

相关内容

最新更新