The following function gives a validation error instead of the token:
failed to validate oAuth signature and token
I faced same issue, what I was missing is passing header in to the curl request. As shown in this question, I was also sending the $header = array('Expect:'), which was the problem in my case. I started sending signature in header with other data as below and it solved the case for me.
$header = calculateHeader($parameters, 'https://api.twitter.com/oauth/request_token');
function calculateHeader(array $parameters, $url)
{
// redefine
$url = (string) $url;
// divide into parts
$parts = parse_url($url);
// init var
$chunks = array();
// process queries
foreach($parameters as $key => $value) $chunks[] = str_replace('%25', '%', urlencode_rfc3986($key) . '="' . urlencode_rfc3986($value) . '"');
// build return
$return = 'Authorization: OAuth realm="' . $parts['scheme'] . '://' . $parts['host'] . $parts['path'] . '", ';
$return .= implode(',', $chunks);
// prepend name and OAuth part
return $return;
}
function urlencode_rfc3986($value)
{
if(is_array($value)) return array_map('urlencode_rfc3986', $value);
else
{
$search = array('+', ' ', '%7E', '%');
$replace = array('%20', '%20', '~', '%25');
return str_replace($search, $replace, urlencode($value));
}
}