Adventures in PayPal: First steps to gaining an access token using the REST API


Spoiler alert: if you've come here to find a solution on how to use the PayPal API with MAMP, then I apologise in advance that I can't be of help. I can only report the issues that I encountered when testing its compatibility.

To begin

So I've been dabbling in PayPal's REST APIs and have found that while using cURL from the OS X/macOS terminal is straightforward getting this stuff working on my hosted website wasn't as straightforward without piecing together some code from around the web. I'm not going to go through the steps of setting up a sandbox client id and secret here, for that you need to go over to http://developer.paypal.com. I am also not going to tackle the subject of setting up the necessary PayPal account for utilising the API. Neither am I going to enter into how you obtain SSL certificates. Here I'll be dealing with the real world hurdles of code being placed on your website that is going to work. And this is going to be reported as I go along, so there may well be difficulties ahead that I can't at present predict.

Code: 1

The first useful piece of code is this:
<?php

if (!curl_version()['features'] & CURL_VERSION_SSL) {
    echo "SSL is not supported with this cURL installation.";
}
else { 
   echo "You have cURL version: ".curl_version()['version'].". ";
   echo "You have SSL/NSS version: ".curl_version()['ssl_version'];
}

?>
It is rejigged from a user comment on the official PHP site. The code will tell you whether SSL is supported and then SSL/NSS information.

With MAMP 3.2.1 I encountered the error: "error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure". There are a number of suggested solutions to this but I haven't yet had time to try any of them. One of the problems is I believe that an old version of OpenSSL (OpenSSL/0.9.8) runs on MAMP that doesn't support TLS but installing the newer version is in itself supposedly a challenge.

Once you've passed this first hurdle and found out that you are probably going to be OK, then we can start testing for sure that we can retrieve an access token.

Code: 2

<?php

// http://stackoverflow.com/questions/15729167/paypal-api-with-php-and-curl
// https://github.com/paypal/adaptivepayments-sdk-php/issues/24
// https://github.com/paypal/rest-api-curlsamples/blob/master/execute_all_calls.php

$clientId = "Replace this string with your ID";
$secret = "Replace this string with your Secrect";

function get_access_token($url, $postdata) {
 global $clientId, $clientSecret;
 $curl = curl_init($url); 
 curl_setopt($curl, CURLOPT_POST, true); 
 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
 curl_setopt($curl, CURLOPT_USERPWD, $clientId . ":" . $clientSecret);
// curl_setopt($ch, CURLOPT_SSLVERSION, 1);
// curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'TLSv1');
 curl_setopt($curl, CURLOPT_HEADER, false); 
 curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 
 curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata); 
 // curl_setopt($curl, CURLOPT_VERBOSE, TRUE);
 $response = curl_exec( $curl );
 if (empty($response)) {
     // some kind of an error happened
     die(curl_error($curl));
     curl_close($curl); // close cURL handler
 } else {
     $info = curl_getinfo($curl);
  echo "Time took: " . $info['total_time']*1000 . "ms\n";
     curl_close($curl); // close cURL handler
  if($info['http_code'] != 200 && $info['http_code'] != 201 ) {
   echo "Received error: " . $info['http_code']. "\n";
   echo "Raw response:".$response."\n";
   die();
     }
 }
 // Convert the result from JSON format to a PHP array 
 $jsonResponse = json_decode( $response );
 return $jsonResponse->access_token;
}
echo get_access_token('https://api.sandbox.paypal.com/v1/oauth2/token','grant_type=client_credentials');

?>

You'll notice some URLs at the head of the code. These are stopping points along the way but this code is from the PayPal Github resources and was last updated a few years ago. You'll also see some commented out code, the first two lines (after the URLs) that have been commented out were suggestions of how to get things working but I found were unneeded in the end for my own setup but might be useful to others.

The more recent resources are harder to unpick and separate out, so I've started here and will then endeavour to use this code as a starting point from which to translate other API calls into PHP. The reason for starting with PHP is because it is widely understood and a well-supported language and is more likely to have the required libraries pre-installed than perhaps others. And this post is more about getting things running with what you have than needing to install new stuff onto servers.


Comments