Use PHP to connect with Xero

Sid Maestre
Xero Developer
Published in
6 min readAug 13, 2020

--

Photo by Luca Bravo on Unsplash

In previous posts, we demonstrated connecting to Xero using only an OAuth 2.0 library. We’ve provided examples in NodeJS, Java, .NET, Ruby, GoLang and in this post we look at PHP.

What are some reasons a developer might choose to build with just an OAuth 2.0 library and not the official Xero PHP SDK?

  1. You have an existing OAuth 1.0a integration and must keep your current codebase by retro fitting OAuth 2.0 and Xero tenant id headers.
  2. You are working with WorkflowMax or Xero Practice Manager APIs that only return XML (our SDKs only handle JSON requests and responses).
  3. You are working with APIs that are not currently supported in the SDK. At this time, NZ Payroll and Files are not supported, but will in the future.
  4. You prefer to roll your own solution or face some other constraint that prevents the use of an official SDK.

Note: PHP developers who want to use our SDK should check out xero-php-oauth2.

Which OAuth 2 client?

There are many OAuth 2.0 clients for PHP but we found the PHP league oauth2-client easy to use.

Today’s example code loads the oauth2-client library with composer. The oauth2-client handles our OAuth flow, and is used to retrieve a list of Xero tenants (and their tenant ids) in order to access Xero API endpoints.

You can download the complete code shown in this post at php-oauth2-example.

Prerequisites for today

  • A local server running PHP 5.6 or higher (i.e. MAMP)
  • Composer: dependency manager for PHP installed

Start your local server

I’m using MAMP which has an htdocs folder as it’s webroot.

Setup your project

Open up your terminal and navigate to the webroot folder (i.e. htdocs)

cd /Applications/MAMP/htdocs

Make a new folder for our project

mkdir php-oauth2-example

Change into our new folder

cd php-oauth2-example

Create your composer.json file

composer init

I just hit enter to accept the default answers to all the questions and when it asks about adding dependencies interactively say “no”. Do you confirm generation? Answer ‘yes’.

You’ve initialized your composer.json file. Let’s install the oauth2-client. In the terminal enter the following command to add the oauth2-client to your composer.json file.

composer require league/oauth2-client

Open the composer.json file and you should see “league/oauth2-client” under require.

Your folder should look like this.

Get your API keys (client id & secret)

If you don’t have a Xero user account, you can create one for free. Once you’ve activated your user account and enabled the Demo company.

  • Login to Xero developer portal and click “New app”.
  • Enter your app name, company url, privacy policy url, and redirect URI (i.e. http://localhost:8888/php-oauth2-example/index.php).
  • Agree to the terms and conditions and click “Create App”.
  • Click the “Generate a secret” button.
  • Copy and save your client id and client secret for use later.
  • Click the “Save” button. Your secret is now hidden.

Let’s write some code.

In our project folder, create a new file and name it index.php.

Step 1 — configure your OAuth 2.0 client

On line 2, we load our dependencies, including the oauth2-client.

On line 4, we start a session, so we can save our “state” value and compare it to the state returned by Xero when redirected back to our application. This check prevents CSRF (cross site request forgery) attacks.

On line 6–8 we set our $clientId, $clientSecret and $redirectUri to match our Xero OAuth 2.0 application we created. Once those are in place, we can initialize the $provider on line 10–17.

Copy and paste the following code.

Swap in your client id, client secret and the redirectURI set at the Xero developer portal.

Navigate your browser to load index.php (i.e. http://localhost:8888/php-oauth2-example/). You should see a success message.

Step 2 — generate an authorization url

Let’s look at the new code we’ve added.

On line 20, we check if a query string param named “code” exists on our URL. If not, let’s execute the code inside our if statement.

One line 22, we declare the $options array to hold our scopes. Scope define the resources our app will access through Xero’s API. Find out more about the scopes available and their corresponding endpoints.

On line 28, use the $provider object to generate an authorization URL.

On line 31, before we redirect, save our state in a session variable.

One line 33, display our authorization url on the screen.

Update index.php. Copy and paste the following code.

Swap in your client id, client secret and the redirectURI set at the Xero developer portal.

Refresh your browser to execute this updated code and you should see your authorization url displayed on screen. It will look something like this.

https://login.xero.com/identity/connect/authorize?scope=openid%20email%20profile%20offline_access%20accounting.transactions%20accounting.settings&state=1442d89e5abdfd40ae883ca818605bfa&response_type=code&approval_prompt=auto&redirect_uri=http%3A%2F%2Flocalhost%3A8888%2Fphp-oauth2-example%2Findex.php&client_id=E2B33204DE2643AF929928372DC2

Step 3 — execute the OAuth 2.0 flow

Let’s get our access token.

On line 35, forward the user to Xero to login and grant our app access. Once complete, the user is redirected back to our application.

One line 38, if a ‘code’ parameter exists but the state parameter is empty or doesn’t match our saved oauth2state variable, we execute the elseif statement to and display an Invalid state message on line 40.

Otherwise, we execute line 43 else statement.

One lines 47–49, we swap our code for an access token.

On lines 53–59, we use the $provider and getAuthenticatedRequest method to perform a GET on the https://api.xero.com/connections endpoint passing in our $accessToken->getToken() and $options arguments. This returns an array of tenants so we know which organisation are associated with our access token.

On line 61, we pass the $connectionsResponse object to the getParsedResponse method on the $provider object to get an array of Xero tenants and their IDs.

Update index.php. Copy and paste the following code.

Swap in your client id, client secret and the redirectURI set at the Xero developer portal.

Refresh your browser to execute this updated code and you should go through the OAuth flow and return back to your application. It will look something like this.

Step 4 — get organisation details

We now have all the pieces necessary to make an authenticated request.

On line 72 -73, we set the ‘xero-tenant-id’ header and the ‘accept’ header. This tells Xero’s API which tenant we are working with and how to format the data returned.

On line 75–80, we pass in the method (GET, POST, PUT, etc), the resource url , access token and options.

Update index.php. Copy and paste the following code.

Swap in your client id, client secret and the redirectURI set at the Xero developer portal.

Refresh your browser to execute this updated code and see your organisation details displayed.

Note: index.php is a very basic script meant to illustrate the OAuth 2.0 flow with minimal code. If you hit refresh on your browser after completing the redirect, you will see the Invalid state message. This is because you’ve already exchanged your code for an access token and can not use the code returned by Xero a 2nd time.

As a bonus, if you pass the offline_access scope a refresh token is returned. After 30 minutes your access token will expire, but you use the $provider and refresh token to obtain a new access token.

That’s it! OAuth 2.0 for PHP in 103 lines of code. Let us know how you are getting on and happy coding!

Over 2 million small businesses, and their advisors are looking for the best cloud apps that integrate with Xero. Partner with us, and we’ll make sure they find yours.

--

--

Head of Developer Evangelism @Xero and working with the @XeroAPI team