Sage Pay v3.00 Integration

筅森魡賤 提交于 2019-11-29 13:09:16

You could try dropping the following functions into the script, then swapping out simpleXor for encryptAes. Make sure that you also add an '@' symbol as the first character of the crypt string (and strip it off when decoding the response from Sage Pay).

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, $password)
{
    $strInitVector = $password;
    $strIn = pack('H*', $hex);
    $string = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $password, $strIn, MCRYPT_MODE_CBC,$strInitVector);
    return removePKCS5Padding($string);
}
Rik Blacow

You could try this. I can't test it, so let me know how you get on.

<?php

    if ( !defined('IN_CSCART') ) { die('Access denied'); }

    if (defined('PAYMENT_NOTIFICATION')) {  

    // Get the password
    $payment_id=db_get_field("SELECT $db_tables[payments].payment_id FROM $db_tables[payments] LEFT JOIN $db_tables[payment_processors] ON $db_tables

    [payment_processors].processor_id = $db_tables[payments].processor_id WHERE $db_tables[payment_processors].processor_script='protx_form.php'");
    $processor_data = fn_get_payment_method_data($payment_id);


    #Rik added:
    $result = "&".decryptAes($_REQUEST['crypt'], $processor_data["params"]["password"])."&";

    #$result = "&".simpleXor(base64Decode($_REQUEST['crypt']), $processor_data["params"]["password"])."&";

    preg_match("/Status=(.+)&/U", $result, $a);
    if(trim($a[1]) == "OK") {
        $pp_response['order_status'] = ($processor_data["params"]["transaction_type"] == 'PAYMENT') ? 'P' : 'O';
        preg_match("/TxAuthNo=(.+)&/U", $result, $authno);
        $pp_response["reason_text"] = "AuthNo: ".$authno[1];
        preg_match("/VPSTxID={(.+)}/U", $result, $transaction_id);
        $pp_response["transaction_id"] = @$transaction_id[1];
    } else {
        $pp_response['order_status'] = 'F';
        preg_match("/StatusDetail=(.+)&/U", $result, $stat);
        $pp_response["reason_text"] = "Status: ".trim($stat[1])." (".trim($a[1]).") ";
    }
    preg_match("/AVSCV2=(.*)&/U", $result, $avs);
    if(!empty($avs[1])) {
        $pp_response['descr_avs'] = $avs[1];
    }
    include $payment_files_dir.'payment_cc_complete.php';
    fn_order_placement_routines($order_id);

    }
    else
    {
        global $http_location, $b_order, $_total_back;

        $post_address = ($processor_data['params']['testmode'] != "N") ? "https://test.sagepay.com/gateway/service/vspform-register.vsp" : 

    "https://live.sagepay.com/gateway/service/vspform-register.vsp";

        $post["VPSProtocol"] = "2.23";
        $post["TxType"] = $processor_data["params"]["transaction_type"];
        $post["Vendor"] = htmlspecialchars($processor_data["params"]["vendor"]);

        // Form Cart products
        $strings = 0;
        if (is_array($cart['products'])) {
            $strings += count($cart['products']);
        }

        if (!empty($cart['products'])) {
            foreach ($cart['products'] as $v) {
                $_product = db_get_field("SELECT product FROM $db_tables[product_descriptions] WHERE product_id='$v[product_id]' AND lang_code='$cart_language'");
                $products_string .= ":".str_replace(":", " ", $_product).":".$v['amount'].":".fn_format_price($v['subtotal']/$v['amount']).":::".fn_format_price($v

    ['subtotal']);
            }
        }
        if (!empty($cart['payment_surcharge'])) {
            $products_string .= ":Payment surcharge:---:---:---:---:".fn_format_price($cart['payment_surcharge']);
            $strings ++;
        }
        if (!empty($cart['shipping_cost'])) {
            $products_string .= ":Shipping cost:---:---:---:---:".fn_format_price($cart['shipping_cost']);
            $strings ++;
        }
        $post_encrypted .= "Basket=".$strings.$products_string;


    #Rik added:

     $post["Crypt"] = "@".encryptAes($post_encrypted, $processor_data["params"]["password"]);

    #    $post["Crypt"] = base64_encode(simpleXor($post_encrypted, $processor_data["params"]["password"]));
    #    $post["Crypt"] = htmlspecialchars($post["Crypt"]);

        $msg = fn_get_lang_var('text_cc_processor_connection');
        $msg = str_replace('[processor]', 'Protx Server', $msg);

    echo <<<EOT
    <html>
    <body onLoad="document.process.submit();">
    <form action="{$post_address}" method="POST" name="process">
    <INPUT type=hidden name="VPSProtocol" value="{$post['VPSProtocol']}">
    <INPUT type=hidden name="Vendor" value="{$post['Vendor']}">
    <INPUT type=hidden name="TxType" value="{$post['TxType']}">
    <INPUT type=hidden name="Crypt" value="{$post['Crypt']}">
    <p>
    <div align=center>{$msg}</div>
    </p>
    </body>
    </html>
    EOT;
    }

    exit;

    //
    // ---------------- Additional functions ------------
    //
    function simpleXor($InString, $Key) {
    $KeyList = array();
    $output = "";

    for($i = 0; $i < strlen($Key); $i++){
        $KeyList[$i] = ord(substr($Key, $i, 1));
    }
    for($i = 0; $i < strlen($InString); $i++) {
        $output.= chr(ord(substr($InString, $i, 1)) ^ ($KeyList[$i % strlen($Key)]));
    }

    return $output;
    }

    function base64Decode($scrambled) {
    // Initialise output variable
    $output = "";
    // Fix plus to space conversion issue
    $scrambled = str_replace(" ","+",$scrambled);
    // Do encoding
    $output = base64_decode($scrambled);
    // Return the result
    return $output;
    }


    #added by Rik

    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, $password)
    {

    #Sagepay specific - remove the '@'
    $strIn = substr($strIn,1)

        $strInitVector = $password;
        $strIn = pack('H*', $hex);
        $string = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $password, $strIn, MCRYPT_MODE_CBC,$strInitVector);
        return removePKCS5Padding($string);
    }

    ?>
/*First build your data. */

$data = 'variableA='.$this->variableA;
$data .= '&variableB='.$this->variableB;
...
$data .= '&variableZ='.$this->variableZ;

/** Encript data */
$dataEncrip = $this->encData($data);


/** function to Encrypt *//
public function encData($data){
  $data = $this->pkcs5_pad( $data, 16);
  $dataEnc = "@".bin2hex( mcrypt_encrypt( MCRYPT_RIJNDAEL_128,
                                          $this->passwordToEncript,
                                          $data,
                                          MCRYPT_MODE_CBC,
                                          $this->getPasswordToEncrypt()));
  return $dataEnc;                                                           
}

 /** Pkcs5_pad */
public function pkcs5_pad( $data, $blocksize ){
    $pad = $blocksize - (strlen( $data ) % $blocksize);
    return $data . str_repeat( chr( $pad ), $pad );
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!