I've had IPN working for years: I'm using a classic Paypal Button to initiate a purchase, and then Paypal sends me an IPN to my web server so that I can record the payment and send the customer an email.
But since Oct 4, 2021, Paypal has not been able to send me IPNs any more.
The "Instant Payment Notification (IPN) history" shows all IPNs since then as either Failed or Pending.
My server, however, responds just fine to the requests if I invoke the IPN URL from a browser. My server (Debian 10 with Apache 2) has not had any configuration changes or package updates in the past week, especially not since the time when it still received IPNs (Oct 3).
The only change I could find around that date (on Oct 3) is an automatic renewal of the Let's Encrypt SSL cert, which happened many times before without causing any such trouble with IPN. I have since recreated the Let's Encrypt cert, even as a dedicated one just for that domain given to Paypal (before the cert was shared between multiple domains on that server), with no improvement.
What works
Invoke the URL (https://paypal-api.tempel.org/) from curl or a web browser. My CGI script is invoked, and the Apache access.log shows the GET request.
What does not work
Use the IPN Simulator, specifying the same URL - then the simulator page shows
IPN was not sent, and the handshake was not verified. Review your information
at the top and I see no request in the Apache access.log
What has changed?
I have checked my firewall (which I hadn't changed in a while), even disabled it, to no avail.
Why would Paypal suddenly fail to even contact my server?
I suspect it has to do with the SSL cert, as its renewal date is the only date relation I could find and since Paypal not accepting the SSL cert would probably also lead to the effect that it won't even issue the GET or POST request to my server, hence no log entry about it.
Am I doing the testing with the Simulator right? How else could I find out why Paypal doesn't perform the "handshake"?
SSL cert oddities
Even though certbot says that the SSL cert is up-to-date, I get this output from openssl for the domain:
% openssl s_client -connect paypal-api.tempel.org:443 -showcerts -CApath /etc/ssl/certs/
CONNECTED(00000005)
depth=1 O = Digital Signature Trust Co., CN = DST Root CA X3
verify error:num=10:certificate has expired
notAfter=Sep 30 14:01:15 2021 GMT
verify return:0
depth=1 O = Digital Signature Trust Co., CN = DST Root CA X3
verify error:num=10:certificate has expired
notAfter=Sep 30 14:01:15 2021 GMT
verify return:0
depth=3 O = Digital Signature Trust Co., CN = DST Root CA X3
verify error:num=10:certificate has expired
notAfter=Sep 30 14:01:15 2021 GMT
verify return:0
---
Certificate chain
0 s:/CN=git.tempel.org
i:/C=US/O=Let's Encrypt/CN=R3
-----BEGIN CERTIFICATE-----
…
-----END CERTIFICATE-----
---
Server certificate
subject=/CN=git.tempel.org
issuer=/C=US/O=Let's Encrypt/CN=R3
---
No client certificate CA names sent
Server Temp Key: ECDH, X25519, 253 bits
---
SSL handshake has read 4574 bytes and written 281 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-CHACHA20-POLY1305
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-CHACHA20-POLY1305
Session-ID: 523AEDD29014010191C7B3DD16F4DC7179B8D91372C3063CEF8D6AD2ED7B800E
Session-ID-ctx:
Master-Key: 36D105B8EAD319DA6B8D2EA30484FC6676F2A2D64CA0EE8889B16396ECA71178FE5154638DCE1E9AF051D8D2FA44472E
Start Time: 1633776598
Timeout : 7200 (sec)
Verify return code: 0 (ok)
---
closed
Why does it say "certificate has expired" at the top, even though it's ok at the end? Could this be the issue?
More strangely, when I give the IPN Simulator another domain of mine, which is also using Let's Encrypt, e.g. www.tempel.org, the Simulator responded yesterday with a positive result, yet today, it gives the same "handshake" error. Also, openssl already gave the same "certificate has expired" error yesterday when the IPN Simulator still accepted it.
So, this all seems to have to do with Let's Encrypt's certificates, somehow. But how do I fix this, apart from buying a different SSL cert?
Or is this just some odd caching issue? When I open https://paypal-api.tempel.org/ in Safari, and check its cert info, it does not indicate any expired certs. What's going on here?
Related to recent expiry of X3 root cert?
I have a hunch that this is related to the expiry of one of Let's Encrypt's root certificate on Sept 30, 2021. The openssl command I've shown above mentions that X3 certificate, indeed.
I am still not clear on how to fix this, however. I understand the instructions in the SO article about disabling the outdated X3 cert, but don't understand what to do then, yet. Probably force-renew the certs with certbot. But even that doesn't make the Simulator happy, yet, and the openssl cmd keeps mentioning the X3 root regardless.
Updated the certs
After reading here about fixing the X3 expiry issues, I renewed my cert by forcing the X1 root (h1.tempel.org is another domain on the same server):
certbot renew --cert-name h1.tempel.org --preferred-chain "ISRG Root X1" --force-renewal
and then restarted Apache (apachectl graceful).
Oddly, since then, when I give https://h1.tempel.org/ to the IPN Simulator, I get the desired "IPN was sent and the handshake was verified." message. But using https://paypal-api.tempel.org/, which is the same certificate, but just a different Apache site on the same server, I still get the "the handshake was not verified" error msg. I am out of ideas.
Can anyone see a difference in the certs between https://h1.tempel.org/ and https://paypal-api.tempel.org/?
I've finally managed to get it to work again - in parts.
After I had found out that the simulator accepts https://h1.tempel.org/ but not https://paypal-api.tempel.org/, even though both are valid pages that return status 200, and both are on the same server and use the same SSL certificate, I reconfigured the web server so that the h1 subdomain would also serve the cgi handler. Then I updated the handler URL at https://www.paypal.com/cgi-bin/webscr?cmd=_profile-ipn-notify to use the h1 subdomain (instead of paypal-api, and that fixed the issue, at least for NEW Paypal transactions.
However, trying to resend the previously failed notifications still fails, because they keep using the old URL.
Paypal Support responds
After finally having contacted Paypal business support, I learned:
They're using Cisco / Talos Intelligence to rate ANY outside page they contact, apparently.
And for some inexplicable reason, Talos currently rates my IPN URL's domain as "malware"! No other blacklisting site rates my site, because it's virtually invisible, and there's no content delivered by that site, apart from the IPN cgi handler, which delivers nothing but an empty reply with either status 200 or 500, depending on the content.
Which means I now have to get Talos to remove that malware rating (which is still pending 24 hours later!). Interestingly, Talos only rates the domain, not all sites served by that server's IP address. Therefore, even payments.tempel.org, which is literally nothing but a ServerAlias to paypal-api.tempel.org, is rated fine.
Paypal support also explained that the notification URL is stored in the database, and gets re-used when trying to re-send a failed notification, hence it would keep using the old (currently malware-rated) URL despite me having told Paypal to use a different URL now.
But now, a day later, trying resend again on the failed message, suddenly does use the newly set URL, regardless of Paypal support's explanation that this would not happen with re-sends.
So, the moral of the story: Sometimes it's not your fault but it's Paypal who gets this wrong. Or Cisco.
Also worth noting: Paypal won't alert you if they suddenly decide to consider your IPN URL part of a malware site. Nothing in the help or their testing tools will tell you why they're not contacting you any more, leaving you guessing until you contact them (In that regard, the initial answer (now deleted) was right to suggest that I need to contact Paypal directly because Paypal had blacklisted me for some reason). And they can't even whitelist you, but instead leave you fighting with Cisco over getting your rating back to "harmless".
As per the paypal security upgrade on Jan 17th 2016 they are saying that the server needs to be installed with a ssl server with ssl of algorithm SHA-256 and the certificate needs to verify with a G5 ROOT certificate. But my doubt here previusly i can test the paypal sandbox payment in my localhost(a server without https) and it was worked perfectly. But as per the new upgrade from the paypal team is there any option to check the api service in sandbox in a http server(may be on localhost). When i try this i got a handshake_failure exception.
This was my mistake and finally i understood that ssl not needed. When i have update the paypal sdk jar to 1.4 the issue cleared.
We develop local apps that redirect to a secure web host which then sends the relevant FB app info to our FB app which in turn redirects back to our web server which redirects back to our local app. The local app stores the relevant FB user info so that user interaction is then posted to FB as per their approval. Everything works perfectly except for our latest project.
Our latest project running in Dubai is having latency issues between FB, the web server and our localhost on its return from the FB app authorisation. When the PHP script execution time was set to 30 seconds the redirect would timeout. We have increased this execution duration and the app works again but the wait is not ideal as ppl are queued in malls waiting to try out the activation.
I see it is possible to setup SSL on the localhost server as per: How do I allow HTTPS for Apache on localhost?
So my question is: Would FB allow this SSL connection or would the certificate have to come from an authority on a certified web server?
I was thinking of using the localhost WAMP server as the web server aswell and setting up its own OpenSSL to try reduce the latency issues.
I never built the original application so does the FB PHP SDK even need to be hosted on a secure site?
I have a website where i added facebook og tags. http://bowarrow.de No matter what i try and what i change i always get a 403 Error in the debugger.
Though it can access my site somehow. I read every question about this and in the last question i asked about it, no one could really help me. So i decided i ask on facebook and could find the following:
In this case, your site is definitely returning a 403 error to at
least some of the requests from the debugger. This is something
happening in your code or hosting infrastructure
$curl -A "facebookexternalhit/1.1" -i 'http://bowarror.de/' HTTP/1.1
403 Forbidden Date: Mon, 03 Jun 2013 16:03:55 GMT Server: Apache
Content-Length: 2940 Content-Type: text/html
Host Europe GmbH – bowarrow.de [...]
I tried it myself and can confirm that i can't get any access with that facebook header. I asked hostgator several times if there is a server problem on their site and they denied. So maybe i think it might have something to do with host europe, where my domain is registered?
I linked the domain to my hosting through a-records because host europe doesn't support nameserver changes.
Any ideas, help?
Okay i've found probably what caused it. The reason for this was that i use my domain from hosteurope with hostgator. Because hosteurope doesn't allow nameserver changes i had to change the a-records.
Unfortunally there were some AAAA records IPv6 that i didn't change, because hostgator doesn't support ipv6 in my hosting.
Facebook was crawling these ipv6 and sent a 403 to the debugger. (Because there was no ipv6 server that it could have access to)
Yesterday i deleted them and it nearly immediately startet working. See here: https://developers.facebook.com/tools/debug/og/object?q=http%3A%2F%2Fwww.bowarrow.de%2F
Unfortunally it only works for the URL with www. without it i still get a 403.
see here: https://developers.facebook.com/tools/debug/og/object?q=http%3A%2F%2Fbowarrow.de%2F
For anyone using the 10Web Social Post Feed WordPress plugin, follow these steps:
Go to Facebook Feed WD > Options page and press Uninstall.
Uninstall the plugin by following the steps in this video.
Navigate to Plugins page and delete Facebook Feed WD
Reinstall and activate it.
Re-Authenticate your facebook account and recreate your feeds.
I am working on my first app for Facebook and facing (probably) with the SSL problem. If I am testing the app, so it's working well. But then I wanted to test the app by my friend - so I assigned him the role "Tester", he accepted it and I sent him the link to the app.
If he opened the app, he got the error The website is not available - Error 501 (net::ERR_INSECURE_RESPONSE): Unknown error
I started google it and it looks that the cause is the missing SSL certificate on my hosting, where the app is stored.
BUT - how is possible, that the app is working me well without the SSL and to my friend doesn't? If the SSL is required for Facebook apps, why I didn't get the same error?
(I set Secure Canvas URL: to https://example.com/fb-app-directory/, however I don't have at this domain and hosting any SSL certificate).
I never used before SSL. I bought the domain name on Namecheap and hosting on Hostgator. So now, I should buy a SSL certificate from the offer (http://www.namecheap.com/ssl-certificates.aspx) of Namecheap, right?
Would be suitable for the Facebook app the cheapest one?
Look, this SSL problem can only be solved by purchasing a valid SSL certificate or looking for a server which can host your app and is SSL certified such as:
phpfog.com - Provides you with some limited space and database service.
heroku.com - Does not provide any storage space for saving dynamically generated data. To have that service, you have to buy the Amazon buckets service which, again, is a costly affair.
If you don't want to invest any money, I would recommend that you go with phpfog - it is easy and its documentation is pretty good.
You should buy an SSL cert in order for everyone to be able to access your app. Your friend probably has his settings set so that he browses Facebook securely, in this case he is hitting https://example.com/fb-app-directory/, not your actual URL.
The cheapest one isn't the best one, but it should work as long as it's valid. I would suggest using Heroku though, as that way you get everything you need - for free :)
Use a proxy in heroku.com and bring your page in secure domain as https://yourapplication.herokuapp.com/
"Starting October 1, 2011 Facebook will require a valid SSL Certificate for all pages and applications hosted outside of Facebook."
http://www.wpcode.net/fb-ssl.html/
Maybe you are visiting your application with http://apps.facebook.com/... and your friend is visiting with https://apps.facebook.com/....
Another possibility is that your friend has checked "Browse Facebook on a secure connection (https) whenever possible" under "Account Security".
Try ngrok. It exposes a local web server with just one command:
ngrok 80
After this you can access your localhost like this: xxxxxxxx.ngrok.com