Thanks for sharing all the details this looks like a well structured setup. The token expiration issue might be tied to the sandbox environment not fully supporting the token refresh flow or missing billing setup. You might want to try it in production with a verified account and payment method to see if the issue persists.
Bing Ads authentication token expired error
I'm making a Laravel 11 app where i want to display Bing Ads data. The login process is working, but even if I'm setting the scopes and they appear on the consent screen I only getting back 'User.Read' in the approved scopes. The login process is made with the Socialite package and it's getting back the user just fine.
On the sandbox page I'm stuck at after the creation of the account. I'm on the dashboard and want some data but on the top it displays a warning message that i need to add a payment option. I can't do that on the sandbox because I got error.
The code:
The redirect:
public function connect(int $domain_id)
{
return Socialite::driver('microsoft')
->scopes([
'offline_access',
'https://ads.microsoft.com/msads.manage',
])
->with([
'prompt' => 'consent'
])->redirect();
}
The callback:
public function callback()
{
try {
$microsoft_user = Socialite::driver('microsoft')->stateless()->user();
$domain->microsoftToken()->create([
'domain_id' => $domain->id,
'microsoft_id' => $microsoft_user->id,
'name' => $microsoft_user->name,
'email' => $microsoft_user->email,
'access_token' => $microsoft_user->token,
'refresh_token' => $microsoft_user->refreshToken,
'expires_at' => now()->addSeconds($microsoft_user->expiresIn),
]);
return redirect()->route('profile')->success('Microsoft account connected successfully!');
} catch (Exception $e) {
logger()->error('Microsoft callback error: '.$e->getMessage());
return redirect()->route('profile')->error('Failed to get Microsoft account! Please try again later or contact support.');
}
}
If I'm going with this methods the login process is working and i got the access and refresh tokens. After the login i want to get the ad accounts for this user with:
public function refreshToken(string $refresh_token, string $token_id) {
$auth_controller = new MicrosoftAuthController();
$new_token = $auth_controller->refresh($refresh_token);
$microsoft_token = MicrosoftToken::find($token_id);
$microsoft_token->update([
'access_token' => $new_token['access_token'],
'refresh_token' => $new_token['refresh_token'],
'expires_at' => now()->addSeconds($new_token['expires_in']),
]);
return $microsoft_token;
}
public function getServiceClient(string $access_token, string $refresh_token) {
$auth = (new OAuthWebAuthCodeGrant())
->withClientId(config('services.microsoft.client_id'))
->withClientSecret(config('services.microsoft.client_secret'))
->withRedirectUri(config('services.microsoft.redirect'))
->withEnvironment(ApiEnvironment::Sandbox);
$auth->OAuthTokens = (new OAuthTokens())
->withAccessToken($access_token)
->withRefreshToken($refresh_token);
$auth_data = new AuthorizationData();
$auth_data->Authentication = $auth;
$auth_data->DeveloperToken = config('services.microsoft.developer_token');
try {
return new ServiceClient(
ServiceClientType::CustomerManagementVersion13,
$auth_data,
ApiEnvironment::Sandbox);
} catch (\Exception $e) {
Log::error('Failed to create service client: ' . $e->getMessage());
return [
'error' => 'Failed to create service client: ' . $e->getMessage(),
];
}
}
public function getClientAdAccounts($token) {
if(now()->greaterThan($token['expires_at'])) {
$new_token = $this->refreshToken($token['refresh_token'], $token['id']);
$token = $new_token;
}
$service_client = $this->getServiceClient($token['access_token'], $token['refresh_token']);
$get_user_request = new GetUserRequest();
$get_user_request->UserId = null; // null to get the current user;
$user = $service_client->GetService()->GetUser($get_user_request)->User;
}
The service client is created and at the GetAccountsInfo function i get "Authentication token expired. Please renew it or obtain a new token." (Error code: 109) error.
$user = $service_client->GetService()->GetUser($get_user_request)->User;
The client_id and client_secret is from azure portal app. The developer token is 'BBD37VB98' found in the documentation.
Tried with production tokens and accounts and it not worked also only I got error 105.
I'm at this error for a while now and I don't see what am I doing wrong.