2016-01-23 175 views
0

嗯,我不能使用cURL,我的web主機上安裝的版本無法更改,不支持TLS。PayPal IPN和fsockopen

我想現在使用fsockopen來查看我是否能夠使用IPN。

它只是掛起和瀏覽器引發連接超時。

PHP 7,open_ssl啓用

<?php 
    header('HTTP/1.1 200 OK'); 

    $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']; 

    $req = 'cmd=_notify-validate';    // Add 'cmd=_notify-validate' to beginning of the acknowledgement 
    foreach ($_POST as $key => $value) {   // Loop through the notification NV pairs 
     $value = urlencode(stripslashes($value)); // Encode these values 
     $req .= "&$key=$value";     // Add the NV pairs to the acknowledgement 
    } 

    // Set up the acknowledgement request headers 
    $header = "POST /cgi-bin/webscr HTTP/1.1\r\n";     // HTTP POST request 
    $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; 
    $header .= "Content-Length: " . strlen($req) . "\r\n\r\n"; 

    // Open a socket for the acknowledgement request 
    $fp = fsockopen('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30); 

    // Send the HTTP POST request back to PayPal for validation 
    fputs($fp, $header . $req); 

    while (!feof($fp)) {      // While not EOF 

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

    if (strcmp ($res, "VERIFIED") == 0) { // Response contains VERIFIED - process notification 

     file_put_contents('./log_'.date("j.n.Y").'.txt', 'VERIFIED', FILE_APPEND); 
    } 
    else if (strcmp ($res, "INVALID") == 0) { Response contains INVALID - reject notification 
     file_put_contents('./log_'.date("j.n.Y").'.txt', 'INVALID', FILE_APPEND); 
    } 
    } 
    //close 
    fclose($fp); 
?> 

UPDATE

所以它似乎是我當前的代碼的問題。我使用以下方式查看是否可以與PayPal交談。

<?php 

$site = "sandbox.paypal.com";//works 
$port = 443; 

$fp = fsockopen($site, $port, $errno, $errstr, 30); 

if(!$fp){ 
    echo "<b>The port is NOT open!</b>"; 
}else{ 
    echo "<b>The port is open!</b>"; 
    fclose($fp); 
} 

?> 

結果是The port is open!

UPDATE 2

確定我使用下面的代碼現在越來越從IPN模擬器的響應。我遇到的其他問題是我沒有使用我的聽衆的FQDN,並且離開了http://。

所以,現在的下一個問題是$res = trim($res);總是空白,但我的後期變量不是。這是因爲它是一個沙箱嗎?

<?php 
    $debug   = 1; 
    $sandbox   = 1; 

    header('HTTP/1.1 200 OK'); 

    $item_name  = $_POST['item_name']; 
    $item_number  = $_POST['item_number']; 
    $payment_status = $_POST['payment_status']; 
    if ($_POST['mc_gross'] != null) { 
     $payment_amount = $_POST['mc_gross']; 
    } else { 
     $payment_amount = $_POST['mc_gross1']; 
    } 
    $payment_currency = $_POST['mc_currency']; 
    $txn_id   = $_POST['txn_id']; 
    $receiver_email = $_POST['receiver_email']; 
    $payer_email  = $_POST['payer_email']; 
    $payment_date  = $_POST['payment_date']; 
    $first_name  = $_POST['first_name']; 
    $last_name  = $_POST['last_name']; 
    $item_name  = $_POST['item_name']; 

    $sandbox_url  = "sandbox.paypal.com"; 
    $prod_url   = "paypal.com"; 
    $verfiy_email  = "you email address the payment should be made to"; 

    if ($sandbox) { 
     $url = $sandbox_url; 
    } else { 
     $url = $prod_url; 
    } 

    if ($debug) { 
     error_log(date('[Y-m-d H:i e] '). "IPN URL: " . $url . PHP_EOL, 3, LOG_FILE); 
    } 

    $req = 'cmd=_notify-validate';    // Add 'cmd=_notify-validate' to beginning of the acknowledgement 
    foreach ($_POST as $key => $value) {   // Loop through the notification NV pairs 
     $value = urlencode(stripslashes($value)); // Encode these values 
     $req .= "&$key=$value";     // Add the NV pairs to the acknowledgement 

     if ($debug) { 
      error_log(date('[Y-m-d H:i e] '). "POST Data: " . $key . " - " . $value . PHP_EOL, 3, LOG_FILE); 
     } 
    } 

    //post back to PayPal system to validate (replaces old headers) 
    $header = "POST /cgi-bin/webscr HTTP/1.1\r\n"; 
    $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; 
    $header .= "Host: www." . $url . "\r\n"; 
    $header .= "Connection: close\r\n"; 
    $header .= "Content-Length: " . strlen($req) . "\r\n\r\n"; 
    $fp = fsockopen ('sandbox.paypal.com', 443, $errno, $errstr, 30); 

    //error connecting to paypal 
    if (!$fp) { 
     error_log(date('[Y-m-d H:i e] '). "Can't connect to PayPal to validate IPN message: " . $errno . " - " . $errstr . PHP_EOL, 3, LOG_FILE); 
    } 

    //successful connection  
    if ($fp) { 
     fputs ($fp, $header . $req); 

     while (!feof($fp)) { 
      $res = fgets ($fp, 1024); 
      $res = trim($res); //NEW & IMPORTANT 

      if ($debug) { 
       error_log(date('[Y-m-d H:i e] '). "DEBUG: Validation - " . $res . PHP_EOL, 3, LOG_FILE); 
       error_log(date('[Y-m-d H:i e] '). "DEBUG: Payment Status - " . $payment_status . PHP_EOL, 3, LOG_FILE); 
       error_log(date('[Y-m-d H:i e] '). "DEBUG: Receiver Email - " . $receiver_email . PHP_EOL, 3, LOG_FILE); 
       error_log(date('[Y-m-d H:i e] '). "DEBUG: Verify Email - " . $verfiy_email . PHP_EOL, 3, LOG_FILE); 
      } 

      //I don't see this 
      if (strcmp($res, "VERIFIED") == 0) { 
       //insert order into database  
       if ($debug) { 
        error_log(date('[Y-m-d H:i e] '). "Response Message: " . "VERIFIED" . PHP_EOL, 3, LOG_FILE); 
       } 
      } 

      //I don't see this 
      if (strcmp ($res, "INVALID") == 0) { 
       //insert into DB in a table for bad payments for you to process later 
       if ($debug) { 
        error_log(date('[Y-m-d H:i e] '). "Response Message: " . "INVALID" . PHP_EOL, 3, LOG_FILE); 
       } 
      } 

      if (strcasecmp ($payment_status, "Completed") == 0 && strcasecmp($receiver_email, $verfiy_email) == 0) { 
       if ($debug) { 
        error_log(date('[Y-m-d H:i e] '). "Response Message: " . "Payment VERIFIED" . PHP_EOL, 3, LOG_FILE); 
       } 
      } else { 
       if ($debug) { 
        error_log(date('[Y-m-d H:i e] '). "Response Message: " . "Payment INVALID" . PHP_EOL, 3, LOG_FILE); 
       } 
      } 
     } 

     fclose($fp); 
    } 
?> 
+1

如果您的服務器環境不支持TLS這意味着它一定很老。像10歲以上。如果他們不會讓你進入一臺運行TLS的更新環境的新服務器,我強烈建議你切換主機。 –

+0

好的,我解決了我的問題,但現在$ res始終是空白的。我沒有得到VERIFIED或INVALID。 – Tsukasa

回答

0

$res通過請求響應循環,閱讀它1024bytes有時,離開它只是空在其最後一次迭代。

如果您嘗試通過循環在某處登錄$res變量,則可以逐行找到響應,例如。

HTTP/1.0 302 Found 
Location: https://www.sandbox.paypal.com 
Server: BigIP 
Connection: close 

這不是解決,但..只是一個想法。 :)

0

謝謝發佈!我在發送IPN時遇到了類似的問題,我的服務器使用fsocket驗證了它,代碼已被執行以寫入數據庫,但PayPal在重試數次後仍然報告'傳遞狀態'爲'失敗',導致數據庫中出現重複。查看您的代碼後,我發現,我已經工作過的教程離開了這一行造成來自PayPal請求超時,而不是顯示200:

$header .= "Connection: close\r\n";