Search code examples
phpxero-api

Xero PHP API Error: "You are not permitted to access this resource"


I have the Xero API setup and the OAuth flow working. I have linked up the "Demo Company UK" as the tenant (Organisation) and have granted my user with Adviser • Contact bank account admin, Payroll admin • Expenses (Admin) permissions (which appears to be the highest level) located here: https://go.xero.com/Settings/Users but I still get the following error. "You are not permitted to access this resource" I have added all the scopes that should cover the requests and have a valid access token but still no good.

'client_id'     => env('XERO_CLIENT_ID'),
'client_secret' => env('XERO_CLIENT_SECRET'),
'redirect_uri'  => env('XERO_REDIRECT_URI'),
'scope'         => 'openid email profile offline_access accounting.transactions accounting.contacts accounting.contacts.read accounting.reports.read',

Example function making a basic call to get the users within the account. The connection to Xero is fine but as soon as I try to request any data the same error is thrown.

public function testXero() {
        $xeroAccessToken = GlobalSetting::where('name', '=', 'xero_access_token')->first();
        $xeroTenantOrganisation = GlobalSetting::where('name', '=', 'xero_tenant_organisation_id')->first();

        $xero = new XeroApp(
            new AccessToken(
                array(
                    'access_token' => json_decode($xeroAccessToken->value)->id_token
                )
            ), $xeroTenantOrganisation->value
        );
        //dd( $xero ); //we have a succesfull connection here...
        
        # Retrieve all contacts
        $contacts = $xero->contacts()->get();                               

        dd($contacts); //error "You are not permitted to access this resource".
 }

Has anybody encountered this issue?


Solution

  • The issue is that I was passing id_token when making a new XeroApp class instance. I failed to see all the other objects in the JSON object stored in the Database (very large). There is an actual access_token that is stored along with some other useful bits of information that I make within my call.

    $xero = new XeroApp(
        new AccessToken(
            array(
                'access_token' => json_decode($xeroAccessToken->value)->access_token,
                'refresh_token' => json_decode($xeroAccessToken->value)->refresh_token,
                'expires' => json_decode($xeroAccessToken->value)->expires,
            )
        ), $xeroTenantOrganisation->value
    );
    
    $contacts = $xero->contacts;
    
    dd($contacts);//RESULTS!!! YES
    

    I will keep this thread open just in case it helps anyone out.