贝宝PHP不工作。没有收到来自Sandbox的响应;唯一连接:关闭
我已经干了24个小时了,现在就要把头发拔出来了。我已经在网络上和Stackoverflow中进行了检查,没有找到任何有用的信息。我甚至查看了以前的帖子,比如,但是回复对我来说不起作用。也许我错过了那篇对我有帮助的文章;如果我有,请原谅我重复同样的问题,但这件事相当紧急,我已经穷途末路了 无论如何,问题是:贝宝PHP不工作。没有收到来自Sandbox的响应;唯一连接:关闭,php,paypal,Php,Paypal,我已经干了24个小时了,现在就要把头发拔出来了。我已经在网络上和Stackoverflow中进行了检查,没有找到任何有用的信息。我甚至查看了以前的帖子,比如,但是回复对我来说不起作用。也许我错过了那篇对我有帮助的文章;如果我有,请原谅我重复同样的问题,但这件事相当紧急,我已经穷途末路了 无论如何,问题是: include('../inc/db_fns.inc'); //<--All my DB work is in here. include('../inc/shippin
include('../inc/db_fns.inc'); //<--All my DB work is in here.
include('../inc/shipping.inc');
$paypal_email = "seller_1360198925_biz@hotmail.com";
$paypal_currency = 'USD';
//Here begin the functions I'm using to check everything and pass data to DB.
function no_paypal_trans_id($trans_id) {
$connection = db_connect();
$query = sprintf("SELECT id FROM orders WHERE paypal_trans_id = '%s'", mysql_real_escape_string($trans_id));
$result = mysql_query($query);
$num_results = mysql_num_rows($result);
if($num_results == 0) {
return true;
}
return false;
}
function payment_amount_correct($shipping, $params) {
$amount = 0.00;
for ($i=1; $i <= $params['num_cart_items']; $i++) {
$query = sprintf("SELECT precio FROM products WHERE id='%s'", mysql_real_escape_string($params["item_number{$i}"]));
$result = mysql_query($query);
if($result) {
$item_price = mysql_result($result, 0, 'precio');
$amount += $item_price * $params["quantity{$i}"];
}
}
if(($amount+$shipping) == $params['mc_gross']) {
return true;
} else {
return false;
}
}
function create_order($params) {
db_connect();
$query = sprintf("INSERT INTO orders set orders.firstname = '%s', orders.lastname = '%s', orders.email = '%s', orders.country = '%s', orders.address = '%s', orders.city = '%s', orders.zip_code = '%s', orders.state = '%s', orders.status = '%s', orders.amount = '%s', orders.paypal_trans_id = '%s', created_at = NOW()", mysql_real_escape_string($params['first_name']), mysql_real_escape_string($params['last_name']), mysql_real_escape_string($params['payer_email']), mysql_real_escape_string($params['address_country']), mysql_real_escape_string($params['address_street']), mysql_real_escape_string($params['address_city']), mysql_real_escape_string($params['address_zip']), mysql_real_escape_string($params['address_state']), mysql_real_escape_string($params['payment_status']), mysql_real_escape_string($params['mc_gross']), mysql_real_escape_string($params['txn_id']));
$result = mysql_query($query);
if(!$result) {
return false;
}
$order_id = mysql_insert_id();
for ($i=1; $i <= $params['num_cart_items'] ; $i++) {
$product = find_product($params["item_number{$i}"]);
$query = sprintf("INSERT INTO items set order_id = '%s', product_id = '%s', title = '%s', price = '%s', qty = '%s'", mysql_real_escape_string($order_id), mysql_real_escape_string($product['id']), mysql_real_escape_string($product['title']), mysql_real_escape_string($product['price']), mysql_real_escape_string($params["quantity{$i}"]));
$result = mysql_query($query);
if(!$result) {
return false;
}
}
return true;
}
//Here begins the Paypal code as is
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('www.sandbox.paypal.com', 80, $errno, $errstr, 30); //<--Here I also tried out the other response to the question linked above and it actually returned a 'Invalid host' into he $res var-
// assign posted variables to local variables
$item_name = $_POST['item_name']; //<--These are the two vars for which
$item_number = $_POST['item_number'];// Paypal Sandbox posts no value.
$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'];
if (!$fp) {
// HTTP ERROR
} else {
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {
if ($_POST['payment_status'] == 'Completed' && no_paypal_trans_id($_POST['txn_id']) && $paypal_email == $_POST['receiver_email'] && $paypal_currency == $_POST['mc_currency'] && payment_amount_correct($shipping, $_POST)) {
// process payment
create_order($_POST);
}
} else if (strcmp ($res, "INVALID") == 0) {
// log for manual investigation
}
}
fclose ($fp);
}
$req = cmd=_notify-validate&test_ipn=1&payment_type=instant&payment_date=20%3A55%3A22+Feb+08%2C+2013+PST&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer%40paypalsandbox.com&payer_id=TESTBUYERID01&address_name=John+Smith&address_country=United+States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San+Jose&address_street=123%2C+any+street&receiver_email=seller%40paypalsandbox.com&receiver_id=TESTSELLERID1&residence_country=US&item_name1=something&item_number1=AK-1234&quantity1=1&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross_1=9.34&mc_handling=2.06&mc_handling1=1.67&mc_shipping=3.02&mc_shipping1=1.02&txn_type=cart&txn_id=2229455¬ify_version=2.4&custom=xyz123&invoice=abc1234&charset=windows-1252&verify_sign=AsdNkKD2ktCz.aUB.9WYWy-g8MHoAa-TsvSjUgGstseJVdUhQTq3aCwW
我有一个PHP购物车,它发送客户端到贝宝。一切都很顺利。我已经根据Paypal的指示构建了它,当它向他们发送所有代码时。一切正常,除了最后一步,从Paypal返回到我的服务器检查一切正常。即使在那里,我也照样复制了整个Paypal代码,只是添加了一些函数来检查所有匹配项。然而,我不能让它工作。我尝试将结果发送到DB,但什么也没发生。因此,如果一切正常,并且我没有收到电子邮件,我将PHPMail
命令放置在最后一个操作的正确位置。我在几乎所有其他地方都放置了相同的邮件命令,试图找出发生了什么,并从不同的地方收到了不同的线索
首先,当我打电话将vars Paypal应该发送回我的服务器的电子邮件打印到电子邮件中时,我会收到包含所有VAR的电子邮件,除了项目名称
和项目编号
,我得到的是空白;这很奇怪,因为到目前为止,Paypal Sandbox向我展示了我应该购买的每一种产品。我尝试在PHP代码中给这些变量一个固定值,因为Paypal并没有向它们发布一个值,至少在那个时候是这样。我想知道这两个值的缺失是否是错误的原因;但是,即使设置了值,错误仍然存在
第二,在Paypal代码中有一个while
循环(上面给出的链接中的一个响应说应该用$res=stream\u get\u contents($fp,1024);
,但是,这对我也不起作用),所以我把Mail
命令放在那里,看看我得到了什么。我要求打印$res
var和付款状态
,如期收到了几封电子邮件,收集的结果如下:
payment_status = Pending
$res = HTTP/1.0 302 Found
Location: https://www.sandbox.paypal.com
Server: BigIP
Connection: close
Content-Length: 0
所以我猜错误就发生在这一点上。正在发生(或未发生)的情况不仅没有返回代码为继续检查等而查找的支付状态的已完成
状态,甚至没有返回无效
响应。所以我没有得到任何回应,也没有任何东西可以告诉我一切是否正常。而且,奇怪的是,甚至更糟糕的是,沙盒仍然在为每一次付款尝试向我收取虚假费用,尽管很明显,在某个地方存在错误,而且这个过程没有完成。(当然,这带来了另一个难题:一旦所有这些问题都解决了,如果某个时候由于X原因出现服务器错误,Paypal还会向我的客户收费吗?我甚至不知道有人在我的网站上买了东西。)
好吧,我想这就是我对这件事所能解释的。在这一点上,我看不出哪里出了问题。代码应该使这成为一件非常简单的事情。所以我真的不知道我怎么会把复制粘贴搞砸。我认为至少应该没有错误,除非它们与原始代码一起提供。此外,由于到这一点的所有其他操作都是100%正常的,因此这个错误可能出现的唯一地方是在这个PHP文件中,一旦用户完成支付过程,Paypal必须调用这个文件
对此问题的任何想法都将不胜感激强>
代码在这里
PHP代码:
include('../inc/db_fns.inc'); //<--All my DB work is in here.
include('../inc/shipping.inc');
$paypal_email = "seller_1360198925_biz@hotmail.com";
$paypal_currency = 'USD';
//Here begin the functions I'm using to check everything and pass data to DB.
function no_paypal_trans_id($trans_id) {
$connection = db_connect();
$query = sprintf("SELECT id FROM orders WHERE paypal_trans_id = '%s'", mysql_real_escape_string($trans_id));
$result = mysql_query($query);
$num_results = mysql_num_rows($result);
if($num_results == 0) {
return true;
}
return false;
}
function payment_amount_correct($shipping, $params) {
$amount = 0.00;
for ($i=1; $i <= $params['num_cart_items']; $i++) {
$query = sprintf("SELECT precio FROM products WHERE id='%s'", mysql_real_escape_string($params["item_number{$i}"]));
$result = mysql_query($query);
if($result) {
$item_price = mysql_result($result, 0, 'precio');
$amount += $item_price * $params["quantity{$i}"];
}
}
if(($amount+$shipping) == $params['mc_gross']) {
return true;
} else {
return false;
}
}
function create_order($params) {
db_connect();
$query = sprintf("INSERT INTO orders set orders.firstname = '%s', orders.lastname = '%s', orders.email = '%s', orders.country = '%s', orders.address = '%s', orders.city = '%s', orders.zip_code = '%s', orders.state = '%s', orders.status = '%s', orders.amount = '%s', orders.paypal_trans_id = '%s', created_at = NOW()", mysql_real_escape_string($params['first_name']), mysql_real_escape_string($params['last_name']), mysql_real_escape_string($params['payer_email']), mysql_real_escape_string($params['address_country']), mysql_real_escape_string($params['address_street']), mysql_real_escape_string($params['address_city']), mysql_real_escape_string($params['address_zip']), mysql_real_escape_string($params['address_state']), mysql_real_escape_string($params['payment_status']), mysql_real_escape_string($params['mc_gross']), mysql_real_escape_string($params['txn_id']));
$result = mysql_query($query);
if(!$result) {
return false;
}
$order_id = mysql_insert_id();
for ($i=1; $i <= $params['num_cart_items'] ; $i++) {
$product = find_product($params["item_number{$i}"]);
$query = sprintf("INSERT INTO items set order_id = '%s', product_id = '%s', title = '%s', price = '%s', qty = '%s'", mysql_real_escape_string($order_id), mysql_real_escape_string($product['id']), mysql_real_escape_string($product['title']), mysql_real_escape_string($product['price']), mysql_real_escape_string($params["quantity{$i}"]));
$result = mysql_query($query);
if(!$result) {
return false;
}
}
return true;
}
//Here begins the Paypal code as is
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('www.sandbox.paypal.com', 80, $errno, $errstr, 30); //<--Here I also tried out the other response to the question linked above and it actually returned a 'Invalid host' into he $res var-
// assign posted variables to local variables
$item_name = $_POST['item_name']; //<--These are the two vars for which
$item_number = $_POST['item_number'];// Paypal Sandbox posts no value.
$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'];
if (!$fp) {
// HTTP ERROR
} else {
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {
if ($_POST['payment_status'] == 'Completed' && no_paypal_trans_id($_POST['txn_id']) && $paypal_email == $_POST['receiver_email'] && $paypal_currency == $_POST['mc_currency'] && payment_amount_correct($shipping, $_POST)) {
// process payment
create_order($_POST);
}
} else if (strcmp ($res, "INVALID") == 0) {
// log for manual investigation
}
}
fclose ($fp);
}
$req = cmd=_notify-validate&test_ipn=1&payment_type=instant&payment_date=20%3A55%3A22+Feb+08%2C+2013+PST&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer%40paypalsandbox.com&payer_id=TESTBUYERID01&address_name=John+Smith&address_country=United+States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San+Jose&address_street=123%2C+any+street&receiver_email=seller%40paypalsandbox.com&receiver_id=TESTSELLERID1&residence_country=US&item_name1=something&item_number1=AK-1234&quantity1=1&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross_1=9.34&mc_handling=2.06&mc_handling1=1.67&mc_shipping=3.02&mc_shipping1=1.02&txn_type=cart&txn_id=2229455¬ify_version=2.4&custom=xyz123&invoice=abc1234&charset=windows-1252&verify_sign=AsdNkKD2ktCz.aUB.9WYWy-g8MHoAa-TsvSjUgGstseJVdUhQTq3aCwW
抱歉,这是$req
,而不是$res
var。$res
var由while
循环返回。我在那里放置了一个mail
命令,收到了几封带有$res
值的电子邮件。这些是:
X-Frame-Options: SAMEORIGIN
HTTP/1.0 200 OK
Strict-Transport-Security: max-age=14400
INVALID
Content-Type: text/html; charset=UTF-8
Date: Sat, 09 Feb 2013 05:44:33 GMT
Connection: close
Content-Length: 7
编辑4:完全目瞪口呆:甚至连直接从Paypal开发者网站获得并通过Paypal开发者网站IPN测试仪测试的简单Paypal IPN代码都不能工作…
我使用了找到的Paypal IPN脚本生成器
我选择生成一个脚本,将有效或无效的响应发回给我
我完整地复制了它,并将其粘贴到保存在服务器中的PHP文件中
我检查了又检查了一遍,确保没有留下任何代码
我从找到的IPN模拟器将这个PHP文件定位在我的服务器上
模拟器显示一个检查并显示“IPN已成功发送”
我去检查我的邮件,看看我得到了什么回复,是有效的还是无效的。。。我没有得到任何回应。因此,IPN在某个时候到达PHP buy,该过程被破坏,因此它甚至无法访问有效/无效的函数。然而,这正是Paypal提供给你的代码,并用它为之设计的sim卡进行测试。发生了什么事
第二天的奥德赛
好吧,不用说,还没有运气。但我现在决定彻底跟踪PHP代码和Paypal中的所有内容。其思想是,当此代码将Paypal插入的初始值以相同的顺序发送回Paypal时,会出现VALID
响应(根据Paypal文档)
第一个问题是我根本没有收到代码的响应。因此,假设代码一开始就失败了。碰巧的是,第一个问题是沙箱链接没有工作。(我是在@hexa的帮助下到达这一点的
$req = cmd=_notify-validate&test_ipn=1&payment_type=instant&payment_date=08%3A42%3A23+Feb+09%2C+2013+PST&payment_status=Completed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer%40paypalsandbox.com&payer_id=TESTBUYERID01&business=seller%40paypalsandbox.com&receiver_email=seller%40paypalsandbox.com&receiver_id=TESTSELLERID1&residence_country=US&item_name1=something&item_number1=AK-1234&quantity1=1&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=15.34&mc_gross_1=12.34&mc_handling=2.06&mc_handling1=1.67&mc_shipping=3.02&mc_shipping1=1.02&txn_type=cart&txn_id=23291642¬ify_version=2.4&custom=xyz123&invoice=abc1234&charset=windows-1252&verify_sign=AFcWxV21C7fd0v3bYYYRCpSSRl31ACyRxUQ6LVDwUz.i78mjQLsN9aKb
$ch = curl_init('https://www.paypal.com/pe/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'));
if( !($res = curl_exec($ch)) ) {
// error_log("Got " . curl_error($ch) . " when processing IPN data");
curl_close($ch);
exit;
}
curl_close($ch);
// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('www.sandbox.paypal.com', 80, $errno, $errstr, 30);
// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .= "Host: www.sandbox.paypal.com\r\n";
$header .= "Connection: close\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
$ch = curl_init('https://www.paypal.com/pe/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'));
if( !($res = curl_exec($ch)) ) {
// error_log("Got " . curl_error($ch) . " when processing IPN data");
curl_close($ch);
exit;
}
curl_close($ch);
function verifyPayment($request)
{
if($request->is('post') && !empty($request->data))
{
//build response string
$response = '';
foreach($request->data as $field => $value)
{
//build response string
$response .= $field . '=' . urlencode(stripslashes($value)) . '&';
}
if(empty($id))
{
return false; //invalid transaction
}
//append notify validate command
$response .= "cmd=_notify-validate";
//respond to paypal - open connection
$parsedUrl = parse_url('https://www.sandbox.paypal.com/cgi-bin/webscr');
$sock = fsockopen('ssl://' . $parsedUrl['host'], "443", $errorNumber, $error, 30);
if(!$sock)
{
return false; //could not open connection - must be able to verify
}
//post data back to paypal
fputs($sock, "POST $parsedUrl[path] HTTP/1.1\r\n");
fputs($sock, "Host: $parsedUrl[host]\r\n");
fputs($sock, "Content-type: application/x-www-form-urlencoded\r\n");
fputs($sock, "Content-length: " . strlen($response) . "\r\n");
fputs($sock, "Connection: close\r\n\r\n");
fputs($sock, $response . "\r\n\r\n");
//loop through response and append
$ipnResponse = '';
while(!feof($sock))
{
$ipnResponse .= fgets($sock, 1024);
}
//close connection
fclose($sock);
if(!eregi("VERIFIED", $ipnResponse))
{
return false; //paypal reports invalid transaction
}
//if we made it here, transaction is valid
return true;
}
}