I have the following snippet of code that is meant to capture IPN response from Paypal, however when I output res to a file the file is blank. I've done some troubleshooting and found that when I var_dump the $res variable, it's an empty string. The socket is opening without issue, and the var_dump of fputs shows that 139 bits were written, but the response string itself is still empty, neither containing valid, or invalid.

Thoughts?

// Build the required acknowledgement message out of the notification just received

$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";
$header.= "Connection: Close";

// 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

var_dump(fputs($fp, $header . $req));
$res = stream_get_contents($fp, 1024);
有帮助吗?

解决方案

You're specifying callback on your response, but you're missing a 'Host' header.
'Host' is required with HTTP 1.1.

Try this:

// Build the required acknowledgement message out of the notification just received

$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.= "Host: www.sandbox.paypal.com\r\n";
$header.= "Content-Length: " . strlen($req) . "\r\n";
$header.= "Connection: Close\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

var_dump(fputs($fp, $header . $req));
$res = stream_get_contents($fp, 1024);  

Though I would strongly recommend you port over to cURL rather than fsockopen (like our example).
Whilst fsockopen has its uses, we find it's generally causes more problems because it's very specific in what you must send and how you must specifically read a response.
cURL under PHP is a lot more lenient in that, handling a lot of the background work for you.

其他提示

It seems that paypal has changed a with their IPN api and not updated their documentation. I found the following extremely helpful. Worked the first time.

https://github.com/Quixotix/PHP-PayPal-IPN

You have to set use_ssl to true, because paypal now requires ssl to work. Don't worry though, it comes with a shared certificate already, or you can download the cacert.pem as documented with the curl library

http://curl.haxx.se/docs/caextract.html

after setting it all up, it only took the following code in my ipn listener to get rolling:

<?php

header('HTTP/1.1 200 OK');

require_once('includes/ipnlistener.php');



$ipn = new IpnListener();

$ipn->use_ssl = true;
$ipn->use_sandbox = true;

if($ipn->processIpn() === true) {
    file_put_contents('ipn.log',$ipn->getTextReport());

} else {
    file_put_contents('ipn.log',"Not Verified\n");
}

Hope this helps you too

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top