简体   繁体   English

沙箱/贝宝阶段超级慢。 大约需要20秒才能回复我的IPN处理程序。 现在根本不响应

[英]sandbox / stage of paypal super slow. Around 20 seconds to respond to my IPN handler. Now does not respond at all

i took the example implementation of the IPN handler from paypals official website 我以贝宝官方网站上IPN处理程序的实现为例

now this worked very well in the beginning. 现在,一开始效果很好。 But the answers got slower and slower. 但是答案越来越慢。 For a while they worked fine with 20 seconds delay. 有一阵子,他们工作良好,延迟了20秒。 Now I am getting no traffic at all for minutes. 现在,几分钟之内我什么都没收到。 What is going on? 到底是怎么回事? maybe is the sandbox ipn handler of paypal themselves close to be down? 也许paypal的沙箱ipn处理程序本身即将崩溃? they have a bad setup? 他们的设置不好?

I want to mention this post (it kinda shed some light) 我想提到这篇文章 (有点启发)

note i get not even an initial log. 请注意,我什至没有初始日志。 Paypal seems to not call my side at all any longer. 贝宝(Paypal)似乎再也不会打扰我了。

The IPN is callable, i can call it from, say an incognito window, and it will write to the logfile. IPN是可调用的,我可以从隐身窗口中调用它,并将其写入日志文件。

for completeness, here my file: 为了完整性,这里是我的文件:

<?php

    use ...;
    // 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");
    require_once(__DIR__ . "/../../bootstrap.php");



    //define("LOG_FILE", __DIR__ . "/../../../../../japi/logs/ipn.log");
    error_log(date('[Y-m-d H:i e] '). "Lukas: Initial call to log". PHP_EOL, 3, LOG_FILE);
    // Read POST data
    // reading posted data directly from $_POST causes serialization
    // issues with array data in POST. Reading raw POST data from input stream instead.
    $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]);
    }
    //$mmessage ="hi lukas <br/>";
    //
    //    include_once JCR_KINT_CLASS;
    //$mmessage .= @\Kint::dump($myPost);
    //mail("lukas.meier@gmail.com", "IPN from paypal test", $mmessage);
    // 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);
    }
    // CONFIG: Optional proxy configuration
    //curl_setopt($ch, CURLOPT_PROXY, $proxy);
    //curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 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);
    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) {
      // check whether the payment_status is Completed
      // check that txn_id has not been previously processed
      // check that receiver_email is your PayPal email
      // check that payment_amount/payment_currency are correct
      // process payment and mark item as paid.
      // assign posted variables to local variables
      //$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'];


      $jppa = new JcrPayPalAnswer();
      $jppa->createFromPayPalIpnResponseArray($myPost);

      if($jppa->is_completed){
        //content of file: paykey => array($project_id, serialize($fd), $statisticsId);
        $r = parse_ini_file(JCR_PAYKEY_INIFILE);
        if($r){
          $pkArr = $r[$jppa->pay_key];
          $project_id = $pkArr[0];
          /** @var FundingDetails $fd */
          $fd = unserialize(base64_decode($pkArr[1]));
          $statisticsId = $pkArr[2];
          $jcrp = new JewcerProject($project_id);
          $jewcerFee = $jcrppa->amount_fee_account;
          $fundingAmount = $jcrppa->amount_funding_account_brutto;

          $x = null;
          $js = new JcrStatistic($x, $statisticsId);

          //fna [$amount, $paypalfee, $jewcerFeeAmount]
          $fnA = JcrPayPalService::getFeesAndAmount($fd->amount, $fd->coverfee, $jcrp->getFundingFee());
          $amount = $fnA[0];
          $paypalfee = $fnA[3];
          $jewcerFeeAmount = $fnA[2];

          $fd->wepayFee = $paypalfee;
          $fd->jcrFee = $jewcerFeeAmount;
          $amount_with_fee = $amount;
          if ($fd->coverfee) {
            $fd->amount_without_fees = $amount - $paypalfee - $jewcerFeeAmount;
          } else {
            $fd->amount_without_fees = $fd->amount;
          }
          $fd->amount = $amount_with_fee;
          $jcrf = new JcrFunder($project_id);
          $jcrf->setBasicFunderValues($fd);
          $jcrf->save();
          $js->add_stats_from_fundingdetails($fd, "jfp3");
          EmailService::sendDonationSuccessEmails($jcrp, $fd);

          unset($r[$jppa->pay_key]);
          UtilityService::write_ini_file($r, JCR_PAYKEY_INIFILE);
          UtilityService::write_ini_file(array('ok',  $jcrf->id ), JCR_PAYPAL_STATUS_FOLDER . $jppa->pay_key);
        }else{
          error_log(date('[Y-m-d H:i e] '). "JEWCER ERROR 3200: couldn't find entry for paykey in inifile, inifile val: " . var_export($r, true). PHP_EOL, 3, LOG_FILE);
        }
    //    mail("lukas.meier@gmail.com", "IPN COMPLETED", serialize($jppa));
    //    JcrPayPalKeyPool::$keys[$jppa->pay_key] = $jppa; //eventually verify emails
    //    JcrPayPalKeyPool::$keys[$jppa->pay_key] = $jppa; //eventually verify emails

      }

      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);
      }
    }

I have been using IPN for many years with a wide variety of projects. 我使用IPN多年,涉及各种各样的项目。 In my experience, if everything is configured correctly and your IPN script has no problems then it will work very close to real-time without many hiccups. 以我的经验,如果一切配置正确,并且您的IPN脚本没有问题,那么它将非常接近实时运行,而不会造成很多麻烦。

What you can run into, though, is if your IPN script is failing for any reason, or simply sending PayPal a response code other than 200 when it gets hit, it will re-try, but each time it re-tries it delays the time in which it sends. 不过,您遇到的问题是,如果您的IPN脚本由于某种原因而失败,或者当它被击中时只是向PayPal发送200以外的响应代码,它将重试,但是每次重试都会延迟发送时间。 So it might send one instantly, if that doesn't provide a 200 response it'll send another one in 5 seconds, 10 seconds, 20 seconds, 40 seconds, etc. (that's not the exact increment it uses but it's an example of what it does.) 因此,它可能会立即发送一个,如果不提供200响应,则会在5秒,10秒,20秒,40秒等时间内发送另一个(这不是它使用的确切增量,但这是一个示例)它能做什么。)

If your script is not returning a 200 response at some point, or if this is happening a lot with the IPNs that are getting sent to your script, PayPal's system will move your IPNs to a slower queue than the others that are working well. 如果您的脚本在某个时候没有返回200响应,或者在发送到您的脚本的IPN上经常发生这种情况,那么PayPal的系统会将您的IPN移到较慢的IPN队列中。

Eventually, if it still isn't fixed, they'll just disable it altogether on your account. 最终,如果仍然无法解决问题,他们将在您的帐户中完全禁用它。

Check the IPN history in your PayPal account to see what response you're getting back there on the IPNs that are getting sent. 检查您的PayPal帐户中的IPN历史记录,以查看您对已发送的IPN返回的响应。 Of course, this will allow you to verify that they are indeed getting sent as well. 当然,这将使您能够验证它们是否确实也已发送。

You'll also want to check the PHP error logs on your server to see if anything is going on when the IPN script gets hit that causes it to fail for any reason. 您还需要检查服务器上的PHP错误日志,以查看IPN脚本被击中时由于任何原因导致失败的任何情况。 This could be happening with only certain IPN types or when particular characters are included in the data, for example. 例如,仅某些IPN类型或数据中包含特定字符时,可能会发生这种情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM