Integrating PayPal IPN with PHP - cURL error: SSL CA cert - php

I'm in the midst of integrating PayPal into my website. At this stage, I am using the PayPal Sandbox along with the Instant Payment Notification (IPN) simulator. For the listener itself, I'm using Micah Carrick's code. When sending an IPN through the sandbox, I received the follow error:
cURL error: [77] Problem with the SSL CA cert (path? access rights?)
I originally thought the problem was that my website lacked a SSL certificate, so I purchased one and installed it. Unfortunately, that did not solve my problem. After doing some more research I am under the impression that I am missing a certificate file from PayPal or from cURL. I downloaded one of the developer bundles (pp_php_soap_sdk_1) from PayPal and copied the api_cert_chain file into the directory of my ipn code, but that was unsuccessful. When looking at the certificate, it appears to be expired, so perhaps that is the problem. Any ideas?

Feel like an idiot, but the problem stemmed from the location I was storing the SSL CA cert.

The file ipn_listener.php points to a file called "api_cert_chain.crt". You're most likely missing it. You can download it from: https://cms.paypal.com/cms_content/US/en_US/files/developer/PP_PHP_SOAP_SDK.zip
Download and extract the zip. The file "api_cert_chain.crt" is located in the folder: PP_PHP_SOAP_SDK/php-sdk/lib/PayPal/cert. Upload the file to the directory /cert/ on your server (might need to create the folder).
I came across the solution from this website (last post): Webmaster World.

In the "ipn_listener.php" file there is code that points to the api_cert_chain.crt
dirname(__FILE__)."/api_cert_chain.crt");
You need to make sure that the path to that .crt is actually pointing to where the .crt is on your webserver.

Related

PHP - Stripe Webhook is giving a TLS Error

I am trying to set up webhooks for Stripe. The webhook connects to https://authdomain.subd.com which then forwards the request (after adding a validation token) to http://www.workdomain.com
Both these urls are hosted on the same server.
Payment Intents generated from http://www.workdomain.com successfully go into Stripe.
(Update: I can also query run successful Stripe commands like \Stripe\Charge::all() from authdomain, which verifies that TLS 1.2 supported)
However the webhook returns a TLS error when trying to connect to https://authdomain.subd.com.
I have whitelisted Stripe's IP as listed here enter link description here
This process is working fine when I test it locally using a CLI, so I know I don't have to install Stripe on my auth layer project.
But for some reason when I try this on my live server it doesn't work on my live server.
Is there any reason this is happening?
Thanks for the help
This can be caused by any number of things, but the most common is an incomplete certificate chain. I'd recommend using Qualys' SSL Labs tool to check your server's TLS configuration. For example, to check the domain you shared:
https://www.ssllabs.com/ssltest/analyze.html?d=https://authdomain.subd.com&hideResults=on
If any of the intermediate chain certificates are marked as "missing" in this report, it can cause Stripe to refuse to connect to your webhook (as Stripe can't tie your TLS certificate back to a known global CA). Usually the fix is to download any missing certificates (the tool tells you which one) and add them to your production TLS configuration / bundle. You may need the help of your hosting company to configure this.
To test your repair, re-run the SSL Labs check after deploying the new certificate bundle and see if it's now resolved. Beyond that, if the problems persist I'd recommend writing Stripe support!

SSL Error: UNABLE_TO_VERIFY_LEAF_SIGNATURE

I uploaded my website build with laravel on ubuntu server and used Instamojo to accept payments. I have purchased SSL from Namecheap (PositiveSSL).
The problem is my webhook URL is not working. I tried accessing the URL through Postman and got an error 'Could not get any response'. The screenshot of Postman Console-
This can be caused by failing to bundle the intermediate certificates with the server certificate. You will have at least one intermediate certificate that needs to be bundled with you server cert.
For more information please read the Complete Tutorial for installing SSL on Apache

Apple Pay with Woocommerce (Stripe) "Unable to verify domain - Forbidden"

Everything is setup and I have .well-known folder in my root directory with file.
My Stripe account is activated and my domain is added under Apple Pay tab.
Now when I enable Stripe, I get this notification:
Apple Pay domain verification failed. Please check the log to see the
issue.
When I check the error log, I see:
Error: Unable to verify domain - Forbidden
My hosting is on OVH.
Got the solution and now its working :)
Stripe no longer supports API requests made with TLS 1.0. Please update HTTPS connections with TLS 1.2 or later.
Hosting server is using TLS older version which is not supported anymore
due to security
The upgrade process will be seamless for most users. At the application layer, SHA-2 and TLS 1.2 behave identically to their older versions. You won’t need to change your code, but might need to upgrade your operating system or packages.
for ref:https://stripe.com/blog/upgrading-tls
Hope it will help!!
Have you added Domain Verification file into the .well-known/ folder.
If not please find it in your Stripe dashboard download it or here and upload to .well-known/ folder.
Make sure that you need to access your verification file by your URL https://example.com/.well-known/apple-developer-merchantid-domain-association
In my Case i was using WHMCS on a subdomain, and had to insert the apple merchant file on the root path ./well-known of my domain
subdomain.domain.com/.well˜
domain.com/.well˜
Solved my problem

In App Purchase (Sandbox) - Receipt Validation Fails Because of curl / SSL

I have noticed that my server-side receipt validation code is failing only for the sandbox (the live version of my app in the store works fine, but on Xcode, where I am testing the next version, receipt validation always fails).
I tracked the problem to the php/curl code where I contact the iTunes server (https://sandbox.itunes.apple.com/verifyReceipt), and I get this error from curl:
SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:func(144):reason(134)
I wonder if this has anything to do with the russian guy and his hack...
But it only happens with my sandbox code. The live version seems to be working...
Any clues?
Perhaps I should use the 'live' iTunes server for both sandbox and live, as detailed here?
in app purchase, production receipt validation now validating sandbox purchases?
(Wasn't aware of this change. Is it still OK?)
EDIT I modified my sandbox-php code to use the LIVE iTunes server (URL: https://buy.itunes.apple.com/verifyReceipt), and test-user purchases/repurchases are working now. I am still puzzled... Has the sandbox server been deprecated? Does it identify itself with an SSL certificate different than the live environment, which certificate has been revoked?
Looks like Apple recently reupped the SSL cert for Sandbox and it is signed correctly with the subject alternate name domain sandbox.itunes.apple.com. but didn't sign it with the correct URL (or just used the one from Live and not bothered with Sandbox). They instead signed it with buy.itunes.apple.com which broke any cURL requests (our server had the same problem). As a workaround for now, we have used the option:
if ($isSandbox) curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
This turns off SSL verification, so use with caution as it could lead to man-in-the-middle attacks. I don't think this is a huge deal on Sandbox since it is test users in a test environment.
Edit:
Actually, Apple pointed out that the CA cert bundle with a default cURL install prior to 7.18.0 is severely outdated. http://curl.haxx.se/docs/sslcerts.html
We may have had a server update recently that broke our cURL installation, but I'm not our Sys Admin so I really don't know for sure. But take a look at the link as that includes the workaround I mentioned above (#1), and a few other options, including updating the CA cert bundle.
Edit:
I wanted to add another side-note here. It seems as though there was a bug fix in cURL version 7.19.7 that dealt with Subject Alternative Names.
libcurl-OpenSSL failed to verify some certs with Subject Alternative Name
So this could in fact be partially Apple, and partially cURL. Apple's certificate renewal with the usage of the SAN possibly broke anything still on any version older than 7.19.7. We are still testing as to whether this is the case on our server.
Edit:
We found out that the issue was not the version of cURL we were using, but it was with the CA cert pem file we needed cURL to point to. It is #2 via the cURL link above, but in PHP it looks like this:
if ($isSandbox) curl_setopt($ch, CURLOPT_CAINFO, '/etc/ssl/certs/cacert.pem');
You can grab the latest CA cert pem file from http://curl.haxx.se/docs/caextract.html

Testing if a client certificat is installed in the client browser

I was wondering if any of you know if it is possible in javascript or php to test if a client has a specific client certificate installed in the browser.
The thing is that we have a server certificate installed but to be recognized by the clients, they need 2 client certificates that make them recognize the authority of the issuer of our server certificate. We would like to test the browser for these 2 certificates, if there are not there, we want to propose the client to download them before to enter in https mode...
Anybody can help? Please detail your answer if you know one.
You can do it client side by using javascript to request a known file from a secured (https) source. if the request fails then it means the client refused to accept your certificate (or another network error) at this point you could popup a message to ask the user to install the root certificate with a link to the root certificate.
This must be done from a non secure page. otherwise the user may refuse your certificate and never load the page to start with and therefore your javascript never runs
It can't be done in PHP because php (which is server side) cannot determine whether the client browser has a particular root ca installed
I however would not do this. get a proper certificate instead.
You appear to have insufficient understanding of how SSL works in general. I suggest spending some time understanding how SSL works and how certificates are used.
DC
to learn about sending and receiving http responses with javascript read this page..
http://www.w3schools.com/XML/xml_http.asp
It can be used to send and receive any text data, not just xml. It is real easy to implement but you must be aware of browser version issues.
DC
what about a warning message that will be hidden by a javascript which will be loaded from your https site.
in the warning message you can link the windows update site or wherever the updated root certifcates can be downloaded to their browser.
PHP is a server side language. If you really want to test this then you need to do it with JavaScript and then send back an AJAX request to PHP.
But I think there is another solution to your problem. Normally when a CA change their name etc. they have usually new "Intermediate Certificates" you can use. (If you have an apache httpd server then you can search for "ca bundle" on their website as well.) With this bundle you can send the new CA certificate along with your certificate.
Forcing your users to download and install a homegrown CA certificate is ugly and hateful. Instead, show them the love and pay the $30 US to get an SSL certificate signed by a reputable, already trusted, CA.

Categories