Bing Ads authentication token expired error

Krisztián Püspök 0 Reputation points
2025-06-25T11:21:48.3133333+00:00

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.

Microsoft Advertising API
Microsoft Advertising API
A Microsoft API that provides programmatic access to Microsoft Advertising to manage large campaigns or to integrate your marketing with other in-house systems.
487 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. ethan john 0 Reputation points
    2025-07-02T10:08:49.3933333+00:00

    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.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.