【问题标题】:paypal IPN not working when using email function使用电子邮件功能时,paypal IPN 无法正常工作
【发布时间】:2016-08-22 00:51:48
【问题描述】:

我正在通过我的网站上的贝宝进行付款,但我在使用即时付款通知时遇到了问题,

我从 paypal 的示例中复制了以下基本代码:

<?php
// CONFIG: Enable debug mode. This means we'll log requests into 'ipn.log' in the same directory.
// Especially useful if you encounter network errors or other intermittent problems with IPN (validation).
// Set this to 0 once you go live or don't require logging.
define("DEBUG", 1);
// Set to 0 once you're ready to go live
define("USE_SANDBOX", 1);
define("LOG_FILE", "./ipn.log");

$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';
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";
}
// Post IPN data back to PayPal to validate the IPN data is genuine
// Without this step anyone can fake IPN data
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);
}

// Set TCP timeout to 30 seconds
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] '). "Can't connect to PayPal to validate IPN message: " . curl_error($ch) . PHP_EOL, 3, LOG_FILE);
    }
    curl_close($ch);
    exit;
} else {
        // Log the entire HTTP response if debug is switched on.
        if(DEBUG == true) {
            error_log(date('[Y-m-d H:i e] '). "HTTP request of validation request:". curl_getinfo($ch, CURLINFO_HEADER_OUT) ." for IPN payload: $req" . PHP_EOL, 3, LOG_FILE);
            error_log(date('[Y-m-d H:i e] '). "HTTP response of validation request: $res" . PHP_EOL, 3, LOG_FILE);
        }
        curl_close($ch);
}
// Inspect IPN validation result and act accordingly
// Split response headers and payload, a better way for strcmp
$tokens = explode("\r\n\r\n", trim($res));
$res = trim(end($tokens));
if (strcmp ($res, "VERIFIED") == 0) {


    mail('try@website.com', 'New Order', 'New Order', 'From: support@website.com');



    if(DEBUG == true) {
        error_log(date('[Y-m-d H:i e] '). "Verified IPN: $req ". PHP_EOL, 3, LOG_FILE);
    }
} else if (strcmp ($res, "INVALID") == 0) {
    // log for manual investigation
    // Add business logic here which deals with invalid IPN messages
    if(DEBUG == true) {
        error_log(date('[Y-m-d H:i e] '). "Invalid IPN: $req" . PHP_EOL, 3, LOG_FILE);
    }
}
?>

如果我删除邮件功能,一切都按预期工作,日志会写入一次,IPN 历史记录中会出现“已发送”状态。

现在,当使用邮件功能时,每件事都会执行大约 8 次,这意味着 8 条日志写入和 8 封电子邮件发送。 同时IPN历史一直在“重试”状态一段时间后变成“错误”状态,提到http响应字段在这两种情况下都是空的。

感谢您的时间伙伴。

编辑 1:

这是日志文件中的内容:

[2016-04-27 12:19 America/New_York] HTTP request of validation request:POST /cgi-bin/webscr HTTP/1.1
Host: www.sandbox.paypal.com
Accept: */*
Connection: Close
Content-Length: 1052
Content-Type: application/x-www-form-urlencoded
Expect: 100-continue



for IPN payload: bla bla bla
[2016-04-27 12:19 America/New_York] HTTP response of validation request: HTTP/1.1 100 Continue

HTTP/1.1 200 OK

bla bla bla

VERIFIED

我认为一切正常,apache 日志也没有显示任何错误...

编辑 2:

已解决,请参阅下面的解决方案。

【问题讨论】:

    标签: php email paypal paypal-ipn


    【解决方案1】:

    Okey 我终于找到了解决方案,这仅适用于使用虚拟专用服务器的人。对我来说,问题是邮件功能花费的时间太长,并且可能在 IPN 侦听器中产生超时,

    要解决这个问题:
    - 首先你在命令提示符下得到主机名提示hostname
    - 然后我编辑主机文件:sudo nano /etc/hosts
    ------------并更改此行-> 127.0.0.1 localhost myhostname
    -----------到这一行 -> 127.0.0.1 localhost localhost.localdomain myhostname

    来源:
    http://deeemm.com/entry/general/fix-your-painfully-slow-php-mail-function

    【讨论】:

      【解决方案2】:

      我认为您的邮件功能失败并给出了 200 以外的标头,这是贝宝期望的,这就是为什么再重试 8 次的原因。 无论如何,我编辑了代码并将 mail() 函数放在 try catch 块中并记录了错误。

          <?php
              // CONFIG: Enable debug mode. This means we'll log requests into 'ipn.log' in the same directory.
              // Especially useful if you encounter network errors or other intermittent problems with IPN (validation).
              // Set this to 0 once you go live or don't require logging.
              define("DEBUG", 1);
              // Set to 0 once you're ready to go live
              define("USE_SANDBOX", 1);
              define("LOG_FILE", "./ipn.log");
      
              $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';
              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";
              }
              // Post IPN data back to PayPal to validate the IPN data is genuine
              // Without this step anyone can fake IPN data
              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);
              }
      
              // Set TCP timeout to 30 seconds
              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] '). "Can't connect to PayPal to validate IPN message: " . curl_error($ch) . PHP_EOL, 3, LOG_FILE);
                  }
                  curl_close($ch);
                  exit;
              } else {
                      // Log the entire HTTP response if debug is switched on.
                      if(DEBUG == true) {
                          error_log(date('[Y-m-d H:i e] '). "HTTP request of validation request:". curl_getinfo($ch, CURLINFO_HEADER_OUT) ." for IPN payload: $req" . PHP_EOL, 3, LOG_FILE);
                          error_log(date('[Y-m-d H:i e] '). "HTTP response of validation request: $res" . PHP_EOL, 3, LOG_FILE);
                      }
                      curl_close($ch);
              }
              // Inspect IPN validation result and act accordingly
              // Split response headers and payload, a better way for strcmp
              $tokens = explode("\r\n\r\n", trim($res));
              $res = trim(end($tokens));
              if (strcmp ($res, "VERIFIED") == 0) {
      
      
                  try{
      mail('try@website.com', 'New Order', 'New Order', 'From: support@website.com');
      
      }
      catch(Exception $e){
      error_log(date('[Y-m-d H:i e] '). "Email could not be sent. Error" . $e->getMessage(). PHP_EOL, 3, LOG_FILE);
      }
      
      
                  if(DEBUG == true) {
                      error_log(date('[Y-m-d H:i e] '). "Verified IPN: $req ". PHP_EOL, 3, LOG_FILE);
                  }
              } else if (strcmp ($res, "INVALID") == 0) {
                  // log for manual investigation
                  // Add business logic here which deals with invalid IPN messages
                  if(DEBUG == true) {
                      error_log(date('[Y-m-d H:i e] '). "Invalid IPN: $req" . PHP_EOL, 3, LOG_FILE);
                  }
              }
              ?>
      

      【讨论】:

      • 感谢您的回答,我尝试了 try-catch,但日志中没有出现错误,请参阅帖子编辑
      猜你喜欢
      • 1970-01-01
      • 2023-04-01
      • 2013-11-14
      • 1970-01-01
      • 2014-05-30
      • 2014-11-23
      • 2013-09-30
      • 2015-06-28
      • 1970-01-01
      相关资源
      最近更新 更多