Проблема IPN в PayPal с использованием Codeigniter при получении ответов IPN - PullRequest
1 голос
/ 09 января 2020

Я использовал this_for_reference (который работал нормально).

Проблемы, с которыми я сталкиваюсь: Когда я пытался реализовать то же самое С помощью CodeIgniter для оплаты через PayPal я могу завершить транзакцию для платежей. Сообщения IPN были сгенерированы на стороне PayPal [детали мгновенного платежа (IPN)]. Но я не смог получить сообщения IPN с URL-адресом уведомления или URL-адресом успеха, указанным ниже, поэтому база данных не обновляется.

Это файл просмотра, в который я добавляю товары в корзину, а затем в платеж 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 PayPal

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

                  }

            }

}

и отображение результатов в файле просмотра.

1 Ответ

0 голосов
/ 10 января 2020
<input type='hidden' name='notify_url' value='http://{MyDomain}/pauypal/ipn'>

Является ли эта опечатка вашей реальной проблемой?

Что вы видите в истории IPN для учетной записи песочницы PayPal, получающей платежи?

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

...