PHP: cURL SSL Verification

While trying to figure out of PayPal Payment Data Transfers I came over an issue that caused my cURL requests to fail.

These were the cURL options I used:

curl_setopt_array($request, array
(
    CURLOPT_URL => 'https://www.sandbox.paypal.com/cgi-bin/webscr',
    CURLOPT_POST => TRUE,
    CURLOPT_POSTFIELDS => http_build_query(array
    (
        'cmd' => '_notify-synch',
        'tx' => $tx,
      'at' => $your_pdt_identity_token,
    )),
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_HEADER => FALSE
));

Worked great on my web host, but locally didn’t get any response. Turned out I was getting an error, SSL certificate problem: unable to get local issuer certificate, and here are two ways to fix it.

Globally via php.ini

  1. Go to curl.haxx.se/docs/caextract.html
  2. Download the cacert.pem and put it somwhere, for example C:\wamp\cacert.pem
  3. Edit the curl.cainfo property in the curl section:
    [curl]
    ; A default value for the CURLOPT_CAINFO option. This is required to be an
    ; absolute path.
    curl.cainfo = C:\wamp\cacert.pem
  4. Restart the web server

Locally via curl option

  1. Go to curl.haxx.se/docs/caextract.html
  2. Download the cacert.pem and put it for example next to your script.
  3. Set the CURLTOPT_SSL_VERIFYPEER and CURLOPT_CAINFO options when you’re executing a curl request
    curl_setopt_array($request, array
    (
        // Other options...
        CURLOPT_SSL_VERIFYPEER => TRUE, // Verify peers
        CURLOPT_CAINFO => 'cacert.pem' // Path to file with certificates
    ));

Why?

Since we are using the HTTPS protocol we need to somehow verify the one we are talking to. Your browser does this by checking their certificate against several built-in certificate stores from trusted certificate suppliers, like for example VeriSign.

cURL does this verification automatically as well, except on my local machine PHP wasn’t configured with a default store to use.

Solution was as you can read above, to find one, and let PHP know about it, either through php.ini or through curl options.

Voila!

  • Perfect! Thanks!

  • Sirius Black

    how did you know sir that CURL wasnt verifying the certificates automatically ? . i have a script using CURL , i tested it with SandBox and its working from Database to Sending Emails but when i tested on Live, no database, no emails

    • Sirius Black

      or rather. more elaborate question . is this working on Live Paypal ? / thanks sir

      • It was at least working with Live PayPal when I developed this.

    • It wasn’t a matter of live or sandbox for me. It was local machine vs webhost. On my webhost the code worked fine, while on my localmachine it silently failed. Checked the curl_error, I think, either way I discovered the certificate wasn’t checked correctly. After some Googling I found that there were no certificate file to check against on my system for some reason, so got one manually and told curl to use that one.

  • Hi there, I have to change CURLOPT_SSL_VERIFYPEER => TRUE, to CURLOPT_SSL_VERIFYPEER => 0, then it work. I don’t know the reason but I just want to share.

  • Pingback: PHP Tutorial: PayPal Instant Payment Notification (IPN) | Geekality()