【问题标题】:IPN Paypal in Symfony 3Symfony 3 中的 IPN Paypal
【发布时间】:2017-01-04 09:29:59
【问题描述】:

我在一个基于 Symfony 3 和 PayPal API 的网站上工作。

我尝试在 Symfony 之外使用 IPN,它运行良好。

现在我尝试在我的控制器中实现它,但没有任何反应。

此代码来自 Paypal 的 Github。

public function paypalAction(Request $request){
  // STEP 1: Read POST data

  // reading posted data from directly from $_POST causes serialization
  // issues with array data in POST
  // reading raw POST data from input stream instead.
  $raw_post_data = $request->getContent();
  $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";
  }


  // STEP 2: Post IPN data back to paypal to validate

  $ch = curl_init('https://www.sandbox.paypal.com/cgi-bin/webscr');
  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);
  curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));

  // In wamp like environments that do not come bundled with root authority certificates,
  // please download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set the directory path
  // of the certificate as shown below.
  // curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem');
  if( !($res = curl_exec($ch)) ) {
      // error_log("Got " . curl_error($ch) . " when processing IPN data");
      curl_close($ch);
      exit;
  }
  curl_close($ch);


  // STEP 3: Inspect IPN validation result and act accordingly

  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 Primary PayPal email
      // check that payment_amount/payment_currency are correct
      // process payment

      // assign posted variables to local variables

      $item_name = $_POST['item_name'];
      $item_number = $_POST['item_number'];
      $cart_item = $_POST['num_cart_items'];
      $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'];

      // <---- HERE you can do your INSERT to the database
      return new Response("Paypal worked !");
  } else if (strcmp ($res, "INVALID") == 0) {
      // log for manual investigation
      return new Response("Paypal didn't worked !");
  }
}

【问题讨论】:

    标签: php paypal symfony paypal-ipn


    【解决方案1】:

    抱歉,我还不能发表我认为应该如此的评论。我想提的几件事,首先请检查您的日志(symfony3: /{project}/var/log/dev.log(或 prod 中的 prod.log),并让我们知道与您的请求相关的任何事情。

    其次,IPN 是否正在发送以及发送到哪里?人们忽略的一点是,他们将在本地运行一个 symfony 项目,却忘记了 paypal 无法将它的 ipn 发送到您的本地主机...如果您想这样做,您应该使用 ngrok 之类的东西来隧道您的本地主机,然后将其发送到暴露您的本地主机的隧道地址

    第三,我刚刚完成了一个集成了 paypal 和 Orderly IPN Bundle 的项目,可以节省大量时间。 https://github.com/orderly/symfony2-paypal-ipn 当然,接收和记录 IPN 很容易,但 Orderly 会做的远不止这些——我们应该做但没有想到的事情——而且它很容易集成。虽然,请注意不再维护有序 IPN,因此如果您选择采用此选项,您可能需要参考这些拉取请求 https://github.com/orderly/symfony2-paypal-ipn/pull/38/files https://github.com/orderly/symfony2-paypal-ipn/pull/42/files(虽然也许不要只为每个人设置 255 并使用一些主动性)

    希望这在某种程度上有所帮助。

    哦,PS。我遇到了你可能遇到的问题 - 默认情况下,PayPal 将其 IPN 发送为 windows-1252,但我的数据库是 UTF-8。我花了一段时间才明白这一点,因为直到有人以 ü 的名义下订单才导致问题。要更改此https://simple-membership-plugin.com/setting-utf-8-formatting-for-your-paypal-ipn-messages/

    编辑:在 symfony 中,您还应该将 Request $request 传递给 paypalAction,而不是使用 $_GET 或 $_POST,尽管它们会起作用。

    【讨论】:

      【解决方案2】:

      您不能使用file_get_contents('php://input');,因为Request 对象之前使用过它。

      use Symfony\Component\HttpFoundation\Request;
      
      ...
      
      public function paypalAction(Request $request)
      {
          $raw_post_data = $request->getContent();
          ...
      }
      

      【讨论】:

      • 感谢您的帮助,因为 IPN 模拟器现在可以使用我的脚本。但不幸的是,当我回到我的网站时,我仍然收到“PayPal 不起作用”。看来 $request 是空的,我不知道为什么。
      【解决方案3】:

      好吧,我对此进行了更深入的研究,发现问题出在我使用的 PayPal 按钮/表单上。

      这是一个“立即购买”按钮的代码,它与 IPN 和我的控制器完美配合:

       <form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">
        <input type='hidden' value="5" name="amount" />
        <input name="currency_code" type="hidden" value="EUR" />
        <input name="shipping" type="hidden" value="0.00" />
        <input name="tax" type="hidden" value="0.00" />
        <input name="return" type="hidden" value="http://www.YOURDOMAIN.com/valid/paiement" />
        <input name="cancel_return" type="hidden" value="http://www.YOURDOMAIN.com/cancel/paiement" />
        <input name="notify_url" type="hidden" value="http://www.YOURDOMAIN.com/validation/paiement" />
        <input name="cmd" type="hidden" value="_xclick" />
        <input name="business" type="hidden" value="YOURMAIL@YOURDOMAIN.com" />
        <input name="item_name" type="hidden" value="A kind of book" />
        <input name="no_note" type="hidden" value="1" />
        <input name="lc" type="hidden" value="FR" />
        <input name="bn" type="hidden" value="PP-BuyNowBF" />
        <input name="custom" type="hidden" value="4" />
        <input alt="Effectuez vos paiements via PayPal : une solution rapide, gratuite et sécurisée" name="submit" src="https://www.paypal.com/fr_FR/FR/i/btn/btn_buynow_LG.gif" type="image" /><img src="https://www.paypal.com/fr_FR/i/scr/pixel.gif" border="0" alt="" width="1" height="1" />
      </form>
      

      这是一个“添加到购物车”按钮,它不起作用,并且没有给我来自 PayPal IPN 的回调。我得到一个空的回复。

       <form target="paypal" action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">
        <input type="hidden" name="cmd" value="_s-xclick">
        <input type="hidden" name="hosted_button_id" value="YOURID">
        <input name="return" type="hidden" value="http://www.YOURDOMAIN.com/valid/paiement" />
        <input name="cancel_return" type="hidden" value="http://www.YOURDOMAIN.com/cancel/paiement" />
        <input name="notify_url" type="hidden" value="http://www.YOURDOMAIN.com/validation/paiement" />
        <input type="image" src="https://www.sandbox.paypal.com/fr_FR/FR/i/btn/btn_cart_LG.gif" border="0" name="submit" alt="PayPal, le réflexe sécurité pour payer en ligne">
        <img alt="" border="0" src="https://www.sandbox.paypal.com/fr_FR/i/scr/pixel.gif" width="1" height="1">
      </form>
      

      我不明白为什么 IPN 的工作方式因我使用的按钮而异。

      注意:在任何这些情况下,IPN 模拟器都能完美运行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-07-29
        • 2016-08-09
        • 1970-01-01
        • 2013-01-01
        • 2011-02-19
        • 2011-09-12
        相关资源
        最近更新 更多