PayPal IPN 已验证握手但 IPN 无效

Posted

技术标签:

【中文标题】PayPal IPN 已验证握手但 IPN 无效【英文标题】:PayPal IPN verified handshake but Invalid IPN 【发布时间】:2017-02-17 21:06:49 【问题描述】:

我在使用“旧”PayPal IPN 代码时遇到问题。 当我使用 PayPal IPN 模拟器时,我收到消息 IPN was sent and the handshake was verified.,但在我的日志中我可以看到 IPN 消息是 Invalid

我已经检查了以下内容:

服务器支持 SHA2 并拥有 SHA2 SSL 证书 已为商家帐户激活 IPN IPN URL 正确 PayPal 按钮语言编码设置为 UTF-8

我使用的代码

        define("DEBUG", true);
        define("USE_SANDBOX", 1);

        $raw_post_data = file_get_contents('php://input');
        $raw_post_array = explode('&', $raw_post_data);
        $myPost = array();

        foreach ($raw_post_array as $keyval) 
            $keyval = explode ('=', $keyval);
            if (count($keyval) == 2)
                $myPost[$keyval[0]] = urldecode($keyval[1]);
        

        $req = 'cmd=_notify-validate';

        if(function_exists('get_magic_quotes_gpc')) 
            $get_magic_quotes_exists = true;
        

        foreach ($myPost as $key => $value) 
            if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) 
                $value = urlencode(stripslashes($value));
             else 
                $value = urlencode($value);
            
            $req .= "&$key=$value";
        

        if(USE_SANDBOX == true) 
            $paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr";
         else 
            $paypal_url = "https://www.paypal.com/cgi-bin/webscr";
        

        $ch = curl_init($paypal_url);

        if ($ch == FALSE) 
            return FALSE;
        

        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
        curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);

        if(DEBUG == true) 
            curl_setopt($ch, CURLOPT_HEADER, 1);
            curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
        

        //si depronto se usa proxy eliminar los //
        //curl_setopt($ch, CURLOPT_PROXY, $proxy);
        //curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);

        //se coloca el tiempo maximo que se demora este script
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));

        $res = curl_exec($ch);

        if (curl_errno($ch) != 0) // cURL error
            
            if(DEBUG == true)  
                error_log(date('[Y-m-d H:i e] '). "No se puede conectar a PayPal para validar el IPN: " . curl_error($ch) . PHP_EOL, 3, LOG_FILE);
            
            curl_close($ch);
            exit;
         else 
                if(DEBUG == true) 
                    error_log(date('[Y-m-d H:i e] '). "HTTP response:". curl_getinfo($ch, CURLINFO_HEADER_OUT) ." over IPN: $req" . PHP_EOL, 3, LOG_FILE);
                    error_log(date('[Y-m-d H:i e] '). "HTTP respnse a la validacion: $res" . PHP_EOL, 3, LOG_FILE);
                
                curl_close($ch);
        

        $tokens = explode("\r\n\r\n", trim($res));
        $res = trim(end($tokens));

        if (strcmp ($res, "VERIFIED") == 0) 
            //$item_name = $_POST['item_name'];
            //$item_number = $_POST['item_number'];
            //$payment_status = $_POST['payment_status'];
            //$payment_amount = $_POST['mc_gross'];
            //$payment_currency = $_POST['mc_currency'];
            //$txn_id = $_POST['txn_id'];
            //$receiver_email = $_POST['receiver_email'];
            //$payer_email = $_POST['payer_email'];

            $txt = fopen("paypalLog.txt", "a+");

            ob_start();
            var_dump($_POST);
            $result = ob_get_clean();

            fputs($txt, $result);
            @fclose($fp);
            //fin

            // crea el LOG
            if(DEBUG == true) 
                error_log(date('[Y-m-d H:i e] '). "IPN Verification: $req ". PHP_EOL, 3, LOG_FILE);
            
         else if (strcmp ($res, "INVALID") == 0) 
            if(DEBUG == true) 
                error_log(date('[Y-m-d H:i e] '). "IPN Validation: $req" . PHP_EOL, 3, LOG_FILE);
            
        

日志文件

[2016-10-09 09:49 Europe/Berlin] HTTP response:POST /cgi-bin/webscr HTTP/1.1

Host: www.sandbox.paypal.com

Accept: */*

Connection: Close

Content-Length: 938

Content-Type: application/x-www-form-urlencoded



 over IPN: cmd=_notify-validate&payment_type=instant&payment_date=Sun+Oct+09+2016+09%3A43%3A26+GMT+0200+%28Mitteleurop%E4ische+Sommerzeit%29&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer%40paypalsandbox.com&payer_id=TESTBUYERID01&address_name=John+Smith&address_country=United+States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San+Jose&address_street=123+any+street&business=seller%40paypalsandbox.com&receiver_email=seller%40paypalsandbox.com&receiver_id=seller%40paypalsandbox.com&residence_country=US&item_name1=something&item_number1=AK-1234&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&mc_gross_1=12.34&mc_handling=2.06&mc_handling1=1.67&mc_shipping=3.02&mc_shipping1=1.02&txn_type=cart&txn_id=911158411&notify_version=2.1&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=AFcWxV21C7fd0v3bYYYRCps-s-rl31Abb2NUi36uV.Fg6Hd45FbjL
[2016-10-09 09:49 Europe/Berlin] HTTP respnse a la validacion: HTTP/1.1 200 OK

Date: Sun, 09 Oct 2016 07:49:50 GMT

Server: Apache

X-Frame-Options: SAMEORIGIN

Set-Cookie: c9MWDuvPtT9GIMyPc3jwol1VSlO=0UL2ykO4iVuB1THqg4V_A1yKQujjM6s4YtickDFcjh59dGheER5gsdGdmZZCbEMgaMmN3I_R2w7FGJZfAT-b-iu--TRNYPmz3sNcg65cP4NX_3N8vLL5YRk_wP4ng3sV9Z3McJOb8ZG0zTMTQXFAqNee8dS5HvEPSBGxiANK5LjhfcvpbotfTs4OUc-IpsuB3DouU2MaWlABlVdH733KqBHIIPLGrxy9USjIiaf5DS3KhJ-i0RwH3PVy0DOAr0_dWjahWdwr9ulHq11ZhUpD8S6lntr6iZtHNNGZblK_SH-RAA__EZe29-pw1HQAqu-R5-VY0ff9-oEgHfWUB8DzzsAg3dtF2us-ucVhShoSDJcm_ScOgU62vaFkuC1BLEbDJgs0NG9U3NngCZQo59X_7MrfOON8ofxREAKK1yaqdxpI9gWFz1Jrzcbe8KzW; domain=.paypal.com; path=/; Secure; HttpOnly

Set-Cookie: cookie_check=yes; expires=Wed, 07-Oct-2026 07:49:51 GMT; domain=.paypal.com; path=/; Secure; HttpOnly

Set-Cookie: navcmd=_notify-validate; domain=.paypal.com; path=/; Secure; HttpOnly

Set-Cookie: navlns=0.0; expires=Tue, 09-Oct-2018 07:49:51 GMT; domain=.paypal.com; path=/; Secure; HttpOnly

Set-Cookie: Apache=10.42.101.60.1356986390240295; path=/; expires=Tue, 02-Oct-46 07:49:50 GMT

Vary: Accept-Encoding,User-Agent

Connection: close

HTTP_X_PP_AZ_LOCATOR: sandbox.slc

Paypal-Debug-Id: beb3b1rt5fd1

Set-Cookie: X-PP-SILOVER=name%3DSANDBOX3.WEB.1%26silo_version%3D1880%26app%3Dappdispatcher%26TIME%3D2666985815%26HTTP_X_PP_AZ_LOCATOR%3Dsandbox.slc; Expires=Sun, 09 Oct 2016 08:19:51 GMT; domain=.paypal.com; path=/; Secure; HttpOnly

Set-Cookie: X-PP-SILOVER=; Expires=Thu, 01 Jan 1970 00:00:01 GMT

Strict-Transport-Security: max-age=14400

Transfer-Encoding: chunked

Content-Type: text/html; charset=UTF-8



INVALID
[2016-10-09 09:49 Europe/Berlin] IPN Invalido: cmd=_notify-validate&payment_type=instant&payment_date=Sun+Oct+09+2016+09%3A43%3A26+GMT+0200+%28Mitteleurop%E4ische+Sommerzeit%29&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer%40paypalsandbox.com&payer_id=TESTBUYERID01&address_name=John+Smith&address_country=United+States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San+Jose&address_street=123+any+street&business=seller%40paypalsandbox.com&receiver_email=seller%40paypalsandbox.com&receiver_id=seller%40paypalsandbox.com&residence_country=US&item_name1=something&item_number1=AK-1234&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&mc_gross_1=12.34&mc_handling=2.06&mc_handling1=1.67&mc_shipping=3.02&mc_shipping1=1.02&txn_type=cart&txn_id=911158411&notify_version=2.1&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=AFcWxV21C7fd0v3bYYYRCps-s-rl31Abb2NUi36uV.Fg6Hd45FbjL

【问题讨论】:

【参考方案1】:

终于解决了这个问题。使用 PayPal 沙盒时需要注意以下几点:

当您使用 PayPal IPN 模拟器时,您得到的回复将始终是Invalid。 PayPal 沙盒 IPN 响应可能会延迟几分钟(不仅仅是几秒钟),因此请务必稍等片刻,看看是否有响应传入。 由于某些原因,如果 PayPal Sandbox 帐户与真实 PayPal 帐户具有完全相同的邮件地址,则 PayPal Sandbox 不会提供响应。

通过考虑上述事项,我已经解决了我的问题。 希望这对其他人也有帮助。

【讨论】:

【参考方案2】:

您提供的代码表明您正在使用 Sanbox 进行调试。因此,您必须检查 Paypal 表单操作是否具有 sanbox 链接,并且您的企业帐户也属于 sanbox。

如果您想使用实际的 paypal 帐户,只需将第二行更改为 define("USE_SANDBOX", 0);

【讨论】:

感谢您的回复,但这不是问题所在。每个链接和连接的 PayPal 账户都是沙盒账户,仅供测试使用。

以上是关于PayPal IPN 已验证握手但 IPN 无效的主要内容,如果未能解决你的问题,请参考以下文章

PayPal IPN 模拟器:IPN 未发送,握手未验证。请查看您的信息

接收 PayPal IPN 时不获取任何参数

Paypal IPN 已验证,但 Paypal 不断重试

符合规范,但仍然:未发送 IPN,未验证握手。请查看您的信息

IPN未发送,握手未验证

Paypal ipn 未验证:无效