【问题标题】:PayPal IPN issue using Codeigniter while retrieving IPN responses在检索 IPN 响应时使用 Codeigniter 的 PayPal IPN 问题
【发布时间】:2020-04-27 12:02:51
【问题描述】:

我使用了this_for_reference(效果很好)。

我面临的问题: 当我尝试使用 CodeIgniter 实施 same 以使用 PayPal 进行购物车付款时,我可以完成付款交易。 IPN 消息是在 PayPal 端生成的 [即时付款通知 (IPN) 详细信息]。但是我无法使用通知 URL 或下面提供的成功 URL 检索 IPN 消息,因此数据库没有得到更新。

这是视图文件,我在其中将商品添加到购物车,然后添加到 PayPal 付款。

<div class="row">
    <?php if(!empty($products)): foreach($products as $row): ?>
    <div class="thumbnail">

        <form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">
            <!-- Identify your business so that you can collect the payments. -->
            <input type="hidden" name="business" value="{My PayPal email ID}">

            <!-- Specify a PayPal Shopping Cart Add to Cart button. -->
            <input type="hidden" name="cmd" value="_cart">
            <input type="hidden" name="add" value="1">

            <!-- Specify details about the item that buyers will purchase. -->
            <input type="hidden" name="item_name" value="<?php echo $row['name']; ?>">
            <input type="hidden" name="item_number" value="<?php echo $row['item_number']; ?>">
            <input type="hidden" name="amount" value="<?php echo $row['price']; ?>">
            <input type="hidden" name="currency_code" value="USD">

            <!-- Specify URLs -->
            <input type='hidden' name='cancel_return' value='http://{MyDomain}/paypal/cancel'>
            <input type='hidden' name='return' value='http://{MyDomain}/paypal/success'>

//Notification URL is actually "http://{MyDomain}/paypal/ipn",
 but it's **not a typo error** in my actual code. 
I still face issues, mentioned in my Question.
{Preston PHX} It was a good catch//

            <input type='hidden' name='notify_url' value='http://{MyDomain}/paypal/ipn'>

            <!-- Display the payment button. -->
            <input type="image" name="submit"
              src="https://www.paypalobjects.com/webstatic/en_US/i/btn/png/btn_addtocart_120x26.png"
              alt="Add to Cart">
            <img alt="" width="1" height="1" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif">
        </form>

    <?php endforeach; endif; ?>

</div>

支付宝IPN功能

public function ipn()
    {   
        $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)
            {
                $my_post[$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
         */
        $paypalURL = "https://www.sandbox.paypal.com/cgi-bin/webscr";
        $ch = curl_init($paypalURL);
        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_SSLVERSION, 6);
        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', 'User-Agent: company-name'));
        $res = curl_exec($ch);
        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) {

            //Payment data
            $txn_id = $_POST['txn_id'];
            $payment_gross = $_POST['mc_gross'];
            $currency_code = $_POST['mc_currency'];
            $payment_status = $_POST['payment_status'];
            $payer_email = $_POST['payer_email'];

            //Check if payment data exists with the same TXN ID.
            $prevPayment = $this->db->query("SELECT payment_id FROM payment WHERE txn_id = '".$txn_id."'");
            if($prevPayment->get()->num_rows() > 0){
                exit();
            }else{
                //Insert tansaction data into the database

                $insertPayment = $this->db->query("INSERT INTO payment(txn_id,payment_gross,currency_code,payment_status,payer_email) VALUES('".$txn_id."','".$payment_gross."','".$currency_code."','".$payment_status."','".$payer_email."')");
                if($insertPayment){
                    //Insert order items into the database
                    $payment_id = $this->db->insert_id();
                    $num_cart_items = $_POST['num_cart_items'];
                    for($i=1;$i<=$num_cart_items;$i++){
                        $order_item_number = $_POST['item_number'.$i];
                        $order_item_quantity = $_POST['quantity'.$i];
                        $order_item_gross_amount = $_POST['mc_gross_'.$i];
                        $insertOrderItem = $this->db->query("INSERT INTO order_items(payment_id,item_number,quantity,gross_amount) VALUES('".$payment_id."','".$order_item_number."','".$order_item_quantity."','".$order_item_gross_amount."')");
                    }
                }

            }

        }

        }

PayPal成功函数

public function success(){
            $txn_id = $_GET['tx'];
            $payment_gross = $_GET['amt'];
            $currency_code = $_GET['cc'];
            $payment_status = $_GET['st'];

            if(!empty($txn_id)){
                //Check if payment data exists with the same TXN ID.
                $paymentResult = $this->db->query("SELECT * FROM payment WHERE txn_id = '".$txn_id."'");


                 /* if($paymentResult->num_rows > 0){
                    //payment information
                    $paymentRow = $paymentResult->fetch_assoc();
                    $payment_id = $paymentRow['payment_id'];*/

                if($paymentResult->get()->num_rows() > 0){
                    //payment information
                    foreach($paymentResult->get()->result_array() as $row)
                    {
                        $payment_id = $row['payment_id'];
                    }
                    $payment_id = $paymentRow['payment_id'];

                    //order items details
                    $orderItemResult = $this->db->query("SELECT p.name, i.quantity, i.gross_amount FROM order_items as i LEFT JOIN products as p ON p.id = i.item_number WHERE payment_id = '".$payment_id."'");
                    //pass the transaction data to view
                    //$this->load->view('paypal/cartsuccess', $data);

                  }

            }

}

并在视图文件中显示结果。

【问题讨论】:

    标签: codeigniter paypal e-commerce paypal-ipn cart


    【解决方案1】:
    <input type='hidden' name='notify_url' value='http://{MyDomain}/pauypal/ipn'>
    

    这个错字是你真正的问题吗?

    您在接收付款的 PayPal 沙盒帐户的 IPN 历史记录中看到了什么?

    https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_display-ipns-history

    【讨论】:

    • 嗨......不,这不是错字......实际上
    • IPN 消息是在 PayPal 端生成的 [即时付款通知 (IPN) 详细信息],例如 num_cart_items,Item_number1, custom, payer_status,payer_email,mc_gross,verify_sign,payer_id, txn_id 等。
    • 那么,PayPal IPN 历史日志显示您的网络服务器使用 HTTP 200 响应确认这些 IPN?您的网络服务器日志显示什么?您应该在该级别解决此问题。
    • sandbox.paypal.com/cgi-bin/webscr?cmd=_display-ipns-history 实际上保存了所有事务的日志,IPN 消息中包含所有详细信息,其中提到了 HTTP 响应代码 200,传递状态为已发送。
    • 那很好。现在您需要调试您的网络服务器并找出它为什么不处理,或者为什么它不验证,或者为什么它不保存到数据库中,每个 IPN。
    猜你喜欢
    • 1970-01-01
    • 2020-08-29
    • 2019-02-27
    • 2016-11-18
    • 2017-02-14
    • 1970-01-01
    • 2011-04-28
    • 2014-07-15
    • 2016-02-07
    相关资源
    最近更新 更多