I had a similar problem. Looks like SAGE errors when you try to refresh token on every single request but seems fine if you do it on expiration. My PHP code in Laravel looks like this to retrieve the TOKEN which I store in DATABASE with all the necessary details.
public function getAccessToken()
{
if (!$sageOauthAccessToken = $this->company->sageOauthAccessToken) {
return null;
}
if (Carbon::parse($sageOauthAccessToken->expires_in) > Carbon::now()) {
return $this->company->sageOauthAccessToken->access_token;
}
//refresh TOKEN
$client = new Client();
$response = $client->post('https://oauth.accounting.sage.com/token', [
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/x-www-form-urlencoded',
],
'form_params' => [
'grant_type' => 'refresh_token',
'refresh_token' => $sageOauthAccessToken->refresh_token,
'client_id' => config('services.sage.client_id'),
'client_secret' => config('services.sage.client_secret'),
],
]);
$statusCode = $response->getStatusCode();
if ($statusCode == 200) {
$responseData = json_decode($response->getBody(), true);
//Update TOKEN
SageOauthAccessToken::updateOrCreate(
[
'company_id' => $this->company->id,
],
[
'access_token' => $responseData['access_token'],
'expires_in' => Carbon::now()->addSeconds($responseData['expires_in']),
'refresh_token' => $responseData['refresh_token'],
'refresh_token_expires_in' => Carbon::now()->addSeconds($responseData['refresh_token_expires_in']),
'scope' => $responseData['scope'],
]
);
return $responseData['access_token'];
} else {
// Handle the error response
return json_decode($response->getBody(), true);
}
}