【发布时间】:2016-04-29 18:04:24
【问题描述】:
我不能使用 cURL,安装在我的 web 主机上的无法更改的版本不支持 TLS。
我现在正在尝试使用 fsockopen 看看是否可以使用 IPN。
它只是挂起,浏览器抛出连接超时。
PHP 7,open_ssl 已启用
<?php
header('HTTP/1.1 200 OK');
$item_name = $_POST['item_name'];
$item_number = $_POST['item_number'];
$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'];
$req = 'cmd=_notify-validate'; // Add 'cmd=_notify-validate' to beginning of the acknowledgement
foreach ($_POST as $key => $value) { // Loop through the notification NV pairs
$value = urlencode(stripslashes($value)); // Encode these values
$req .= "&$key=$value"; // Add the NV pairs to the acknowledgement
}
// Set up the acknowledgement request headers
$header = "POST /cgi-bin/webscr HTTP/1.1\r\n"; // HTTP POST request
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
// Open a socket for the acknowledgement request
$fp = fsockopen('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
// Send the HTTP POST request back to PayPal for validation
fputs($fp, $header . $req);
while (!feof($fp)) { // While not EOF
$res = trim(fgets ($fp, 1024));
if (strcmp ($res, "VERIFIED") == 0) { // Response contains VERIFIED - process notification
file_put_contents('./log_'.date("j.n.Y").'.txt', 'VERIFIED', FILE_APPEND);
}
else if (strcmp ($res, "INVALID") == 0) { Response contains INVALID - reject notification
file_put_contents('./log_'.date("j.n.Y").'.txt', 'INVALID', FILE_APPEND);
}
}
//close
fclose($fp);
?>
更新
所以这似乎是我当前代码的问题。我使用以下内容查看是否可以与 PayPal 通话。
<?php
$site = "sandbox.paypal.com";//works
$port = 443;
$fp = fsockopen($site, $port, $errno, $errstr, 30);
if(!$fp){
echo "<b>The port is NOT open!</b>";
}else{
echo "<b>The port is open!</b>";
fclose($fp);
}
?>
结果是The port is open!
更新 2
好的,我现在使用以下代码从 IPN 模拟器获得响应。我遇到的其他问题是我未能使用我的听众的 FQDN 并离开了 http://。
所以现在下一个问题是$res = trim($res); 总是空白,但我的帖子变量不是。这是因为它是沙盒吗?
<?php
$debug = 1;
$sandbox = 1;
header('HTTP/1.1 200 OK');
$item_name = $_POST['item_name'];
$item_number = $_POST['item_number'];
$payment_status = $_POST['payment_status'];
if ($_POST['mc_gross'] != null) {
$payment_amount = $_POST['mc_gross'];
} else {
$payment_amount = $_POST['mc_gross1'];
}
$payment_currency = $_POST['mc_currency'];
$txn_id = $_POST['txn_id'];
$receiver_email = $_POST['receiver_email'];
$payer_email = $_POST['payer_email'];
$payment_date = $_POST['payment_date'];
$first_name = $_POST['first_name'];
$last_name = $_POST['last_name'];
$item_name = $_POST['item_name'];
$sandbox_url = "sandbox.paypal.com";
$prod_url = "paypal.com";
$verfiy_email = "you email address the payment should be made to";
if ($sandbox) {
$url = $sandbox_url;
} else {
$url = $prod_url;
}
if ($debug) {
error_log(date('[Y-m-d H:i e] '). "IPN URL: " . $url . PHP_EOL, 3, LOG_FILE);
}
$req = 'cmd=_notify-validate'; // Add 'cmd=_notify-validate' to beginning of the acknowledgement
foreach ($_POST as $key => $value) { // Loop through the notification NV pairs
$value = urlencode(stripslashes($value)); // Encode these values
$req .= "&$key=$value"; // Add the NV pairs to the acknowledgement
if ($debug) {
error_log(date('[Y-m-d H:i e] '). "POST Data: " . $key . " - " . $value . PHP_EOL, 3, LOG_FILE);
}
}
//post back to PayPal system to validate (replaces old headers)
$header = "POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Host: www." . $url . "\r\n";
$header .= "Connection: close\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('sandbox.paypal.com', 443, $errno, $errstr, 30);
//error connecting to paypal
if (!$fp) {
error_log(date('[Y-m-d H:i e] '). "Can't connect to PayPal to validate IPN message: " . $errno . " - " . $errstr . PHP_EOL, 3, LOG_FILE);
}
//successful connection
if ($fp) {
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
$res = trim($res); //NEW & IMPORTANT
if ($debug) {
error_log(date('[Y-m-d H:i e] '). "DEBUG: Validation - " . $res . PHP_EOL, 3, LOG_FILE);
error_log(date('[Y-m-d H:i e] '). "DEBUG: Payment Status - " . $payment_status . PHP_EOL, 3, LOG_FILE);
error_log(date('[Y-m-d H:i e] '). "DEBUG: Receiver Email - " . $receiver_email . PHP_EOL, 3, LOG_FILE);
error_log(date('[Y-m-d H:i e] '). "DEBUG: Verify Email - " . $verfiy_email . PHP_EOL, 3, LOG_FILE);
}
//I don't see this
if (strcmp($res, "VERIFIED") == 0) {
//insert order into database
if ($debug) {
error_log(date('[Y-m-d H:i e] '). "Response Message: " . "VERIFIED" . PHP_EOL, 3, LOG_FILE);
}
}
//I don't see this
if (strcmp ($res, "INVALID") == 0) {
//insert into DB in a table for bad payments for you to process later
if ($debug) {
error_log(date('[Y-m-d H:i e] '). "Response Message: " . "INVALID" . PHP_EOL, 3, LOG_FILE);
}
}
if (strcasecmp ($payment_status, "Completed") == 0 && strcasecmp($receiver_email, $verfiy_email) == 0) {
if ($debug) {
error_log(date('[Y-m-d H:i e] '). "Response Message: " . "Payment VERIFIED" . PHP_EOL, 3, LOG_FILE);
}
} else {
if ($debug) {
error_log(date('[Y-m-d H:i e] '). "Response Message: " . "Payment INVALID" . PHP_EOL, 3, LOG_FILE);
}
}
}
fclose($fp);
}
?>
【问题讨论】:
-
如果您的服务器环境不支持 TLS,这意味着它必须很旧。像10岁以上。如果他们无法让您进入具有更新环境且运行 TLS 的新服务器,我强烈建议您切换主机。
-
好的,所以我解决了我的问题,但现在 $res 始终为空白。我没有收到 VERIFIED 或 INVALID 回复。
标签: php paypal paypal-ipn fsockopen