PHP CURL netsuite API throws invalid login and login audit throws invalidSignature in netsuite
Question
I am trying to get customers from NetSuite API in Magento. It throws error
{"type":"https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2","title":"Invalid login attempt, for more details see Login Audit Trail.","status":401,"o:errorCode":"INVALID_LOGIN"}
I checked in the error log in Netsuite. Over there error is invalidSignature.
Please guys help me Where am I going to wrong? I had checked the 10 times signature method process on different websites, but it still says,u the OAuth signature is invalid.
Please Help me, Developers. If any developer has a doubt feel free to ask a question in detail Here is code
<?php
define("NETSUITE_URL", 'https://xxxxxxxxx.suitetalk.api.netsuite.com/services/rest/record/v1/customer/1');
define("NETSUITE_ACCOUNT", 'xxxxxxx');
define("NETSUITE_CONSUMER_KEY", 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
define("NETSUITE_CONSUMER_SECRET", 'xxxxxxxxxxxxxxxxxxxxxxxxx');
define("NETSUITE_TOKEN_ID", 'xxxxxxxxxxxxxxxxxxx');
define("NETSUITE_TOKEN_SECRET", 'xxxxxxxxxxxxxxx');
$oauth_nonce = md5(mt_rand());
$oauth_timestamp = time();
$oauth_signature_method = 'HMAC-SHA1';
$oauth_version = "1.0";
$baseString = urlencode(NETSUITE_URL)."&".urlencode(
"&oauth_consumer_key=".NETSUITE_CONSUMER_KEY
."&oauth_nonce=".$oauth_nonce
."&oauth_signature_method=".$oauth_signature_method
."&oauth_timestamp=".$oauth_timestamp
."&oauth_token=".NETSUITE_TOKEN_ID
."&oauth_version=".$oauth_version
);
$sigString = urlencode(NETSUITE_CONSUMER_SECRET).'&'.urlencode(NETSUITE_TOKEN_SECRET);
$signature = base64_encode(hash_hmac('sha1', $baseString, $sigString, true));
$auth_header = "OAuth "
. 'oauth_signature="' . $signature . '", '
. 'oauth_version="' . rawurlencode($oauth_version) . '", '
. 'oauth_nonce="' . rawurlencode($oauth_nonce) . '", '
. 'oauth_signature_method="' . rawurlencode($oauth_signature_method) . '", '
. 'oauth_consumer_key="' . rawurlencode(NETSUITE_CONSUMER_KEY) . '", '
. 'oauth_token="' . rawurlencode(NETSUITE_TOKEN_ID) . '", '
. 'oauth_timestamp="' . rawurlencode($oauth_timestamp) . '", '
. 'realm="' . rawurlencode(NETSUITE_ACCOUNT) .'"';
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => NETSUITE_URL,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
// CURLOPT_FAILONERROR => true,
CURLOPT_SSL_VERIFYHOST=>false,
CURLOPT_SSL_VERIFYPEER=>false,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"Authorization:$auth_header"
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
?>
Solution
Here is my code which I am using to connect with Netsuite. If anyone has question, feel free to ask me because I did a lot struggle to understand NetSuite API and its structure.
<?php
class callNetsuiteApi{
// PRODUCTION CREDENTIALS
const NETSUITE_CONSUMER_KEY = 'xxxxxxxxxxxxxxxxxxxxxx';
const NETSUITE_ACCOUNT = 'xxxxxxxxxxxxxxxxxx';
const NETSUITE_CONSUMER_SECRET = 'xxxxxxxxxxxxxx';
const NETSUITE_TOKEN_ID = 'xxxxxxxxxxxxx';
const NETSUITE_TOKEN_SECRET = 'xxxxxxxxxxxxxxxxxxx';
public function callRestApi($url){
$oauth_nonce = md5(mt_rand());
$oauth_timestamp = time();
$oauth_signature_method = 'HMAC-SHA1';
$oauth_version = "1.0";
// generate Signature
$baseString = $this->restletBaseString("GET",
$url,
self::NETSUITE_CONSUMER_KEY,
self::NETSUITE_TOKEN_ID,
$oauth_nonce,
$oauth_timestamp,
$oauth_version,
$oauth_signature_method,null);
$key = rawurlencode(self::NETSUITE_CONSUMER_SECRET) .'&'. rawurlencode(self::NETSUITE_TOKEN_SECRET);
$signature = base64_encode(hash_hmac('sha1', $baseString, $key, true));
// GENERATE HEADER TO PASS IN CURL
$header = 'Authorization: OAuth '
.'realm="' .rawurlencode(self::NETSUITE_ACCOUNT) .'", '
.'oauth_consumer_key="' .rawurlencode(self::NETSUITE_CONSUMER_KEY) .'", '
.'oauth_token="' .rawurlencode(self::NETSUITE_TOKEN_ID) .'", '
.'oauth_nonce="' .rawurlencode($oauth_nonce) .'", '
.'oauth_timestamp="' .rawurlencode($oauth_timestamp) .'", '
.'oauth_signature_method="' .rawurlencode($oauth_signature_method) .'", '
.'oauth_version="' .rawurlencode($oauth_version) .'", '
.'oauth_signature="' .rawurlencode($signature) .'"';
return $this->callCurl($header,$url);
}
public function callCurl($header,$url){
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_SSL_VERIFYHOST=>false,
CURLOPT_SSL_VERIFYPEER=>false,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
$header,
"content-type: application/json"
),
));
$response = curl_exec($curl);
curl_close($curl);
$product = json_decode($response, true);
return $product;
}
public function restletBaseString($httpMethod, $url, $consumerKey, $tokenKey, $nonce, $timestamp, $version, $signatureMethod, $postParams){
//http method must be upper case
$baseString = strtoupper($httpMethod) .'&';
//include url without parameters, schema and hostname must be lower case
if (strpos($url, '?')){
$baseUrl = substr($url, 0, strpos($url, '?'));
$getParams = substr($url, strpos($url, '?') + 1);
} else {
$baseUrl = $url;
$getParams = "";
}
$hostname = strtolower(substr($baseUrl, 0, strpos($baseUrl, '/', 10)));
$path = substr($baseUrl, strpos($baseUrl, '/', 10));
$baseUrl = $hostname . $path;
$baseString .= rawurlencode($baseUrl) .'&';
//all oauth and get params. First they are decoded, next alphabetically sorted, next each key and values is encoded and finally whole parameters are encoded
$params = array();
$params['oauth_consumer_key'] = array($consumerKey);
$params['oauth_token'] = array($tokenKey);
$params['oauth_nonce'] = array($nonce);
$params['oauth_timestamp'] = array($timestamp);
$params['oauth_signature_method'] = array($signatureMethod);
$params['oauth_version'] = array($version);
foreach (explode('&', $getParams ."&". $postParams) as $param) {
$parsed = explode('=', $param);
if ($parsed[0] != "") {
$value = isset($parsed[1]) ? urldecode($parsed[1]): "";
if (isset($params[urldecode($parsed[0])])) {
array_push($params[urldecode($parsed[0])], $value);
} else {
$params[urldecode($parsed[0])] = array($value);
}
}
}
//all parameters must be alphabetically sorted
ksort($params);
$paramString = "";
foreach ($params as $key => $valueArray){
//all values must be alphabetically sorted
sort($valueArray);
foreach ($valueArray as $value){
$paramString .= rawurlencode($key) . '='. rawurlencode($value) .'&';
}
}
$paramString = substr($paramString, 0, -1);
$baseString .= rawurlencode($paramString);
return $baseString;
}
}
$obj = new callNetsuiteApi();
$url = "https://xxxxxxxxx.suitetalk.api.netsuite.com/services/rest/record/v1/inventoryItem/".$internalId."?expandSubResources=true";
$response = $obj->callRestApi($url);
?>
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange