我已经呆了24小时,正要拔头发。我已经在整个Web上和Stackoverflow中进行了检查,发现没有任何帮助。我什至检查了以前的帖子,例如Not receiving a response from Paypal IPN Sandbox,但响应对我不起作用。也许我错过了对我有帮助的职位;如果可以的话,请原谅我重复同样的问题,但是这件事很紧急,我已经走到尽头了。
无论如何,问题是这样的:
我有一个PHP购物车,它将客户发送到Paypal。一切工作正常。在将所有代码发送给他们时,我已经按照Paypal的说明进行了构建。一切都很好,除非涉及到最后一步,从Paypal返回POST
返回我的服务器以检查一切正常。甚至到那里,我都照原样复制了整个Paypal代码,并添加了一些功能来检查我所有方面的匹配情况。但是,我无法使其正常工作。我尝试将结果发送到数据库,但没有任何反应。因此,我将一个PHP Mail
命令放在正确的位置,如果一切正常并且我没有收到电子邮件,则应该执行最后一个操作。我在几乎所有其他地方都放置了相同的Mail
命令,试图找出正在发生的事情,并从不同的地方收到了不同的线索。
首先,当我打电话将Paypal应该发送回我的服务器的变量打印到电子邮件中时,我收到了带有和item_name
的所有变量的电子邮件,但我将其留空。这很奇怪,因为到目前为止,贝宝(Paypal)沙箱向我展示了我应该购买的每个产品。考虑到贝宝(Paypal)没有向它们发布值,至少在那时,我尝试给PHP代码上的这些变量一个固定值。我想看看是否缺少这两个值是导致错误的原因。但是,即使设置了值,错误仍然存在。
其次,贝宝(Paypal)代码中有一个item_number
循环(上面给出的链接中的响应说应该用while
代替的循环,但这对我也不起作用),所以我将< cc>命令在那里,看看我得到了什么。我要求打印$res=stream_get_contents($fp, 1024);
var和Mail
,并按预期方式获得了几封电子邮件,其收集结果如下: payment_status = Pending
$res = HTTP/1.0 302 Found
Location: https://www.sandbox.paypal.com
Server: BigIP
Connection: close
Content-Length: 0
因此,我猜测此刻正在发生错误。某事正在发生(或未发生),这不仅没有返回代码要继续检查等的$res
的payment_status
状态,而且还没有返回Completed
响应。因此,我没有任何反应,也没有任何东西可以告诉我是否一切正常。而且,奇怪的是,甚至很明显的事实是,即使很明显某个地方有错误并且流程没有完成,Sandbox仍会为这些付款尝试中的每一次向我收费。 (当然,这带来了另一个难题:一旦解决了所有问题,如果某个时候由于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);
}
编辑1:再说一遍:不走运!
我刚刚尝试了原始的,未修改过的Paypal代码。我刚刚将其复制并粘贴到此PHP中,然后运行Sandbox buy。结果一样。没有回应,没有数据插入表中,我也无法得知有人实际上从我的购物车中购买了东西,但是Paypal仍然对购买收取虚假费用。这支持我怀疑该错误来自原始代码,并且与我添加的功能无关。希望有人能尽快理解这一点。首先要感谢那个人!
编辑2:第一个回应。
现在删除了他/她的回复的友善用户足以尝试一下。他/她建议Paypal文档在我有payment_status
的地方提及INVALID
。也许我的代码版本较旧,所以我尝试了他/她的建议。现在我评论发生了什么:
首先,非常感谢您的回复。不幸的是,它没有运气。用一个地址替换另一个地址后,现在该过程不会进入https://www.sandbox.paypal.com/cgi-bin/webscr
循环,它会在http://www.sandbox.paypal.com
处停止。我放置了一个while
命令以打印出该命令中包含的fsockopen
和Mail
。用$errno
代替$errstr
我无法找到套接字传输“ https”-在配置PHP时是否忘记启用它?因此,我删除了“ https://”,然后重试。现在,我得到php_network_getaddresses:getaddrinfo失败:名称或服务未知。有任何想法吗?
编辑3:在评论部分中与@hexacyanide的对话之后: $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
抱歉,这是https://www.sandbox.paypal.com/cgi-bin/webscr
,而不是http://www.sandbox.paypal.com
var。 $req
变量由$res
循环返回。我在其中放置了$res
命令,并获得了多个带有while
值的电子邮件。这些是: 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 Developer网站上经过Paypal Developer网站IPN测试器测试的简单Paypal IPN代码...
我使用了here找到的Paypal IPN脚本生成器。
我选择生成一个脚本,该脚本将通过电子邮件发送给我VALID或INVALID响应。
我将其完整复制并粘贴到保存在服务器中的PHP文件中。
我检查并重新检查是否没有留下任何代码。
我从发现here的IPN模拟器中将该PHP文件定位到服务器上。
模拟器显示一个检查并说“ IPN成功发送”。
我去检查我的邮件,看看我收到了什么答复,无论是有效还是无效...我都没有任何答复。因此,IPN在某个时候到达了PHP购买中心,该过程已中断,因此甚至无法使用VALID / INVALID函数。但是,这正是Paypal给您的代码,并已为其专门设计的模拟程序进行了测试。发生什么了?
此奥德赛第二天
好。不用说:还没有运气。但是我现在决定彻底跟踪PHP代码和Paypal中的所有内容。想法是,当此代码以相同的顺序(根据Paypal文档的说明)将Paypal插入的初始值发送回Paypal时,就会出现mail
响应。
第一个问题是我从代码中根本没有收到任何响应。因此,假设是代码从一开始就失败了。碰巧,第一个问题是沙盒链接不起作用。 (我在@hexacyanide的帮助下达到了这一点,他很乐意跟进昨天的进展或缺乏进展。每当我获得足够的声誉以积极地标记他/她的回应时,我都会这么做。)因此,我取消了$res
,并且,它正在返回响应,但是现在响应是VALID
。
从那时起到现在,我已经了解到IPN仅用于卖方方交易检查和数据记录。贝宝不关心IPN的结果。所以我的购物车100%工作正常。用户可以购买东西,贝宝将向用户收费。 IPN只会检查我的购买信息是否实际上来自贝宝,并且一切都在那儿,然后(以我的脚本)将所有这些信息发送到数据库中,这样我就可以履行我的服务了。因此,即使在没有IPN的情况下成功进行交易,IPN也是促进整个销售过程的宝贵机制。但是,所有这些最后的信息使我怀疑我的购物车的所有代码都是O.K.,而且问题仅在这里,使用此代码或Paypal处理它的方式。 (事实上,通过贝宝自己的IPN模拟器传递的贝宝“原始”代码未返回任何响应,但是在初始状态下由于无法连接到贝宝服务器而出现了同样的错误,这使我倾向于认为问题与Paypal方面有问题。)
因此,所有进入和退出此PHP的日志。为了创建检查点,我将sandbox.
命令放在代码的每个重要位置。在INVALID
命令中,我包括一个增量变量,以使传入的POSTED数据有序排列。这就是我得到的:
这是Paypal将数据发布到代码中的顺序(按发布顺序) 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
notify_version=2.4
custom=xyz123
invoice=abc1234
charset=windows-1252
乍一看,我似乎正在从Paypal获取所有我应该获得的数据。这就是PP发送的顺序。因此,如果我以该顺序发送该数据,而PP实际上确实以相同的顺序对其进行了检查,那么从理论上讲,我应该得到一个Mail
响应。
因此,代码要做的是添加“ cmd = _notify-validate”,这是唯一的添加(PP文档明确表明这是必要的添加),并将所有这些数据传递到名为foreach()
的var中。方式:VALID
。
这是来自下一个检查点的消息,该消息仅在$req
命令关闭后添加。 $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
注意最后的A=X&B=Y&C=Z...
。我无法解释该数据,因为它在foreach()
循环中没有以电子邮件的形式吐出。那么它是从哪里来的呢?这可能是返回verify_sign=AFcWxV21C7fd0v3bYYYRCpSSRl31ACyRxUQ6LVDwUz.i78mjQLsN9aKb
响应的罪魁祸首吗?公开问题。但是,此时所有这些数据都由代码在“ DATA COMING IN”检查点传递;因此,如果这些数据是传入的,并且我的代码将其发送回去,那么一切都应该很好。
因此,下一个检查点将是“ DATA COMING OUT”。我在将foreach()
写回PP的INVALID
代码之前找到了这个检查点。这就是代码的内容: $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
哼!我想念什么吗?我的视线是否跳过了导致此代码行程的最微小的嘶哑声?输出似乎与输入完全相同。让我们假设PP可以很好地处理其代码,以PP期望的方式将POSTED数据转换为字符串,并因此检查...假设所有这一切,可能是什么问题?
让我们再看看...:未解决的问题:
标头可能有问题吗?根据文档,这是应该使用的标头...因此,除非他们对此不满意,否则它应该可以正常工作。
给出的网址可能有问题吗?好吧,这实际上是一个问题,或者在某些时候是WAS。 Internet上至少有6或7个不同的URL在运行,这些URL应该可以工作,而不能工作。有些人为某些人服务,而不是为其他人服务,有些人似乎永远无法工作,等等。甚至PP本身也不确定应该使用什么URL,因为在他们自己的文档中,URL有所不同。清楚的是,使用fputs ($fp, $header . $req);
URL将不会返回任何内容-一种是假设这些URL已损坏。
字符集可能有问题吗?会有不兼容吗?这只是在我看到数据以十六进制代码输入和输出时发生的。问题是这应该使其兼容,对吗?但是,昨天,当我检查$req
循环中发生了什么,并将从PP发送回的信息捕获到sandbox.
var中时,我没有得到十六进制代码,正如您在本证书中进一步看到的那样。
下一个检查点是while()
无效和$res
无效的经典检查点。而且,当然,我得到了一个告诉我一切都无效的东西。
希望我提供的详细信息可以使某人的灯泡明亮地发光!至于我,我还是很傻。
提前致谢!
非常感谢您的回应!
尽管听起来很明智,但我还没有尝试过第二个。听起来这可能是我从PayPal获得的原始代码的问题。如果我有时间尝试一下,看看代码是否可以运行,我将在此处发布反馈。希望有人会发现这一切有用。
一周后,我把头撞在墙上,花了一点时间来解决我的大脑中的问题,几天后,终于,我终于找到了另一种解决网络问题的方法,该方法与第二种方法非常相似。六氰化物反应的一部分。我将其发布在下面,供关注此字符串的任何人使用。但是,我必须说,贝宝(PayPal)代码有很多漏洞。至少我收到了一个。此后,我还有其他一些问题必须通过变通办法解决。最糟糕的是,PayPal根本不支持。我什至打了三遍电话:第一,那个人挂在我身上;第二,我挂了电话。然后,他们告诉我这可能是病毒问题(当他们不知道到底是怎么回事时的典型响应)。
无论如何,我希望我能对您的回答都进行评分,但是我需要获得+15分以上的评分,因此我在这里口头赞美他们。我按原样尝试了Hexacynide的响应代码,但对我来说还是不起作用,因此无法将其标记为已选中。如果将来有时间尝试其他方法,并且可以使用,我将其标记为正确。
在此之前,这是我使用CURL进行的代码更新。 $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);
注意:由于它已启动并正在运行,因此这里针对的是真实的东西,但是,将它与if()
一起使用也可以。
最佳答案
我是Stackoverflow的新手,所以我没有意识到有人可以回答自己的问题。无论如何,我已经在上个星期的原始帖子末尾对其进行了编辑。现在,我将其包括在这里,以便遇到任何此类麻烦的人都可以参考并意识到这是我解决问题的方式。
我尝试了一位贡献者在此处提供的第一个解决方案,但不幸的是,它对我没有用。一旦我已经能够以其他方式解决它,第二个解决方案就到了,所以我没有尝试过。也许将来我会解决。但是,如果有人尝试过,请在这里留下您的评论,以便其他人从智慧中受益。
这是我的解决方案:
一周后,我把头撞在墙上,花了一点时间来解决我的大脑中的问题,几天后,终于,我终于找到了另一种解决网络问题的方法,该方法与第二种方法非常相似。六氰化物反应的一部分。我将其发布在下面,供关注此字符串的任何人使用。但是,我必须说,贝宝(PayPal)代码有很多漏洞。至少我收到了一个。此后,我还有其他一些问题必须通过变通办法解决。最糟糕的是,PayPal根本不支持。我什至打了三遍电话:第一,那个人挂在我身上;第二,我挂了电话。然后,他们告诉我这可能是病毒问题(当他们不知道到底是怎么回事时的典型响应)。
无论如何,我希望我能对您的回答都进行评分,但是我需要获得+15分以上的评分,因此我在这里口头赞美他们。我按原样尝试了Hexacynide的响应代码,但对我来说还是不起作用,因此无法将其标记为已选中。如果将来有时间尝试其他方法,并且可以使用,我将其标记为正确。
在此之前,这是我使用CURL进行的代码更新。
$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);
注意:由于它已启动并正在运行,因此这里针对的是真实的东西,但是,将它与
sandbox.
一起使用也可以。
关于php - Paypal PHP无法正常工作。没有收到来自沙盒的回复;仅限连接:关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14784104/