user1576375 user1576375 - 11 months ago 106
PHP Question

PayPal IPN Bad Request 400 Error

Using the PayPal IPN, I keep getting an error 400.

I have been making the script send me emails of

to see what the response is, inside of the
while (!feof($fp)) {}
loop. I always end up getting the error:
HTTP/1.0 400 Bad Request

In total I get back:

HTTP/1.0 400 Bad Request
​Connection: close
Server: BigIP
Content-Length: 19
​Invalid Host Header

​The last line after this is just blank. Here is my code, I have tried changing loads of things but nothing works.

$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$value = preg_replace('/(.*[^%^0^D])(%0A)(.*)/i','${1}%0D%0A${3}', $value);// IPN fix
$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('ssl://', 443, $errno, $errstr, 30);

if (!$fp) {
} else {
fputs($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {
} else if (strcmp ($res, "INVALID") == 0) {
// E-mail admin or alert user
fclose ($fp);

I have added a line, this is the header before it is sent:

POST /cgi-bin/webscr HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 1096

Answer Source

Since you're opening the socket yourself, rather than using an HTTP library such as curl, you need to set the proper HTTP Protocol version and add the HTTP Host header yourself just below the POST line.

$header = "POST /cgi-bin/webscr HTTP/1.1\r\n";
$header .= "Host:\r\n";