Search code examples
phpcurlnetsuiterestlet

NetSuite RESTlet works in Postman but not in cURL


We are posting a new customer lead to NetSuite using a RESTlet. We get a successful add in Postman, but when I grab the PHP - cURL code from Postman to replicate in my code, I get the following:

{"error" : {"code" : "INVALID_LOGIN_ATTEMPT", "message" : "Invalid login attempt."}}

Here is the code I'm using. Again, this is the "PHP - cURL" code auto-generated by Postman with my variables substituting for the values.

$post_fields = '{
    "first_name": "' . $first_name . '",
    "last_name": "' . $last_name . '",
    "email": "' . $email . '",
    "phone": "' . $phone . '",
    "shipping_address": {
        "name": "' . $first_name . ' ' . $last_name . '",
        "address_1": "",
        "address_2":"",
        "city": "' . $city . '",
        "state": "' . $state . '",
        "postal_code": "' . $zip . '",
        "country": "US"
    }
}';

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://xxxxxxx.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=904&deploy=1',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => $post_fields,
  CURLOPT_HTTPHEADER => array(
    'Authorization: OAuth realm="xxxxxxx",
        oauth_consumer_key="xxxxxxxxx",
        oauth_token="xxxxxxxx",
        oauth_signature_method="HMAC-SHA256",
        oauth_timestamp="' . time() . '",
        oauth_nonce="' . $nonce . '",
        oauth_version="1.0",
        oauth_signature="xxxxxxxxxxx"',
    'Content-Type: application/json',
    'Cookie: NS_ROUTING_VERSION=LAGGING'
  ),
));

$response = curl_exec($curl);
curl_close($curl);

The only thing I can think of is I'm using the oauth_signature value that Postman generates, but I've run it numerous times in Postman and the signature is identical each time and it works there.

Any thoughts on what is incorrect in this setup?


Solution

  • If you're using oauth you have to resign each request because each request will have a different timestamp and a different nonce.