php - 无法将我的 PayPal IPN 脚本从 http 1.0 转换为 1.1

标签 php paypal paypal-ipn

我的脚本目前已经上线,我有一个有问题的沙箱来测试我的修改,这激怒了我的一些客户。我最好在现场测试。

PayPal 发了一封电子邮件警告我们,并不断提醒我跳到 1.1,但自 6 月以来,我一直运气不好,尝试了各种组合并咨询了各种平台以寻求建议。

下面是我当前的 PayPal.php 代码,它链接到我的网站所需的许多类。

我尝试了很多编码组合,从注释行中可以明显看出这一点。

他们似乎无法工作,我的选择已经用完了。

有好心人能解决这个问题吗?或者告诉我出了什么问题?

IPN 总是回复我无效的响应或错误,但在 http 1.0 中一切都很好而且花花公子......

<?php

include_once(PayPalConfig::$params[PayPalConfig::$PAYPAL_PATH]."/PayPalSettings.php");
include_once(PayPalConfig::$params[PayPalConfig::$PAYPAL_PATH]."/PayPalConstants.php");

class PayPal
{       
    private $settings;
    private $socket;    
    private $data;

    /**
     * Constructor
     *
     * @param PayPalSettings $settings
     */
    public function __construct(PayPalSettings $settings, array $data)
    {
        // Store the setting which has been passed in
        $this->settings = $settings;

        $this->data = $data;
    }

    /**
     * Enter description here...
     *
     * @return unknown
     */
    function connectToPayPal()
    {
        // Store the URL string
        //$url = $this->settings->paypalURL;
        $url = "ssl://ipnpb.paypal.com";

        // Open a socket with paypal and send all the POSTed info as our request        
        //ORIGINAL
        //$this->socket = fsockopen ($url, 80, $errno, $errstr, 30);
        //AMENDED - 30/06/2013
        $this->socket = fsockopen ($url, 443, $errno, $errstr, 30);
        //FAILED AGAIN
        //$this->socket = fsockopen ($url, 443, $errno, $errstr, 30);

        return $this->socket;
    }

    /**
     * Enter description here...
     *
     * @return unknown
     */
    function createDataForPayPal()
    {
        // create a request to paypal to verify the data we have recieved
        $req = 'cmd=_notify-validate';

        // Build request string from each value in the $_POST
        foreach ($this->data as $key => $value)
        {
            //Original
            //$value = urlencode(stripslashes($value));
            //AMENDED - 30/08/2013
            $value = urlencode($value);
            $req .= "&$key=$value";
        }

        return $req;
    }

    /**
     * Enter description here...
     *
     * @param unknown_type $fp
     * @param unknown_type $requestString
     * @return unknown
     */
    function verifyWithPaypal($fp, $requestString)
    {       
        /* OLD CHUNK
        // post back to PayPal system to validate
        $header = "POST /cgi-bin/webscr HTTP/1.1\r\n";
        //try this NEXT? - Not tried - 20/08/13
        //$header = "POST cgi-bin/webscr HTTP/1.1\r\n";
        $header .= "Host: ipnpb.paypal.com\r\n";
        $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
        //$header .= "Content-Length: " . strlen($requestString) . "\r\n";
        $header .= "Content-Length: " . strlen($requestString) . "\r\n\r\n";
        $header .= "Connection: close\r\n\r\n";
        */

        // post back to PayPal system to validate
        $header = "POST /cgi-bin/webscr HTTP/1.1\r\n";
        $header .= "Content-Length: " . strlen($requestString) . "\r\n";
        $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
        $header .= "Host: ipnpb.paypal.com\r\n";
        $header .= "Connection: close\r\n\r\n";     

        // If the send has failed, we just have to return false
        if (!$fp)
        {
            return PayPalConstants::$FAILED_TO_CONNECT;
        }
        else
        {
            // Paypal responded to our request. Store the respond
            //Original
            fputs ($fp, $header . $requestString);
            //Amended New Try Next
            //fputs ($fp, $header . $requestString . "\r\n\r\n");

            // Fetch respond string from PayPal

            while (!feof($fp))
            {
                $res = fgets ($fp, 1024);

                //Writes $res to LogFile
                //$logger->write($res); 

                // Determine if the transaction has been verified with PayPal
                if (strcmp (trim($res), "VERIFIED") == 0)
                {
                    return PayPalConstants::$VERIFIED;
                }
                else if (strcmp (trim($res), "INVALID") == 0)
                {
                    return PayPalConstants::$NOT_VERIFIED;
                }
            }

        }

        //return $res;
        return PayPalConstants::$NOT_VERIFIED;
    }

    /**
     * Return the payment status 
     *
     * @return string The payment status
     */
    function getPaymentStatus()
    {
        if ($this->socket)
        {
            return $this->data[self::$PAYMENT_STATUS];
        }
    }

    function massPayment(array $payee, $environment, $emailSubject, $receiverType, $bTest=false)
    {
        // Setup sending data               
        $currency = 'USD';
        $method = PayPalConstants::$MASS_PAYMENT;
        $nvpStr="&EMAILSUBJECT=$emailSubject&RECEIVERTYPE=$receiverType&CURRENCYCODE=$currency";

        // Encode the string
        foreach($payee as $i => $receiverData) {
            $receiverEmail = urlencode($receiverData['receiverEmail']);
            $amount = urlencode($receiverData['amount']);
            $uniqueID = urlencode($receiverData['uniqueID']);
            $note = urlencode($receiverData['note']);
            $nvpStr .= "&L_EMAIL$i=$receiverEmail&L_Amt$i=$amount&L_UNIQUEID$i=$uniqueID&L_NOTE$i=$note";
        }

        // Set end point
        if ($environment != "live")
        {
            $API_Endpoint = "https://api-3t.$environment.paypal.com/nvp";
        }
        else
        {
            // TODO: Live API endpoint set here
            $API_Endpoint = "https://api-3t.paypal.com/nvp";
        }

        $mode = PayPalConfig::$API;
        // What mode are we using the API?
        if ($bTest)
        {
            $mode = PayPalConfig::$API_TEST;
        }

        $API_Username = PayPalConfig::$params[$mode][PayPalConfig::$API_USERNAME];
        $API_Password = PayPalConfig::$params[$mode][PayPalConfig::$API_PASSWORD];
        $API_Sign     = PayPalConfig::$params[$mode][PayPalConfig::$API_SIGN];

        // Set the curl parameters.
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
        curl_setopt($ch, CURLOPT_VERBOSE, 1);

        // Turn off the server and peer verification (TrustManager Concept).
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);

        $version = urlencode('51.0');

        // Generate the request string
        $nvpreq = "METHOD=$method".
                  "&VERSION=$version".
                  "&PWD=$API_Password".
                  "&USER=$API_Username".
                  "&SIGNATURE=$API_Sign$nvpStr";


        // Set the request as a POST FIELD for curl.
        curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);

        // Get response from the server.
        $httpResponse = curl_exec($ch);

        if(!$httpResponse) {
            exit("$method failed: ".curl_error($ch).'('.curl_errno($ch).')');
        }

        // Extract the response details.
        $httpResponseAr = explode("&", $httpResponse);

        $httpParsedResponseAr = array();
        foreach ($httpResponseAr as $i => $value) {
            $tmpAr = explode("=", $value);
            if(sizeof($tmpAr) > 1) {
                $httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
            }
        }

        if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) {
            exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
        }

        return ($httpParsedResponseAr);

    }
}

?>

最佳答案

不知何故,直接修剪结果(而不是在比较之前)对我有用:

$res = fgets ($fp, 1024); $res = trim($res);

祝你好运

关于php - 无法将我的 PayPal IPN 脚本从 http 1.0 转换为 1.1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18719421/

相关文章:

php - 为不同的网络用户(管理员、客户)提供不同的菜单 View 以创建新帐户

php - 正确使用 mkdir()

php - 在 WKWebView 上从服务器读取 docx 文件

php - 使用个人账户的 Paypal 付款列表

grails - Paypal 不在沙盒中发送 IP 通知

php - ColdFusion 替代 cURL

node.js - 如何使用 Node SDK 制作用于接受付款的 Paypal 按钮?

php - 如果数据库列为空 symfony 2,则过滤数组

php - 当 session ID 已知但无法启动 session 时删除 session 变量

paypal - 在 PayPal IPN 模拟器中测试 HTTPS 响应服务器时出错