1. Go to this page and download the library: Download fooman/xero-php-oauth2 library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
fooman / xero-php-oauth2 example snippets
ini_set('display_errors', 'On');
ague\OAuth2\Client\Provider\GenericProvider([
'clientId' => '__CLIENT_ID__',
'clientSecret' => '__CLIENT_SECRET__',
'redirectUri' => '__REDIRECT_URI__',
'urlAuthorize' => 'https://login.xero.com/identity/connect/authorize',
'urlAccessToken' => 'https://identity.xero.com/connect/token',
'urlResourceOwnerDetails' => 'https://api.xero.com/api.xro/2.0/Organisation'
]);
// Scope defines the data your app has permission to access.
// Learn more about scopes at https://developer.xero.com/documentation/oauth2/scopes
$options = [
'scope' => ['openid email profile offline_access accounting.settings accounting.transactions accounting.contacts accounting.journals.read accounting.reports.read accounting.attachments']
];
// This returns the authorizeUrl with necessary parameters applied (e.g. state).
$authorizationUrl = $provider->getAuthorizationUrl($options);
// Save the state generated for you and store it to the session.
// For security, on callback we compare the saved state with the one returned to ensure they match.
$_SESSION['oauth2state'] = $provider->getState();
// Redirect the user to the authorization URL.
header('Location: ' . $authorizationUrl);
exit();
ini_set('display_errors', 'On');
ge Classe uses sessions for storing token > extend to your DB of choice
$storage = new StorageClass();
$provider = new \League\OAuth2\Client\Provider\GenericProvider([
'clientId' => '__CLIENT_ID__',
'clientSecret' => '__CLIENT_SECRET__',
'redirectUri' => '__REDIRECT_URI__',
'urlAuthorize' => 'https://login.xero.com/identity/connect/authorize',
'urlAccessToken' => 'https://identity.xero.com/connect/token',
'urlResourceOwnerDetails' => 'https://api.xero.com/api.xro/2.0/Organisation'
]);
// If we don't have an authorization code then get one
if (!isset($_GET['code'])) {
echo "Something went wrong, no authorization code found";
exit("Something went wrong, no authorization code found");
// Check given state against previously stored one to mitigate CSRF attack
} elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) {
echo "Invalid State";
unset($_SESSION['oauth2state']);
exit('Invalid state');
} else {
try {
// Try to get an access token using the authorization code grant.
$accessToken = $provider->getAccessToken('authorization_code', [
'code' => $_GET['code']
]);
$config = XeroAPI\XeroPHP\Configuration::getDefaultConfiguration()->setAccessToken( (string)$accessToken->getToken() );
$identityApi = new XeroAPI\XeroPHP\Api\IdentityApi(
new GuzzleHttp\Client(),
$config
);
$result = $identityApi->getConnections();
// Save my tokens, expiration tenant_id
$storage->setToken(
$accessToken->getToken(),
$accessToken->getExpires(),
$result[0]->getTenantId(),
$accessToken->getRefreshToken(),
$accessToken->getValues()["id_token"]
);
header('Location: ' . './authorizedResource.php');
exit();
} catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {
echo "Callback failed";
exit();
}
}
ini_set('display_errors', 'On');
his class to deserialize error caught
use XeroAPI\XeroPHP\AccountingObjectSerializer;
// Storage Classe uses sessions for storing token > extend to your DB of choice
$storage = new StorageClass();
$xeroTenantId = (string)$storage->getSession()['tenant_id'];
if ($storage->getHasExpired()) {
$provider = new \League\OAuth2\Client\Provider\GenericProvider([
'clientId' => '__CLIENT_ID__',
'clientSecret' => '__CLIENT_SECRET__',
'redirectUri' => 'http://localhost:8888/xero-php-oauth2-starter/callback.php',
'urlAuthorize' => 'https://login.xero.com/identity/connect/authorize',
'urlAccessToken' => 'https://identity.xero.com/connect/token',
'urlResourceOwnerDetails' => 'https://identity.xero.com/resources'
]);
$newAccessToken = $provider->getAccessToken('refresh_token', [
'refresh_token' => $storage->getRefreshToken()
]);
// Save my token, expiration and refresh token
$storage->setToken(
$newAccessToken->getToken(),
$newAccessToken->getExpires(),
$xeroTenantId,
$newAccessToken->getRefreshToken(),
$newAccessToken->getValues()["id_token"] );
}
$config = XeroAPI\XeroPHP\Configuration::getDefaultConfiguration()->setAccessToken( (string)$storage->getSession()['token'] );
$accountingApi = new XeroAPI\XeroPHP\Api\AccountingApi(
new GuzzleHttp\Client(),
$config
);
$assetApi = new XeroAPI\XeroPHP\Api\AssetApi(
new GuzzleHttp\Client(),
$config
);
$identityApi = new XeroAPI\XeroPHP\Api\IdentityApi(
new GuzzleHttp\Client(),
$config
);
$projectApi = new XeroAPI\XeroPHP\Api\ProjectApi(
new GuzzleHttp\Client(),
$config
);
$message = "no API calls";
if (isset($_GET['action'])) {
if ($_GET["action"] == 1) {
// Get Organisation details
$apiResponse = $accountingApi->getOrganisations($xeroTenantId);
$message = 'Organisation Name: ' . $apiResponse->getOrganisations()[0]->getName();
} else if ($_GET["action"] == 2) {
// Create Contact
try {
$person = new XeroAPI\XeroPHP\Models\Accounting\ContactPerson;
$person->setFirstName("John")
->setLastName("Smith")
->setEmailAddress("[email protected]")
->setIncludeInEmails(true);
$arr_persons = [];
array_push($arr_persons, $person);
$contact = new XeroAPI\XeroPHP\Models\Accounting\Contact;
$contact->setName('FooBar')
->setFirstName("Foo")
->setLastName("Bar")
->setEmailAddress("[email protected]")
->setContactPersons($arr_persons);
$arr_contacts = [];
array_push($arr_contacts, $contact);
$contacts = new XeroAPI\XeroPHP\Models\Accounting\Contacts;
$contacts->setContacts($arr_contacts);
$apiResponse = $accountingApi->createContacts($xeroTenantId,$contacts);
$message = 'New Contact Name: ' . $apiResponse->getContacts()[0]->getName();
} catch (\XeroAPI\XeroPHP\ApiException $e) {
$error = AccountingObjectSerializer::deserialize(
$e->getResponseBody(),
'\XeroAPI\XeroPHP\Models\Accounting\Error',
[]
);
$message = "ApiException - " . $error->getElements()[0]["validation_errors"][0]["message"];
}
} else if ($_GET["action"] == 3) {
$if_modified_since = new \DateTime("2019-01-02T19:20:30+01:00"); // \DateTime | Only records created or modified since this timestamp will be returned
$if_modified_since = null;
$where = 'Type=="ACCREC"'; // string
$where = null;
$order = null; // string
$ids = null; // string[] | Filter by a comma-separated list of Invoice Ids.
$invoice_numbers = null; // string[] | Filter by a comma-separated list of Invoice Numbers.
$contact_ids = null; // string[] | Filter by a comma-separated list of ContactIDs.
$statuses = array("DRAFT", "SUBMITTED");;
$page = 1; // int | e.g. page=1 – Up to 100 invoices will be returned in a single API call with line items
$
class StorageClass
{
function __construct() {
if( !isset($_SESSION) ){
$this->init_session();
}
}
public function init_session(){
session_start();
}
public function getSession() {
return $_SESSION['oauth2'];
}
public function startSession($token, $secret, $expires = null)
{
session_start();
}
public function setToken($token, $expires = null, $tenantId, $refreshToken, $idToken)
{
$_SESSION['oauth2'] = [
'token' => $token,
'expires' => $expires,
'tenant_id' => $tenantId,
'refresh_token' => $refreshToken,
'id_token' => $idToken
];
}
public function getToken()
{
//If it doesn't exist or is expired, return null
if (empty($this->getSession())
|| ($_SESSION['oauth2']['expires'] !== null
&& $_SESSION['oauth2']['expires'] <= time())
) {
return null;
}
return $this->getSession();
}
public function getAccessToken()
{
return $_SESSION['oauth2']['token'];
}
public function getRefreshToken()
{
return $_SESSION['oauth2']['refresh_token'];
}
public function getExpires()
{
return $_SESSION['oauth2']['expires'];
}
public function getXeroTenantId()
{
return $_SESSION['oauth2']['tenant_id'];
}
public function getIdToken()
{
return $_SESSION['oauth2']['id_token'];
}
public function getHasExpired()
{
if (!empty($this->getSession()))
{
if(time() > $this->getExpires())
{
return true;
} else {
return false;
}
} else {
return true;
}
}
}
$provider = new \League\OAuth2\Client\Provider\GenericProvider([
'clientId' => '__CLIENT_ID__',
'clientSecret' => '__CLIENT_SECRET__',
'redirectUri' => '__REDIRECT_URI__ ',
'urlAuthorize' => 'https://login.xero.com/identity/connect/authorize',
'urlAccessToken' => 'https://identity.xero.com/connect/token',
'urlResourceOwnerDetails' => 'https://identity.xero.com/resources'
]);
try {
// Try to get an access token using the client credentials grant.
$accessToken = $provider->getAccessToken('client_credentials');
echo($accessToken->getToken());
} catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {
// Failed to get the access token
exit($e->getMessage());
}
// DECODE & VERIFY ACCESS_TOKEN
$accessToken = (string)$storage->getSession()['token'];
$jwtAccessTokenClaims = new XeroAPI\XeroPHP\JWTClaims();
$jwtAccessTokenClaims->decodeAccessToken($accessToken);
echo($jwtAccessTokenClaims->getNbf());
echo($jwtAccessTokenClaims->getExp());
echo($jwtAccessTokenClaims->getIss());
echo($jwtAccessTokenClaims->getAudValue());
echo($jwtAccessTokenClaims->getClientId());
echo($jwtAccessTokenClaims->getAuthTime());
echo($jwtAccessTokenClaims->getXeroUserId());
echo($jwtAccessTokenClaims->getGlobalSessionId());
echo($jwtAccessTokenClaims->getJti());
echo($jwtAccessTokenClaims->getAuthenticationEventId());
// scopes are an array therfore we dump not echo them.
var_dump($jwtAccessTokenClaims->getScope());
//DECODE & VERIFY ID_TOKEN
$IdToken = (string)$storage->getSession()['id_token'];
$jwtIdTokenClaims = new XeroAPI\XeroPHP\JWTClaims();
$jwtIdTokenClaims->decodeIdToken($IdToken);
// 13 Claims are available
echo($jwtIdTokenClaims->getNbf());
echo($jwtIdTokenClaims->getExp());
echo($jwtIdTokenClaims->getIss());
echo($jwtIdTokenClaims->getAudValue());
echo($jwtIdTokenClaims->getIat());
echo($jwtIdTokenClaims->getAtHash());
echo($jwtIdTokenClaims->getSid());
echo($jwtIdTokenClaims->getSub());
echo($jwtIdTokenClaims->getAuthTime());
echo($jwtIdTokenClaims->getPreferredUsername());
echo($jwtIdTokenClaims->getEmail());
echo($jwtIdTokenClaims->getGivenName());
echo($jwtIdTokenClaims->getFamilyName());
//Get account by id
$result = $apiInstance->getAccount($xeroTenantId,$accountId);
// display formatted date
echo($result->getAccounts()[0]->getUpdatedDateUtcAsDate()->format('Y-m-d H:i:s') ):
// display string in MS .NET JSON format \/Date(1439434356790)\/
echo($result->getAccounts()[0]->getUpdatedDateUtc() ):
//When setting a date for accounting or AU Payroll, remember to use the correct method
// For example setStartDate has a 2nd method with "AsDate" if you wish to pass a native date
// This converts the date object to MS DateFormat
$leaveapplication->setStartDateAsDate(new DateTime('2020-05-02'));
// You'll get an error from the AU Payroll API if you try setStartDate("2020-05-02")
// But if you want to pass in MS Dateformat, this string will work.
$leaveapplication->setStartDate("/Date(1547164800000+0000)/");
composer
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.