I got this error
Array ( [Type] => [Title] => Forbidden [Status] => 403 [Detail] => AuthenticationUnsuccessful [Instance] => 114c05dd-3284-43bb-890f-223999170169 [Extensions] => Array ( ) )
is there some wrong in my code? or my App in Xero is not working? or it needs to be configured?
I want to pull the data of the Invoice in Xero API
<?php
defined('BASEPATH') or exit('No direct script access allowed');
class Overdueinvoice extends MY_Controller
{
private $client_id;
private $client_secret;
private $redirect_uri;
private $authorization_endpoint;
private $token_endpoint;
private $scopes;
private $state;
private $xero_tenant_id;
public function __construct()
{
parent::__construct();
$this->load->helper('url');
// Initialize your OAuth 2.0 credentials here
$this->client_id = 'YOUR_CLIENT_ID';
$this->client_secret = 'YOUR_CLIENT_SECRET';
$this->redirect_uri = 'YOUR_REDIRECT_URI';
$this->authorization_endpoint = 'https://login.xero.com/identity/connect/authorize';
$this->token_endpoint = 'https://identity.xero.com/connect/token';
$this->scopes = 'offline_access openid profile email accounting.transactions';
$this->state = '123';
$this->xero_tenant_id = 'YOUR_XERO_TENANT_ID';
}
public function index()
{
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE");
header("Access-Control-Allow-Headers: Content-Type, Authorization");
if (isset($_GET['code'])) {
$this->handleXeroAuthorization();
} else {
$this->redirectToXeroAuthorization();
}
$data["title"] = "Overdue Invoices | Tremendio Portal";
$data["pagename"] = "Overdue Invoices";
$this->load_page2("overdueinvoice", $data, "overdueinvoice_footer.php", "overdueinvoice_header.php");
}
private function handleXeroAuthorization()
{
// Xero OAuth 2.0 Credentials
$client_id = $this->client_id;
$client_secret = $this->client_secret;
$redirect_uri = $this->redirect_uri;
$authorization_endpoint = $this->authorization_endpoint;
$token_endpoint = $this->token_endpoint;
$scopes = $this->scopes;
$state = $this->state;
$xero_tenant_id = $this->xero_tenant_id; // Get the Xero tenant ID
// Step 1: Handle the callback with the authorization code
$authorization_code = $_GET['code'];
// Step 2: Exchange the authorization code for an access token
$token_request = array(
'grant_type' => 'authorization_code',
'code' => $authorization_code,
'redirect_uri' => $redirect_uri,
);
$curl = curl_init($token_endpoint);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($token_request));
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Authorization: Basic ' . base64_encode($client_id . ':' . $client_secret),
));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$token_response = curl_exec($curl);
curl_close($curl);
// Step 3: Handle the access token and make API requests with it
$token_data = json_decode($token_response, true);
if (isset($token_data['access_token'])) {
// Access token acquired, use it to make API requests, including the Xero tenant ID
$access_token = $token_data['access_token'];
// Store the access token and possibly the refresh token in your session
$this->session->set_userdata('access_token', $access_token);
$this->session->set_userdata('refresh_token', $token_data['refresh_token']);
// Continue with your existing CodeIgniter code to fetch Xero data using the access token and tenant ID
$api_url = 'https://api.xero.com/api.xro/2.0/Invoices?tenantId=' . $xero_tenant_id;
$headers = array(
'Authorization: Bearer ' . $access_token,
'Content-Type: application/json',
);
$ch = curl_init($api_url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
// Process and use the $response data as needed
// You can return the data or do further processing here
$data['xero_data'] = json_decode($response, true); // Assuming the response is JSON
} else {
// Handle the case where access token retrieval failed
echo 'Access token retrieval failed';
}
$this->load->view('overdueinvoice', $data);
}
private function redirectToXeroAuthorization()
{
// Step 4: Redirect the user to Xero's authorization page with scopes and state
// Use class-level properties, not local variables
$client_id = $this->client_id;
$client_secret = $this->client_secret;
$redirect_uri = $this->redirect_uri;
$authorization_endpoint = $this->authorization_endpoint;
$token_endpoint = $this->token_endpoint;
$scopes = $this->scopes;
$state = $this->state;
// The rest of your code remains the same
$authorize_url = $this->authorization_endpoint . '?client_id=' . $client_id . '&redirect_uri=' . $redirect_uri . '&response_type=code&scope=' . $scopes . '&state=' . $state;
header('Location: ' . $authorize_url);
exit;
}
}
Using the instance id 114c05dd-3284-43bb-890f-223999170169 that you received in the response, I can see that the 403 error was thrown because the tenantID is missing from the request's header.