我正在尝试用PHP编写自己的类来进行Server / InFrame付款

I need some help I'm trying to write my own class in PHP for Server/InFrame payments. This is the class:

class SagePay {

    public $VPSProtocol = 3.00;
    public $TxType = "PAYMENT";
    public $Vendor = "************";
    public $VendorTxCode ;
    public $Amount = 11.75;
    public $Currency = "GBP";
    public $Description = "By Def";
    public $NotificationURL = NOTIFICATIONURL ;
    public $BillingSurname ;
    public $BillingFirstnames ;
    public $BillingAddress1 ;
    public $BillingCity ;
    public $BillingPostCode ;
    public $BillingCountry = "GB";
    public $DeliverySurname ;
    public $DeliveryFirstnames ;//= Fname Mname
    public $DeliveryAddress1 ;//= BillAddress Line 1
    public $DeliveryCity ;//= BillCity
    public $DeliveryPostCode ;//= W1A 1BL
    public $DeliveryCountry = "GB";
    public $StoreToken = 1;
    public $CustomerName ;//= Fname Mname Surname
    public $CustomerEMail ;//= customer@example.com
    public $VendorEMail ;//= 
    public $SendEMail =1;//= 0 1 е да прати и на двамата емайли
    public $eMailMessage ;//=  нещо се пише тука
    public $BillingAddress2 ;//= BillAddress Line 2
    public $BillingPhone ;//= 44 (0)7933 000 000
    public $ApplyAVSCV2 = 0;
    public $Apply3DSecure = 0;
    public $AllowGiftAid = 0;
    public $BillingAgreement = 1;
    public $DeliveryAddress2 ;//= BillAddress Line 2
    public $DeliveryPhone ;//= 44 (0)7933 000 000
    public $Profile = "LOW";
    public $AccountType = "E";
    protected $url = "https://test.sagepay.com/gateway/service/vspserver-register.vsp";// must be changet from test to live

    static protected $nonSensitiveRequestDataArray = array("VPSProtocol", "TxType", "Vendor", "VendorTxCode", "Amount","Currency", "Description");
    static protected $nonSensitiveResponseDataArray = array("VPSProtocol", "Status", "StatusDetail", "VPSTxId");

    function __construct() {
      define('SAGEPAY_SDK_PATH', dirname(__FILE__));
      $data = get_object_vars($this);
    }


    static public function requestPost($url,$data, $ttl = 30, $caCertPath = ''){


        set_time_limit(60);
        $output = array();
        $curlSession = curl_init();

        curl_setopt($curlSession, CURLOPT_URL, $url);
        curl_setopt($curlSession, CURLOPT_HEADER, 0);
        curl_setopt($curlSession, CURLOPT_POST, 1);
        curl_setopt($curlSession, CURLOPT_POSTFIELDS, self::arrayToQueryString($data));
        curl_setopt($curlSession, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curlSession, CURLOPT_TIMEOUT, $ttl);
        curl_setopt($curlSession, CURLOPT_SSL_VERIFYHOST, 2);

        if (!empty($caCertPath))
        {
            curl_setopt($curlSession, CURLOPT_SSL_VERIFYPEER, 1);
            curl_setopt($curlSession, CURLOPT_CAINFO, $caCertPath);
        } 
        else
        {
            curl_setopt($curlSession, CURLOPT_SSL_VERIFYPEER, 0);
        }

        $rawresponse = curl_exec($curlSession);
        if (curl_getinfo($curlSession, CURLINFO_HTTP_CODE) !== 200)
        {
            $output['Status'] = "FAIL";
            $output['StatusDetails'] = "Server Response: " . curl_getinfo($curlSession, CURLINFO_HTTP_CODE);
            $output['Response'] = $rawresponse;

            return $output;
        }
        if (curl_error($curlSession))
        {
            $output['Status'] = "FAIL";
            $output['StatusDetail'] = curl_error($curlSession);
            $output['Response'] = $rawresponse;
            return $output;
        }

        curl_close($curlSession);

        $requestForLog= self::arrayToQueryStringRemovingSensitiveData($data,self::$nonSensitiveRequestDataArray ) ; 
        $response = self::queryStringToArray($rawresponse, "
");
        $responseForLog= self::queryStringToArrayRemovingSensitiveData($rawresponse, "
", self::$nonSensitiveResponseDataArray );         

        self::log("Request:" . PHP_EOL . $requestForLog);

        $res = array_merge($output, $response);
        return $res;
    }
    protected static function arrayToQueryString(array $data, $delimiter = '&', $urlencoded = false){
        $queryString = '';
        $delimiterLength = strlen($delimiter);

        // Parse each value pairs and concate to query string
        foreach ($data as $name => $value)
        {   
            // Apply urlencode if it is required
            if ($urlencoded)
            {
                $value = urlencode($value);
            }
            $queryString .= $name . '=' . $value . $delimiter;
        }

        // remove the last delimiter
        return substr($queryString, 0, -1 * $delimiterLength);
    }
    protected static function arrayToQueryStringRemovingSensitiveData(array $data,array $nonSensitiveDataKey, $delimiter = '&', $urlencoded = false){
        $queryString = '';
        $delimiterLength = strlen($delimiter);

        // Parse each value pairs and concate to query string
        foreach ($data as $name => $value)
        {
           if (!in_array($name, $nonSensitiveDataKey)){
                $value=MASK_FOR_HIDDEN_FIELDS;
           }
           else if ($urlencoded){
                $value = urlencode($value);
           }
            // Apply urlencode if it is required

           $queryString .= $name . '=' . $value . $delimiter;
        }

        // remove the last delimiter
        return substr($queryString, 0, -1 * $delimiterLength);
    }
    protected static function queryStringToArray($data, $delimeter = "&"){
        // Explode query by delimiter
        $pairs = explode($delimeter, $data);
        $queryArray = array();

        // Explode pairs by "="
        foreach ($pairs as $pair)
        {
            $keyValue = explode('=', $pair);

            // Use first value as key
            $key = array_shift($keyValue);

            // Implode others as value for $key
            $queryArray[$key] = implode('=', $keyValue);
        }
        return $queryArray;
    }
    protected static function queryStringToArrayRemovingSensitiveData($data, $delimeter = "&", $nonSensitiveDataKey){  
        // Explode query by delimiter
        $pairs = explode($delimeter, $data);
        $queryArray = array();

        // Explode pairs by "="
        foreach ($pairs as $pair)
        {
            $keyValue = explode('=', $pair);
            // Use first value as key
            $key = array_shift($keyValue);
            if (in_array($key, $nonSensitiveDataKey)){
              $keyValue = explode('=', $pair);
            }
            else{
              $keyValue = array(MASK_FOR_HIDDEN_FIELDS);
            }
            // Implode others as value for $key
            $queryArray[$key] = implode('=', $keyValue);

        }
        return $queryArray;
    }
    protected static function log($message){
        return true;
    }
    public function createVendorTxCode(){
      $timestamp = time();
      $random_number = rand(0,32000)*rand(0,32000);
      return "{$timestamp}-{$random_number}";
    }
}

IFrame is created correctly. I fill everything properly in the IFrame and the result is:

HTTP Status Code:   500
HTTP Status Message:    The request was unsuccessful due to an unexpected condition encountered by the server.
Error Code :    5006
Error Description : Unable to redirect to Vendor's web site. The Vendor failed to provide a RedirectionURL.

Where in the demo of PHP is created and how to generate this RedirectionURL?

When your notificationURL receives the results post from Sage Pay, it needs to respond, providing the RedirectURL - this error usually occurs when Sage Pay are unable to reach the specified notificationURL, or there is no redirection URL returned.

I stopped GZIP compression and everithing is OK. Responses from SagePay taken with INPUT_POST