我在我的 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/