After 2018 June 30th, Paypal won't accept non-TLS 1.2 + HTTP 1.1 requests anymore.
They created the URL https://tlstest.paypal.com/ to test if connections are OK. If we open this URL in a browser, we get a successful:
PayPal_Connection_OK
Quesiton: why does it fail when connecting from PHP with the following code? (I get no response at all, the browser is still in waiting "state" like this, so it doesn't even arrive at echo $errno; echo $errstr;
)
<?php
$req = ''; // usually I use $req = 'cmd=_notify-validate'; for IPN
$header .= "POST / HTTP/1.1\r\n";
$header .= "Host: tlstest.paypal.com\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen('tls://tlstest.paypal.com', 443, $errno, $errstr, 30);
if (!$fp) {
echo $errno;
echo $errstr;
} else {
fputs($fp, $header);
while (!feof($fp))
{
$res = fgets($fp, 1024);
echo $res;
}
fclose($fp);
}
?>
Note:
this is not a duplicate of Paypal IPN HTTP/1.1 - doesn't provide any response at all, it is an empty string, the latter is outdated.
I have PHP 5.6.33-0+deb8u1 (cli) (built: Jan 5 2018 15:46:26) and
openssl version text: OpenSSL 1.0.1t 3 May 2016
It works on my side by changing
tls://
tossl://
which makes absolutely no sense to me, but this is also why usingfsockopen
is a too low level library to just do HTTP exchanges with it (you should use a proper HTTP client library) and at the same time not configurable enough regarding TLS stuff.With
$fp = fsockopen('tls://tlstest.paypal.com', 443, $errno, $errstr, 30);
I get :but with
$fp = fsockopen('ssl://tlstest.paypal.com', 443, $errno, $errstr, 30);
I get:And then it hangs, probably because it is a keep-alive connection and the buffer is smaller than 1024 so that you do not get the following body content. Which is probably "PayPal_Connection_OK", as it exactly matches the length displayed in
Content-Length
. This again shows that you should use an HTTP client library instead of trying to (badly) reimplement HTTP on top offsockopen
.For completeness, here is a working code (full credit to PatrickMevzek's answer):
Here is the answer from server: