• Stars
    star
    121
  • Rank 293,924 (Top 6 %)
  • Language
    C#
  • License
    MIT License
  • Created about 7 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A wrapper of the Xero API in the .NetStandard 2.0 framework. Supports Accounting, Payroll AU/US, and Files

Xero-NetStandard

Github forks Github stars

The Xero-NetStandard SDK makes it easy for developers to access Xero's APIs in their Csharp code, and build robust applications and software using small business & general ledger accounting data.

Table of Contents


API Client documentation

This SDK supports full method coverage for the following Xero API sets:

API Set Description
Accounting The Accounting API exposes accounting functions of the main Xero application (most commonly used)
Assets The Assets API exposes fixed asset related functions of the Xero Accounting application
Files The Files API provides access to the files, folders, and the association of files within a Xero organisation
Projects Xero Projects allows businesses to track time and costs on projects/jobs and report on profitability
Payroll (AU) The (AU) Payroll API exposes payroll related functions of the payroll Xero application
Payroll (UK) The (UK) Payroll API exposes payroll related functions of the payroll Xero application
Payroll (NZ) The (NZ) Payroll API exposes payroll related functions of the payroll Xero application
Bankfeeds The Bankfeeds API facilitates the flow of transaction and statement data
AppStore The AppStore API encapsulates subscription based endpoints

drawing


Sample Applications

Sample apps can get you started quickly with simple auth flows to advanced usage.

Sample App Description Screenshot
xero-netstandard-oauth2-app This is a companion app built with .NET Core 3.1 MVC to demonstrate Xero OAuth 2.0 Client Authentication & OAuth 2.0 APIs. gif
xero-netstandard-oauth2-starter-dotnet-core This is a starter app build with .NET Core 3.1 MVC to demonstrate Xero OAuth 2.0 Client Authentication & OAuth 2.0 APIs. gif
xero-netstandard-oauth2-blazor-pkce This project is a Blazor WebAssembly Demo Application demonstrating the use of the Xero Files API, using the Xero NetStandard SDK to upload and delete files, folders and associations. blazor
Xero-NetStandard-custom-connections-starter A getting started command line app showing Custom Connections (aka client_credentials auth) a Xero premium option for building M2M integrations to a single org customs-starter
xeropracticemanager-dotnetcore-oauth2-sample This is an example dotnet core MVC application making use of Xero sign in, and Xero Practice Manager API access using OAuth2.0. customs-starter
Xero-NetStandard-Webhooks-Receiver This application demonstrates how to receive webhooks from Xero. customs-starter

Xero Account Requirements

  • Create a free Xero user account
  • Login to your Xero developer dashboard and create an API application
  • Copy the credentials from your API app and store them using a secure ENV variable strategy
  • Decide the neccesary scopes for your app's functionality

Installation

This project is broken into 2 Nuget packages.

Xero.NetStandard.OAuth2 contains code to call all the XeroAPI endpoints

OAuth2 Endpoints Xero-NetStandard Downloads

Xero.NetStandard.OAuth2Client code to authenticate and manage tokens

OAuth2Client Xero-NetStandard Downloads

OAuth2Client README


Use Nuget to download the packages via command line:

dotnet add package Xero.NetStandard.OAuth2
dotnet add package Xero.NetStandard.OAuth2Client

Or use the Package Manager Console inside Visual Studio

Install-Package Xero.NetStandard.OAuth2
Install-Package Xero.NetStandard.OAuth2Client

You can also download the source code from https://github.com/XeroAPI/Xero-NetStandard and compile it by yourself.

To get started there are a couple main classes:

  • The AccountingApi class
  • XeroOAuth2

The AccountingApi class is not coupled to the OAuth2 class so you easily can use another OAuth2 auth flow if you prefer.

To get started you will just need two things to make calls to the Accounting Api.

  1. xero-tenant-id
  2. accessToken

Configuration

XeroConfiguration xconfig = new XeroConfiguration();
xconfig.ClientId = "yourClientId";
xconfig.ClientSecret = "yourClientSecret";
xconfig.CallbackUri = new Uri("https://localhost:5001"); //default for standard webapi template
xconfig.Scope = "openid profile email offline_access files accounting.transactions accounting.contacts";

var client = new XeroClient(xconfig);

Authentication

Step 1

Build the login link and send the user through the authorization_code flow (a .NET Core Mvc example):

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Logging;
    using Xero.NetStandard.OAuth2.Client;
    using Xero.NetStandard.OAuth2.Config;
    using Xero.NetStandard.OAuth2.Token;
    using System;
    using System.Net.Http;
    using System.Threading.Tasks;
    using Xero.NetStandard.OAuth2.Models;
    using System.Collections.Generic;


    namespace XeroNetStandardApp.Controllers
    {
      public class XeroOauth2Controller : Controller
      {
        private readonly ILogger<HomeController> _logger;
        private readonly IOptions<XeroConfiguration> XeroConfig;

        public XeroOauth2Controller(IOptions<XeroConfiguration> config, ILogger<HomeController> logger)
        {
          _logger = logger;
          this.XeroConfig = config;
        }

        public IActionResult Index()
        {
          XeroConfiguration xconfig = new XeroConfiguration();
          xconfig.ClientId = "yourClientId";
          xconfig.ClientSecret = "yourClientSecret";
          xconfig.CallbackUri = new Uri("https://localhost:5001"); //default for standard webapi template
          xconfig.Scope = "openid profile email offline_access files accounting.transactions accounting.contacts";

          var client = new XeroClient(xconfig);

          return Redirect(client.BuildLoginUri());
        }
      }
    }

Step 2

The user will be redirected to login, authorise access and get redirected back to your callback

In the callback URI, Xero will return a parameter code and state (if you passed any)

  • code
  • state

You can then exchange the temp code for a XeroToken

	XeroConfiguration xconfig = new XeroConfiguration(); 
    
	xconfig.ClientId = "yourClientId";
	xconfig.ClientSecret = "yourClientSecret";
	xconfig.CallbackUri = new Uri("https://localhost:5001") //default for standard webapi template
	xconfig.Scope = "openid profile email files accounting.transactions accounting.contacts offline_access";
	
	var client = new XeroClient(xconfig);
	
	//before getting the access token please check that the state matches
	await client.RequestAccessTokenAsync(code);
    
	//from here you will need to access your Xero Tenants
	List<Tenant> tenants = await client.GetConnections();
    
	// you will now have the tenant id and access token
	foreach (Tenant tenant in tenants)
	{
		// do something with your tenant and access token
		//client.AccessToken;
		//tenant.TenantId;
	}

You can now interact with the OAuth2 token data which has been mapped from Xero's OAuth2 json response.

{
  "id_token": "xxx.yyy.zz",
  "access_token": "xxx.yyy.zzz",
  "expires_in": 1800,
  "token_type": "Bearer",
  "refresh_token": "xxxxxxxxx",
  "scope": "email profile openid accounting.transactions offline_access"
}

...to the XeroToken object model.

xeroToken.AccessToken
xeroToken.RefreshToken
xeroToken.IdToken
xeroToken.TokenType
xeroToken.ExpiresAtUtc

A NOTE on Tokens

You will still need to save the XeroToken in your datastore to keep the connection alive until you or the user disconnect. If you have a valid XeroToken in your database you can restart a XeroAPI connection by passing the token to RefreshAccessTokenAsync on an initialized client.

Auth with PKCE

First build the login link with the PKCE(Proof Key Code Exchange) flow (a .NET Core Mvc example).

PKCE is suited for mobile and desktop applications that don't have a way to keep the ClientSecret private

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Logging;
    using Xero.NetStandard.OAuth2.Client;
    using Xero.NetStandard.OAuth2.Config;
    using Xero.NetStandard.OAuth2.Token;
    using System;
    using System.Net.Http;
    using System.Threading.Tasks;
    using Xero.NetStandard.OAuth2.Models;
    using System.Collections.Generic;


    namespace XeroNetStandardApp.Controllers
    {
      public class XeroOauth2Controller : Controller
      {
        private readonly ILogger<HomeController> _logger;
        private readonly IOptions<XeroConfiguration> XeroConfig;

        public XeroOauth2Controller(IOptions<XeroConfiguration> config, ILogger<HomeController> logger)
        {
          _logger = logger;
          this.XeroConfig = config;
        }

        public IActionResult Index()
        {
          XeroConfiguration xconfig = new XeroConfiguration();
          xconfig.ClientId = "yourClientId";
          xconfig.CallbackUri = new Uri("https://localhost:5001"); //default for standard webapi template
          xconfig.Scope = "openid profile email offline_access files accounting.transactions accounting.contacts";
	  xconfig.State = "YOUR_STATE"

          var client = new XeroClient(xconfig);

          // generate a random codeVerifier
          var validChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-._~";          
          Random random = new Random();
          int charsLength = random.Next(43, 128);
          char[] randomChars = new char[charsLength];
          for (int i = 0; i < charsLength; i++)  
          {  
              randomChars[i] = validChars[random.Next(0, validChars.Length)];  
          }  
          string codeVerifier = new String(randomChars);

          return Redirect(client.BuildLoginUriPkce(codeVerifier));
        }
      }
    }

The user will be redirected to login, authorise access and get redirected to your callback. You can then use the RequestAccessTokenPkceAsync to exchange for a XeroToken set.

	XeroConfiguration xconfig = new XeroConfiguration(); 
	xconfig.ClientId = "yourClientId";
	xconfig.CallbackUri = new Uri("https://localhost:5001") //default for standard webapi template
	xconfig.Scope = "openid profile email files accounting.transactions accounting.contacts offline_access";
	
	var client = new XeroClient(xconfig);
  	string codeVerifier = "Aaaaaaaaaa.Bbbbbbbbbb.0000000000.1111111111";

	await client.RequestAccessTokenPkceAsync(code, codeVerifier);

Custom Connections

Custom Connections are a Xero premium option used for building M2M integrations to a single organisation. A custom connection uses OAuth2.0's client_credentials grant which eliminates the step of exchanging the temporary code for a token set.

To use this SDK with a Custom Connections var xeroTenantId = ""; must still be passed to work with a Custom Connection.

Full sample code: https://github.com/XeroAPI/Xero-NetStandard-custom-connections-starter

using System;
using Xero.NetStandard.OAuth2.Api;
using Xero.NetStandard.OAuth2.Client;
using Xero.NetStandard.OAuth2.Config;
using System.Threading.Tasks;

namespace AsyncMain
{
    class Program
    {
        static async Task Main(string[] args)
        {
            DotNetEnv.Env.Load();
            var helloWorld = await GetHelloWorldAsync();
            Console.WriteLine(helloWorld);
        }

        static async Task<string> GetHelloWorldAsync()
        {   
            XeroConfiguration XeroConfig = new XeroConfiguration
            {
                ClientId = System.Environment.GetEnvironmentVariable("CLIENT_ID"),
                ClientSecret = System.Environment.GetEnvironmentVariable("CLIENT_SECRET")
            };

            var client = new XeroClient(XeroConfig);
            var xeroToken = await client.RequestClientCredentialsTokenAsync();

            try {
                var apiInstance = new AccountingApi();
                var ifModifiedSince = DateTime.Parse("2000-02-06T12:17:43.202-08:00");
                var where = "Status==\"ACTIVE\"";
                var xeroTenantId = "";
                var result = await apiInstance.GetAccountsAsync(xeroToken.AccessToken, xeroTenantId, ifModifiedSince, where, null);
                return result.ToJson();
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception when calling apiInstance.GetInvoice: " + e.Message );
                return e.ToString();
            }
        }
    }
}

Because Custom Connections are only valid for a single organisation you don't need an actual xero-tenant-id however the parameter remains and still requires an empty string.

App Store Subscriptions

If you are implementing subscriptions to participate in Xero's App Store you will need to setup App Store subscriptions endpoints. When a plan is successfully purchased, the user is redirected back to the URL specified in the setup process. The Xero App Store appends the subscription Id to this URL so you can immediately determine what plan the user has subscribed to through the subscriptions API. With your app credentials you can create a client via client_credentials grant type with the marketplace.billing scope. This unique access_token will allow you to query any functions in AppStoreApi. Client Credentials tokens to query app store endpoints will only work for apps that have completed the App Store on-boarding process.

=> /post-purchase-url?subscriptionId=03bc74f2-1237-4477-b782-2dfb1a6d8b21

csharp.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="DotNetEnv" Version="2.1.1" />
    <PackageReference Include="IdentityModel" Version="4.0.0" />
    <PackageReference Include="Xero.NetStandard.OAuth2" Version="3.19.0" />
    <PackageReference Include="Xero.NetStandard.OAuth2Client" Version="1.5.0" />
  </ItemGroup>
</Project>

Program.cs

using System;
using Xero.NetStandard.OAuth2.Api;
using Xero.NetStandard.OAuth2.Client;
using Xero.NetStandard.OAuth2.Config;
using System.Threading.Tasks;

namespace AsyncMain
{
    class Program
    {
        static async Task Main(string[] args)
        {
            DotNetEnv.Env.Load();
            var helloWorld = await GetHelloWorldAsync();
            Console.WriteLine(helloWorld);
        }

        static async Task<string> GetHelloWorldAsync()
        {   
            XeroConfiguration XeroConfig = new XeroConfiguration
            {
                ClientId = System.Environment.GetEnvironmentVariable("APPSTORE_CLIENT_ID"),
                ClientSecret = System.Environment.GetEnvironmentVariable("APPSTORE_CLIENT_SECRET")
            };

            var client = new XeroClient(XeroConfig);
            var xeroToken = await client.RequestClientCredentialsTokenAsync(false);
            
            Guid subscriptionId = Guid.Parse("03bc74f2-1237-4477-b782-2dfb1a6d8b21");

            try {
                var apiInstance = new AppStoreApi();
                var result = await apiInstance.GetSubscriptionAsync(xeroToken.AccessToken, subscriptionId);
                return result.ToJson();
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception when calling apiInstance.GetSubscriptionAsync: " + e.Message );
                return e.ToString();
            }
        }
    }
}
// dotnet run
{
  "currentPeriodEnd": "2021-09-02T14:08:58.772536Z",
  "id": "03bc74f2-1237-4477-b782-2dfb1a6d8b21",
  "organisationId": "79e8b2e5-c63d-4dce-888f-e0f3e9eac647",
  "plans": [
    {
      "status": "ACTIVE",
      "id": "6abc26f3-9390-4194-8b25-ce8b9942fda9",
      "name": "Small",
      "subscriptionItems": [
        {
          "id": "834cff4c-b753-4de2-9e7a-3451e14fa17a",
          "price": {
            "amount": 10.0000,
            "currency": "NZD",
            "id": "2310de92-c7c0-4bcb-b972-fb7612177bc7"
          },
          "product": {
            "type": "FIXED",
            "id": "9586421f-7325-4493-bac9-d93be06a6a38",
            "name": ""
          },
          "startDate": "2021-08-02T14:08:58.772536Z",
          "testMode": true
        }
      ]
    }
  ],
  "startDate": "2021-08-02T14:08:58.772536Z",
  "status": "ACTIVE",
  "testMode": true
}

You should use the subscription data to provision user access/permissions to your application.

App Store Subscription Webhooks

In additon to a subscription Id being passed through the URL, when a purchase or an upgrade takes place you will be notified via a webhook. You can then use the subscription Id in the webhook payload to query the AppStore endpoints and determine what plan the user purchased, upgraded, downgraded or cancelled. Refer to Xero's documenation to learn more about setting up and receiving webhooks or review this blogpost explaing webhooks using this sdk.

https://developer.xero.com/documentation/guides/webhooks/overview/


API Clients

You can access the different API sets and their available methods through the following:

var AccountingApi = new AccountingApi();
var AssetApi = new AssetApi();
var BankFeedsApi = new BankFeedsApi();
var FilesApi = new FilesApi();
var IdentityApi = new IdentityApi();
var PayrollAUApi = new PayrollAUApi();
var PayrollNZApi = new PayrollNZApi();
var PayrollUkApi = new PayrollUkApi();
var ProjectApi = new ProjectApi();
var AppStoreApi = new AppStoreApi();

Helper Methods

A full list of the SDK client's methods:

XeroConfiguration xconfig = new XeroConfiguration();
xconfig.ClientId = "yourClientId";
xconfig.ClientSecret = "yourClientSecret";
xconfig.CallbackUri = new Uri("https://localhost:5001");
xconfig.Scope = "openid profile email offline_access files accounting.transactions ...etc";

var client = new XeroClient(xconfig);
Method Description
client.BuildLoginUri() Returns a Xero authorize URI to start OAuth flow
client.BuildLoginUri(string state, string scope) Returns a Xero authorize URI (with state attached) to start OAuth flow
client.BuildLoginUriPkce(string codeVerifier, string state, string scope) Returns a Xero authorize URI to start OAuth flow with PKCE
client.GetConnectionsAsync(IXeroToken xeroToken) List of Tenants attached to accesstoken
client.DeleteConnectionAsync(IXeroToken xeroToken, Tenant xeroTenant) List of remaining Tenants attached to accesstoken
client.RevokeAccessTokenAsync(IXeroToken xeroToken) Revokes a IXeroToken and returns null
client.RefreshAccessTokenAsync(IXeroToken xeroToken) Returns a IXeroToken
client.RequestClientCredentialsTokenAsync(Boolean fetchTenants=true) Returns a IXeroToken, and defaults to calling GetConnections unless specified
client.RequestAccessTokenAsync(string code) Returns a IXeroToken
client.RequestAccessTokenPkceAsync(string code, string codeVerifier) Returns a IXeroToken
client.GetCurrentValidTokenAsync(IXeroToken xeroToken) Returns a IXeroToken

Usage Examples

Refresh your token

  • Call the refresh (shared between code & PKCE flows)
client.RefreshTokenAsync(xeroToken);

Accounting API


  • Get All invoices
var AccountingApi = new AccountingApi();
var response = await AccountingApi.GetInvoicesAsync(accessToken, xeroTenantId);
  • Get invoices from the last 7 days:
var AccountingApi = new AccountingApi();

var sevenDaysAgo = DateTime.Now.AddDays(-7).ToString("yyyy, MM, dd");
var invoicesFilter = "Date >= DateTime(" + sevenDaysAgo + ")";

var response = await AccountingApi.GetInvoicesAsync(accessToken, xeroTenantId, null, invoicesFilter);
  • Create an invoice (Accounting APIs):
var contact = new Contact();
contact.Name = "John Smith";

var line = new LineItem() {
  Description = "A golf ball",
  Quantity = float.Parse(LineQuantity),
  UnitAmount = float.Parse(LineUnitAmount),
  AccountCode = "200"
};

var lines = new List<LineItem>() {
  line
};

var invoice = new Invoice() {
  Type = Invoice.TypeEnum.ACCREC,
  Contact = contact,
  Date = DateTime.Today,
  DueDate = DateTime.Today.AddDays(30),
  LineItems = lines
};

var invoiceList = new List<Invoice>();
invoiceList.Add(invoice);

var invoices = new Invoices();
invoices._Invoices = invoiceList;

var AccountingApi = new AccountingApi();
var response = await AccountingApi.CreateInvoicesAsync(accessToken, xeroTenantId, invoices);

Fixed Asset API


  • Get All Fixed Assets:
var AssetApi = new AssetApi();
var response = await AssetApi.GetAssetsAsync(accessToken, xeroTenantId, AssetStatusQueryParam.DRAFT);
  • Create a fixed asset:
var asset = new Asset() {
  AssetName = "Office Computer",
  AssetNumber = "FA-001"
};

var AssetApi = new AssetApi();
var response = await AssetApi.CreateAssetAsync(accessToken, xeroTenantId, asset);

Payroll AU API


  • Get Employees:
var PayrollAUApi = new PayrollAUApi();
var response = await PayrollAUApi.GetEmployeesAsync(accessToken, xeroTenantId);

var employees = response._Employees;
  • Create a Employee:
DateTime dob = DateTime.Today.AddYears(-20);

HomeAddress homeAddress = new HomeAddress() {
  AddressLine1 = "6 MeatMe Street",
  AddressLine2 = " ",
  Region = State.VIC,
  City = "Long Island",
  PostalCode = "0000", 
  Country = "New York"
};

Employee employee = new Employee() {
  FirstName = "Bob",
  LastName = "Belcher",
  DateOfBirth = dob,
  HomeAddress = homeAddress
};

var employees = new List<Employee>() { employee };

var PayrollAUApi = new PayrollAUApi();
var response = await PayrollAUApi.CreateEmployeeAsync(accessToken, xeroTenantId, employees);

Bankfeed API


Before trying the APIs, please make sure your company had been approved for Bankfeed endpoints and have the bankfeed scope enabled on your Xero OAuth 2.0 app. If you intend to become a Xero bankfeed partner please start by registering here.

  • Create a bankfeed connection
var feedConnection = new FeedConnection{
  AccountToken = accountToken, 
  AccountNumber = accountNumber,
  AccountType =  accountTypeEnum,
  AccountName = accountName,
  Currency = currencyCode,
  Country = countryCode
};

List<FeedConnection> list = new List<FeedConnection>();
list.Add(feedConnection);

FeedConnections items = new FeedConnections{
  Pagination = new Pagination(),
  Items = list
};

var BankfeedsApi = new BankFeedsApi();
await BankfeedsApi.CreateFeedConnectionsAsync(accessToken, xeroTenantId, items);
  • Get all bankfeed connections
var BankFeedsApi = new BankFeedsApi();
var response = await BankFeedsApi.GetFeedConnectionsAsync(accessToken, xeroTenantId);
var feedConnections = response.Items;
  • Delete a bankfeed connection
Guid bankfeedConnectionIdGuid = Guid.Parse(bankfeedConnectionId);

List<FeedConnection> list = new List<FeedConnection>();

list.Add(
  new FeedConnection {
    Id = bankfeedConnectionIdGuid
  }
);

var feedConnections = new FeedConnections{
    Items = list
};

var BankFeedsApi = new BankFeedsApi();
await BankFeedsApi.DeleteFeedConnectionsAsync(accessToken, xeroTenantId, feedConnections);
  • Create statements against a bankfeed connection (plase ensure your start balance, end balance and statement amounts are mathematically correct)
StartBalance startBalance = new StartBalance{
  Amount = decimal.Parse(startBalanceAmount),
  CreditDebitIndicator = startIndicatorEnum
};

StatementLine statementLine = new StatementLine{
  PostedDate = DateTime.Today,
  Description = "A bankfeed satemement description",
  Amount = 10,
  CreditDebitIndicator = startIndicatorEnum,
  TransactionId = new Guid().ToString()
};

EndBalance endBalance = new EndBalance{
  Amount = decimal.Parse(startBalanceAmount) + statementLine.Amount,
  CreditDebitIndicator = startIndicatorEnum
};

List<StatementLine> statementLines = new List<StatementLine>();
statementLines.Add(statementLine);

var statement = new Statement{
  FeedConnectionId = new Guid(feedConnectionId),
  StartDate = DateTime.Today.AddDays(-20),
  EndDate = DateTime.Today,
  StartBalance = startBalance,
  EndBalance = endBalance,
  StatementLines = statementLines,
};

List<Statement> statementList = new List<Statement>();
statementList.Add(statement);

Statements statements = new Statements{
  Pagination = new Pagination(),
  Items = statementList
};

var BankfeedsApi = new BankFeedsApi();
await BankfeedsApi.CreateStatementsAsync(accessToken, xeroTenantId, statements);
  • Get all statements from all bankfeed connections
var BankFeedsApi = new BankFeedsApi();
var response = await BankFeedsApi.GetStatementsAsync(accessToken, xeroTenantId);

For full documentation please refer to Xero Bankfeed API documentation.

Files API


  • Upload a file:
var FilesApi = new FilesApi();

// Convet IFormFile to byte array
byte[] byteArray; 
using (MemoryStream data = new MemoryStream())
{
  file.CopyTo(data);
  byteArray = data.ToArray();
}

// Upload file
var response = await FilesApi.UploadFileAsync(
    accessToken,
    xeroTenantId,
    null,
    byteArray,
    file.FileName,
    file.ContentType
);
  • Get Files:
var FilesApi = new FilesApi();
var response = await FilesApi.GetFilesAsync(accessToken, xeroTenantId);
var filesItems = response.Items;
  • Delete a File:
Guid fileIDGuid = Guid.Parse(fileID);

var filesApi = new FilesApi();
await filesApi.DeleteFileAsync(accessToken, xeroTenantId, fileIDGuid);
  • Rename a File:
Guid fileIDGuid = Guid.Parse(fileID);

var filesApi = new FilesApi();
FileObject file = await filesApi.GetFileAsync(accessToken, xeroTenantId, fileIDGuid);
file.Name = newName;

var response = await filesApi.UpdateFileAsync(accessToken, xeroTenantId, fileIDGuid, file);
  • Get Associations
var FilesApi = new FilesApi();
var response = await FilesApi.GetFileAssociationsAsync(accessToken, xeroTenantId, new Guid(fileId));
  • Create an Association
var FilesApi = new FilesApi();

var fileIdGuid = new Guid(fileId);
var invoiceIdGuid = new Guid(invoiceId);
Enum.TryParse<ObjectType>(objectType, out var objectTypeEnum);

Association association = new Association{
    FileId = fileIdGuid,
    ObjectId = invoiceIdGuid,
    ObjectType = objectTypeEnum,
    ObjectGroup = ObjectGroup.Invoice
};

var response = await FilesApi.CreateFileAssociationAsync(accessToken, xeroTenantId, fileIdGuid, association);
  • Delete an Association
var fileIdGuid = new Guid(fileId);
var objectIdGuid = new Guid(objectId);

var FilesApi = new FilesApi();
await FilesApi.DeleteFileAssociationAsync(accessToken, xeroTenantId, fileIdGuid, objectIdGuid);

SDK conventions

Security (state check & Jwt validation)

Checking state in OAuth 2.0 flow can prevent CSFR attack. When acccess token and id token is returned, it is also security best practice to validate them.

Examples of checking state and jwt validation:

      var clientState = TokenUtilities.GetCurrentState();
      
      if (state != clientState) {
        return Content("Cross site forgery attack detected!");
      }    

      var client = new XeroClient(XeroConfig.Value);
      var xeroToken = (XeroOAuth2Token)await client.RequestAccessTokenAsync(code);

      var decodedIdToken = JwtUtils.decode(xeroToken.IdToken);

      if ( !JwtUtils.validateIdToken(xeroToken.IdToken, XeroConfig.Value.ClientId) )
      {
        return Content("ID token is not valid");
      }

      if ( !JwtUtils.validateAccessToken(xeroToken.IdToken) )
      {
        return Content("Access token is not valid");
      }

TLS 1.0 deprecation

As of June 30, 2018, Xero's API will remove support for TLS 1.0.

The easiest way to force TLS 1.2 is to set the Runtime Environment for your server (Tomcat, etc) to Java 1.8 which defaults to TLS 1.2.


Contributing

This SDK is one of a number of SDK’s that the Xero Developer team builds and maintains. We are grateful for all the contributions that the community makes.

Here are a few things you should be aware of as a contributor:

  • Xero has adopted the Contributor Covenant Code of Conduct, we expect all contributors in our community to adhere to it
  • If you raise an issue then please make sure to fill out the github issue template, doing so helps us help you
  • You’re welcome to raise PRs. As our SDKs are generated we may use your code in the core SDK build instead of merging your code directly.
  • We have a contribution guide for you to follow when contributing to this SDK
  • Curious about how we generate our SDK’s? Have a read of our process and have a look at our OpenAPISpec
  • This software is published under the MIT License

For questions that aren’t related to SDKs please refer to our developer support page.

More Repositories

1

xero-node

Xero Node SDK for OAuth 2.0 generated from XeroAPI/Xero-OpenAPI
TypeScript
194
star
2

Xero-Net

A skinny wrapper of the Xero API. Supports Payroll, Accounting & Files
C#
129
star
3

XeroOAuth-PHP

PHP class for the Xero API V2
PHP
123
star
4

xero-python

Official Xero OAuth 2.0 python SDK
Python
122
star
5

Xero-OpenAPI

An OpenAPI description of the Xero API
Mustache
94
star
6

xero-php-oauth2

Xero PHP SDK for oAuth 2 generated from Xero API OpenAPI Spec 3.0
PHP
90
star
7

Xero-Java

Official Java client for use with Xero API
Java
74
star
8

xero-ruby

Xero Ruby SDK for OAuth 2.0 generated from XeroAPI/Xero-OpenAPI
Ruby
57
star
9

xoauth

A CLI tool for obtaining JWTs from OpenId Connect providers
Go
49
star
10

XeroAPI.Net

(previous SDK version - no longer supported)
C#
47
star
11

xero-node-oauth2-app

NodeJS app for demonstrating the xero-node v4 SDK
TypeScript
35
star
12

xero-python-oauth2-starter

Python
29
star
13

xero-postman-oauth2

A postman collection for use with Xero's API and OAuth 2.0
24
star
14

xerogolang

Golang SDK for the Xero API
Go
24
star
15

xero-php-oauth2-app

PHP app for demonstrating the xero-php-oauth2 SDK
PHP
22
star
16

xero-php-oauth2-starter

This is a starter app with the code to perform OAuth 2.0 authentication
PHP
16
star
17

xero-python-oauth2-app

python app for demonstrating the xero-python SDK
Python
16
star
18

XeroWebhooksReceiver

An example .Net Core application for receiving webhooks from Xero
C#
15
star
19

xero-netstandard-oauth2-starter-dotnet-core

This is a starter app build with .NET Core 3.1 MVC to demonstrate Xero OAuth 2.0 Client Authentication & OAuth 2.0 APIs.
C#
14
star
20

Xero-Postman

A Postman collection for authenticating to the Xero API
13
star
21

xero-ruby-oauth2-app

Ruby on rails app for demonstrating the xero-ruby SDK
Ruby
12
star
22

Xero-Insomnia

Insomnia collection for the [XeroAPI](https://developer.xero.com/documentation/) - plug in your API app params to start exploring
11
star
23

xero-netstandard-oauth2-samples

Contains sample implementations making use of Xero Sign In and Outh2
C#
10
star
24

golang-oauth2-example

A basic example using golang to complete the OAuth 2 flow on Xero's API without the use of an SDK.
Go
9
star
25

xero-netstandard-oauth2-app

The companion app for Xero .NET SDK
C#
8
star
26

node-oauth2-example

A short and simple example using node and express with openid-client to complete the OAuth flow on Xero's OAuth 2 API without the use of an SDK.
JavaScript
8
star
27

Xero-NetStandard-Webhooks-Receiver

C#
7
star
28

xero-node-oauth2-ts-starter

Starter typescript code for use with xero-node v4
TypeScript
7
star
29

xero-java-oauth2-app

Java app for demonstrating the Xero-Java SDK
Java
6
star
30

xero-oauth2-omniauth-strategy

An Omniauth strategy created for Xero API OAuth 2 based on the generic Omniauth OAuth 2 strategy.
Ruby
6
star
31

xero-node-oauth2-react-app

JavaScript
6
star
32

Api.Documentation

Documentation for Xero's public API
6
star
33

xero-netstandard-oauth2-starter-app-dotnet-framework

This is a starter app build with .NET Framework v4.6.1 MVC to demonstrate Xero OAuth 2.0 Client Authentication & OAuth 2.0 APIs.
JavaScript
6
star
34

net-desktop-pkce-example

.NET OAuth 2.0 example using PKCE to interact with the XeroAPI
C#
4
star
35

xero-oauth2-omniauth-sample

A Ruby on Rails sample application to demonstrate the usage of xero-oauth2-omniauth ruby gem.
Ruby
4
star
36

xero-node-sso-app

Showing an example Single Sign On / "Sign up with Xero" Flow using xero-node SDK
EJS
3
star
37

xero-ruby-oauth2-starter

This is a starter app to perform OAuth 2.0 authentication with xero-ruby
Ruby
3
star
38

xero-ruby-sso-form

An example of the "Sign up with Xero to Lead" flow using the Ruby SDK. The authentication results in a pre-populated sign up form.
Haml
3
star
39

xero-php-webhook

PHP example of code for verifying and receiving a Xero webhook
PHP
3
star
40

Xero-Postman-Tutorial-PKCE-Edition

3
star
41

xero-php-oauth2-custom-connections-starter

Starter app showing Xero's Custom Connections functionality aka OA2 grant_type: `client_credentials`
PHP
3
star
42

xero-java-oauth2-starter

Java starter code for use with Xero-Java SDK to complete OAuth 2 flow
Java
2
star
43

xeropracticemanager-dotnetcore-oauth2-sample

Contains sample implementations making use of the Xero Practice Manager v3 API and OAuth2
C#
2
star
44

xero-ruby-token-migration-script

Ruby script for migrating OAuth1.0a tokens to OAuth2.0
Ruby
2
star
45

workflowmax-postman-oauth2

A postman collection for use with WorkflowMax's API and OAuth 2.0
2
star
46

php-oauth2-example

A PHP example of the OAuth 2.0 flow and Xero's API without the use of an SDK
PHP
2
star
47

xero-netstandard-oauth2-blazor-pkce

Sample application showing a basic Files Api integration using Blazor WebAssembly.
C#
2
star
48

xero-ruby-custom-connections-starter

Simple starter repo showing how to integrate with Xero
Ruby
1
star
49

workflowmax-dotnetcore-oauth2-sample

Contains sample implementations making use of the WorkflowMax v3 API and OAuth2
C#
1
star
50

xero-landing-page

A landing page template to help app partners market their new integration in Xero's marketplace
1
star
51

xero-net-oauth2-sampletokenmigration

Sample app for migrating OAuth1.0a tokens to OAuth2.0 tokens.
C#
1
star
52

Xero-Net-Sign-Up-With-Xero-Samples

C#
1
star
53

Xero-NetStandard-custom-connections-starter

Starter app showing Xero's Custom Connections functionality aka OA2 grant_type: `client_credentials`
C#
1
star
54

xero-python-custom-connections-starter

Custom Connections starter app for xero-python and client_credentials grant
Python
1
star