PayPal IPN 验证的问题



我的PayPal ipn 脚本遇到了一些问题:

    $req = 'cmd=_notify-validate';
    foreach ($_POST as $key => $value) {
        $value = urlencode(stripslashes($value));
        $req .= "&$key=$value";
    }
    // post back to PayPal system to validate
    $header = '';
    $header  = "POST /cgi-bin/webscr HTTP/1.1rn";            
    $header .= "Content-Type: application/x-www-form-urlencodedrn";
    $header .= "Host: www.paypal.comrn";
    $header .= "Connection: closern";
    $header .= "Content-Length: " . strlen($req) . "rnrn";
    $fp = fsockopen('ssl://www.paypal.com', 443, $errno, $errstr, 30);
    if (!$fp) {
    // HTTP ERROR
    } 
    else {
        fputs ($fp, $header . $req);
        $response = '';
        while (!feof($fp)) {
            $res = fgets ($fp, 1024);
            $res = trim($res);
            if (strpos($res,'VERIFIED') !== false) {
            }
            else {
                // not verified
            }
        }
    }

if (strpos($res,'VERIFIED') !== false)总是假的。这是$res返回的内容:

HTTP/1.1 200 OK
Server: Apache
X-Frame-Options: SAMEORIGIN
Strict-Transport-Security: max-age=14400
Strict-Transport-Security: max-age=14400
Content-Type: text/html; charset=UTF-8
DC: slc-a-origin-www-1.paypal.com
Date: Thu, 27 Feb 2014 20:50:47 GMT
Content-Length: 8
Connection: close
Set-Cookie: cwrClyrK4LoCV1fydGbAxiNL6iG=KVmAID_U9eq9TG0lkX119TL840BG6Xau98CeIZX3jTQTx9a4uGno9gxDJGS6VrX8CoBQnj9_n7cUnfeLjb8bD_pyJvE1_XJY5j-Sl5dVIROlu-Cn3_PmfiwL1S0RB-hCOCJzLNIzLsV7H4_xyZg7u4eCzBKTZdlfRru95teI1r2A2tFCtNcYgejjmUHfHzy4nSMco604T_4OJZX_6PvoheXYKqj8tOR_hNW_s3057XoT0wbqzwWA0YI00DZRoRocUuY77_hR6THpxJ6ZnekN3nrdsh74z4XvF39eaf2kdQLGKArjel4sFCAFtmO0NkVQs7VOM_upvhbruJQdm94oOue4UWUpx2NQMUE2JWYNgrgUaBliTrzbFgWOLFidJ1bNJoopcthU5nDUFDXDka7_JSRL44rPMWS0o0kLQIZDnfTiVqhdZsnWNT6wxH4; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: cookie_check=yes; expires=Sun, 25-Feb-2024 20:50:47 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: navcmd=_notify-validate; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: navlns=0.0; expires=Sat, 27-Feb-2016 20:50:47 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: Apache=10.73.8.134.1393534247185146; path=/; expires=Sat, 20-Feb-44 20:50:47 GMT
Set-Cookie: X-PP-SILOVER=name%3DLIVE5.WEB.1%26silo_version%3D880%26app%3Dslingshot%26TIME%3D665128787; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: X-PP-SILOVER=; Expires=Thu, 01 Jan 1970 00:00:01 GMT
Set-Cookie: Apache=10.73.8.46.1393534247177026; path=/; expires=Sat, 20-Feb-44 20:50:47 GMT
Set-Cookie: AKDC=slc-a-origin-www-1.paypal.com; expires=Thu, 27-Feb-2014 21:20:47 GMT; path=/; secure

一些可能的事情,基于我正在使用的工作示例......

  1. 您可能会遇到序列化问题。
  2. 您发回 ssl://www.paypal.com 而不是 https://www.paypal.com/cgi-bin/webscr
  3. 检查验证的方式可能有问题?我的示例使用 strcmp() 而不是 strpos()

    // read raw POST data to prevent serialization issues w/ $_POST
    $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]);
    }
    // read the post from PayPal system and add 'cmd'
    $req = 'cmd=_notify-validate';
    foreach ($myPost as $key => $value) {
        if (get_magic_quotes_gpc()) {
            $value = urlencode(stripslashes($value));
        } else {
            $value = urlencode($value);
        }
        $req .= "&$key=$value";
    }
    // Post IPN back to PayPal to validate the IPN data is genuine
    $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);
    // Set TCP timeout to 30 seconds
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
    // CONFIG: Please download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set the directory path
    // of the certificate as shown below. Ensure the file is readable by the webserver.
    // This is mandatory for some environments.
    // $cert = __DIR__ . "./cacert.pem";
    // curl_setopt($ch, CURLOPT_CAINFO, $cert);
    $res = curl_exec($ch);
    curl_close($ch);
    // Inspect IPN validation result and act accordingly
    if (strcmp($res, "VERIFIED") == 0) {
        // good to go...
    }
    

引用:

  • https://developer.paypal.com/webapps/developer/docs/classic/products/instant-payment-notification/
  • http://paypal.github.io/sdk/sample-apps/

最新更新