Home > Mobile >  Xero PHP Oauth in Laravel throws 401 AuthenticationUnsuccessful when updating contacts
Xero PHP Oauth in Laravel throws 401 AuthenticationUnsuccessful when updating contacts

Time:07-21

I am trying to update Xero contacts, which is part of the invoice in Laravel. I am using Xero-php-oauth2. I have tried

$xero = resolve(AccountingApi::class);
$invoice = new Invoice();
$invoice->setLineItems($lineItems);
$result = $xero->updateInvoice($tenantId, $invoice_id, $invoice);
$contactId = $result->getInvoices()[0]['contact']['contact_id'];
$contact = $this->newContact();
$contact->setContactId($contactId);
//$tenantId, $contactid, and $contact are correct
$xero->updateContact($tenantId, $contactId, $contact);

The request I am trying to send is like following, but the response returns 401 AuthenticationUnsuccessful

Request {#1160 ▼
  -method: "POST"
  -requestTarget: null
  -uri: Uri {#1212 ▼
    -scheme: "https"
    -userInfo: ""
    -host: "api.xero.com"
    -port: null
    -path: "/api.xro/2.0/Contacts/134ab308-7d07-4c2d-a770-c01325947ede"
    -query: ""
    -fragment: ""
  }
  -headers: array:6 [▼
    "Host" => array:1 [▼
      0 => "api.xero.com"
    ]
    "User-Agent" => array:1 [▼
      0 => "[xero-php-oauth2 (2.11.0)]"
    ]
    "xero-tenant-id" => array:1 [▼
      0 => "TENANT_ID_HERE"
    ]
    "Accept" => array:1 [▼
      0 => "application/json"
    ]
    "Content-Type" => array:1 [▼
      0 => "application/json"
    ]
    "Authorization" => array:1 [▼
      0 => "Bearer BEARER_TOKEN_HERE"
    ]
  ]
  -headerNames: array:6 [▶]
  -protocol: "1.1"
  -stream: Stream {#1217 ▼
    -stream: stream resource @755 ▼
      wrapper_type: "PHP"
      stream_type: "TEMP"
      mode: "w b"
      unread_bytes: 0
      seekable: true
      uri: "php://temp"
      options: []
    }
    -size: null
    -seekable: true
    -readable: true
    -writable: true
    -uri: "php://temp"
    -customMetadata: []
  }
}

xero-php-oauth2 sends request along with following options to GuzzleHttp\Client, and It seems to throw error at AccountingAPI@updateContactWithHttpInfo() in following line

$response = $this->client->send($request, $options);`

I also tried to add accounting.contacts scope before calling but it does not work.

$options = ['scope' => ['openid email profile offline_access accounting.settings accounting.transactions accounting.contacts accounting.journals.read accounting.reports.read accounting.attachments']];

Error message

[401] Client error: `POST https://api.xero.com/api.xro/2.0/Contacts/134ab308-7d07-4c2d-a770-c01325947ede` resulted in a `401 Unauthorized` response: {"Type":null,"Title":"Unauthorized","Status":401,"Detail":"AuthenticationUnsuccessful","Instance":"94b725d8-435b-4a98-be (truncated...)

It is working when I create or update invoices with almost identical request. Even identical bearer token. Also creating new contact if I pass that with new invoice. But not updating already existing contact. How can I fix this?

CodePudding user response:

The answer is in the 401 response: "Title":"Unauthorized". You're not unauthenticated, you're unauthorised.

From the docs:

When your app is requesting authorisation from a user it will need to ask for a set of scopes. These scopes will be displayed to the user and describe what data your app will be able to access.

You supply the relevant scopes when requesting authentication with OAuth.

Your OAuth request (i.e. when you request authentication from the user) will be missing the accounts.contacts scope. Add it, and you should be able to successfully call those API endpoints.

  • Related