php - paypal 不发送实时 ipn 详细信息

标签 php paypal

我在我的 paypal 配置中使用以下代码,这是代码

///Paypal Array///
                            $data=array(
                            //merchant email for live
                            //'merchant_email'=>'sumofish@yahoo.com',
                            //merchant email for test
                            'merchant_email'=>'uneebmir321-facilitator@yahoo.com',
                            'product_name'=>$bundleplan." Bundle Plan",
                            's_amount'=>$bundle_came_price,     // Second` Amount
                            's_cycle'=>'M',         //Second Period M=montrh,Y=year ,D=Days, W='week'
                            's_period'=>$period,    // Second Cycle
                            //see small_price fucntionality again
                            'small_price'=>$bundle_came_price,
                            ////see small_price fucntionality again
                            'currency_code'=>'USD',
                            'thanks_page'=>"https://".$_SERVER['HTTP_HOST'].'/puppy/puppy/thanks222.php',
                            'notify_url'=>"https://puppybundle.com/beta/ipn.php",
                            'cancel_url'=>"https://puppybundle.com/beta/index.php",
                            //true for sandbox false for live
                            'paypal_mode'=>true,
                            //true for sandbox false for live
                            'currency_symbole'=>'$'
                            );
                ///Paypal Array///

这是 ipn 类

<?php
session_start();
$unique_id=$_SESSION['unique_id'];
include("db.php");
file_put_contents("newfile.txt",var_export($_POST,true));
$status="not_completed";
                            $status2="paid";
                            $status3="remaining";
                            $zero=0;
                            $currency="CAD";
$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";
}


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

$ch = curl_init('https://www.sandbox.paypal.com/cgi-bin/webscr'); // change to [...]sandbox.paypal[...] when using sandbox to test
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 (trim($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


     $price = $_POST['mc_gross'];
     $currency = $_POST['mc_currency'];
     $payer_email = $_POST['payer_email'];
     $txn_id=$_POST['txn_id'];

    $item_name = $_POST['item_name'];
        if($item_name=="Small Bundle Plan"){

            $item_name="small";
        }

parse_str($_POST['custom'],$_MYVAR);

$custom =$_MYVAR['id'];
$unique_id =$_MYVAR['unique_id'];
trim($custom);
$txt =$custom;
    $currency_code= $_POST['currency_code'];
    $fulldate = gmdate('Y-m-d H:i:s');
    if($txn_id){

    $query="UPDATE `puppy_pending_transaction` SET `status`=? WHERE unique_id=?";
                            $stmt = $db->prepare($query);
                            if($stmt){
                                $stmt->bind_param("ss", $status2,$unique_id);
                                $stmt->execute();   
                                $stmt->close();         
                            } 


$query="INSERT INTO `puppy_transaction_confirmed`(`transaction_id`,`unique_id`, `user_id`, `payer_email`, `transaction_time`, `package`, `amount`, `currency`,`status_delivery`) VALUES (?,?,?,?,?,?,?,?,?)";
                            $stmt = $db->prepare($query);

                            if($stmt) 
                            {
                                $check=$stmt->bind_param("sssssssss",$txn_id,$unique_id,$custom,$payer_email,$fulldate,$item_name,$price,$currency,$status);
                                $stmt->execute();               
                                $stmt->close();
                            }

$query="INSERT INTO `puppy_paid_transaction_record`(`unique_id`, `month_delivered`, `total`,`status`) VALUES (?,?,?,?)";
                            $stmt = $db->prepare($query);
                            if($stmt){
                                $stmt->bind_param("ssss", $unique_id,$zero,$item_name,$status3);
                                $stmt->execute();   
                                $stmt->close();         
                            } 
    }   
} else if (strcmp ($res, "INVALID") == 0) {
    // log for manual investigation 
}
?>

问题是这段代码在沙箱中 100% 正常工作,现在我为实时版本所做的是将商家电子邮件更改为客户电子邮件,并将 paypal_mode 更改为 false 以进行实时测试,另一件事我更改了

`$ch = curl_init('https://www.sandbox.paypal.com/cgi-bin/webscr');

在ipn类中

`$ch = curl_init('https://www.paypal.com/cgi-bin/webscr');`

对于实时模式,我已经使用 ipn 模拟器来验证我的文件,而且还可以,而且我确定我在 paypal 中为商家设置的 ipn 路径也可以,我确定它,我不知道出了什么问题!谁能指出我正确的方向?

最佳答案

根据下载较新的 PHP IPN code from here .您可以将 IPN 类文件保存到您需要的任何位置(下面的示例与您的 IPN 文件位于同一文件夹中。

您还需要设置异常捕获例程,因为 Paypal 默认情况下不会实现异常捕获例程(try{ ...} catch{} block 就是这样做的)。

<?php
define("LOG_FILE", "paypal_ipn.log");
////edit
error_log("Log File Started:\n",3,LOG_FILE);

require('PaypalIPN.php'); //check path is correct. 
$ipn = new PayPalIPN();    
try {
    // Use the sandbox endpoint during testing.
    $ipn->useSandbox(); //comment this line out to use live version.
    $verified = $ipn->verifyIPN(); //returns true or false. 
    if ($verified) {
        /*****
         * Process IPN
         * A list of variables is available here:
         * https://developer.paypal.com/webapps/developer/docs/classic/ipn/integration-guide/IPNandPDTVariables/
         *
         * Here is where you add your data from your current setup, your own custom data to take the values from Paypal and process them.
         ****/
        // 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


        $price       = $_POST['mc_gross'];
        $currency    = $_POST['mc_currency'];
        $payer_email = $_POST['payer_email'];
        $txn_id      = $_POST['txn_id'];

        $item_name = $_POST['item_name'];
        if ($item_name == "Small Bundle Plan") {

            $item_name = "small";
        }

        parse_str($_POST['custom'], $_MYVAR);

        $custom    = $_MYVAR['id'];
        $unique_id = $_MYVAR['unique_id'];
        trim($custom);
        $txt           = $custom;
        $currency_code = $_POST['currency_code'];
        $fulldate      = gmdate('Y-m-d H:i:s');
        if ($txn_id) {

            $query = "UPDATE `puppy_pending_transaction` SET `status`=? WHERE unique_id=?";
            $stmt  = $db->prepare($query);
            if ($stmt) {
                $stmt->bind_param("ss", $status2, $unique_id);
                $stmt->execute();
                $stmt->close();
            }


            $query = "INSERT INTO `puppy_transaction_confirmed`(`transaction_id`,`unique_id`, `user_id`, `payer_email`, `transaction_time`, `package`, `amount`, `currency`,`status_delivery`) VALUES (?,?,?,?,?,?,?,?,?)";
            $stmt  = $db->prepare($query);

            if ($stmt) {
                $check = $stmt->bind_param("sssssssss", $txn_id, $unique_id, $custom, $payer_email, $fulldate, $item_name, $price, $currency, $status);
                $stmt->execute();
                $stmt->close();
            }

            $query = "INSERT INTO `puppy_paid_transaction_record`(`unique_id`, `month_delivered`, `total`,`status`) VALUES (?,?,?,?)";
            $stmt  = $db->prepare($query);
            if ($stmt) {
                $stmt->bind_param("ssss", $unique_id, $zero, $item_name, $status3);
                $stmt->execute();
                $stmt->close();
            }

            /***
             * End OP code
             ***/
        }
        // Reply with an empty 200 response to indicate to paypal the IPN was received correctly.
        header("HTTP/1.1 200 OK");
    }

}
catch (Exception $e) {
    error_log("There was a problem: ".$e->getMessage(),3,LOG_FILE);
}

我还强烈建议您下载关联的.pem 文件并将其上传到您的服务器并在第106 行 调整对它的引用IPN 类文件。这个 pem 文件有一个 key ,供您的服务器与 Paypal 安全服务器通信,并解决了大量与此相关的历史问题。

您可能需要调整一些自己的代码来编辑传入的数据,但这个脚本对我来说比旧的程序 Paypal 代码好得多。


.pem文件说明:

至少从测试的角度来看,我可能最简单的做法是将 Paypal Pem 文件放在与您保存 paypal IPN 类相同的文件夹中。

因此该类的第 106 行:

    if ($this->use_local_certs) {
        curl_setopt($ch, CURLOPT_CAINFO, "cacert.pem");
    }

并确保 $this->use_local_certs = true;

关于php - paypal 不发送实时 ipn 详细信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40546886/

相关文章:

wordpress - 登录paypal沙盒,pay with paypal页面无法登录

c# - 如何将 PayPal 浏览器登录集成到 Visual Studio 集成测试中?

PHP:如何在foreach循环内移动数组指针?

php - Linux CentOS release 6.8 上安装ImageMagick 报错

php - TSP(旅行商问题)求解器使用 GoogleMap

php - Group by 避免 order by

php - 搜索工作正常,只有第一个结果未显示

php - 带有 PHP 和 cURL 的 Paypal API

paypal - 有没有办法在自适应支付中明确批准后确认付款

paypal - 如何停止用原件替换 Logo 文件的 prestashop paypal 模块?