Xeroizer
Xero accounting system API library.
Install / Use
/learn @waynerobinson/XeroizerREADME
Xeroizer API Library
Homepage: http://waynerobinson.github.com/xeroizer
Git: git://github.com/waynerobinson/xeroizer.git
Github: https://github.com/waynerobinson/xeroizer
Author: Wayne Robinson http://www.wayne-robinson.com
Contributors: See Contributors section below
Copyright: 2007-2013
License: MIT License
Introduction
This library is designed to help ruby/rails based applications communicate with the publicly available API for Xero.
If you are unfamiliar with the Xero API, you should first read the documentation located at http://developer.xero.com.
Installation
gem install xeroizer
Basic Usage
require 'rubygems'
require 'xeroizer'
# Create client (used to communicate with the API).
client = Xeroizer::OAuth2Application.new(YOUR_OAUTH2_CLIENT_ID, YOUR_OAUTH2_CLIENT_SECRET)
# Retrieve list of contacts (note: all communication must be made through the client).
contacts = client.Contact.all(:order => 'Name')
Authentication
Example Rails Controller
class XeroSessionController < ApplicationController
before_filter :get_xero_client
public
def new
url = @xero_client.authorize_url(
# The URL's domain must match that listed for your application
# otherwise the user will see an invalid redirect_uri error
redirect_uri: YOUR_CALLBACK_URL,
# space separated, see all scopes at https://developer.xero.com/documentation/oauth2/scopes.
# note that `offline_access` is required to get a refresh token, otherwise the access only lasts for 30 mins and cannot be refreshed.
scope: "accounting.settings.read offline_access"
)
redirect_to url
end
def create
token = @xero_client.authorize_from_code(
params[:code],
redirect_uri: YOUR_CALLBACK_URL
)
connections = @xero_client.current_connections
session[:xero_auth] = {
:access_token => token[:access_token],
:refresh_token => token[:refresh_token],
:tenant_id => connections[1][:tenant_id]
}
end
def destroy
session.data.delete(:xero_auth)
end
private
def get_xero_client
@xero_client = Xeroizer::OAuth2Application.new(
YOUR_OAUTH2_CLIENT_ID,
YOUR_OAUTH2_CLIENT_SECRET,
)
# Add AccessToken if authorised previously.
if session[:xero_auth]
@xero_client.tenant_id = session[:xero_auth][:tenant_id]
@xero_client.authorize_from_access(session[:xero_auth][:acesss_token])
end
end
end
OAuth2 Applications
For more details, checkout Xero's documentation
- Generate the authorization url and redirect the user to authenticate
client = Xeroizer::OAuth2Application.new(
YOUR_OAUTH2_CLIENT_ID,
YOUR_OAUTH2_CLIENT_SECRET,
)
url = client.authorize_url(
# The URL's domain must match that listed for your application
# otherwise the user will see an invalid redirect_uri error
redirect_uri: YOUR_CALLBACK_URL,
# space separated, see all scopes at https://developer.xero.com/documentation/oauth2/scopes.
# note that `offline_access` is required to get a refresh token, otherwise the access only lasts for 30 mins and cannot be refreshed.
scope: "accounting.settings.read offline_access"
)
# Rails as an example
redirect_to url
- In the callback route, use the provided code to retrieve an access token.
token = client.authorize_from_code(
params[:code],
redirect_uri: YOUR_CALLBACK_URL
)
token.to_hash
# {
# "token_type"=>"Bearer",
# "scope"=>"accounting.transactions.read accounting.settings.read",
# :access_token=>"...",
# :refresh_token=>nil,
# :expires_at=>1615220292
# }
# Save the access_token, refresh_token...
- Retrieve the tenant ids.
connections = client.current_connections
# returns Xeroizer::Connection instances
# Save the tenant ids
- Use access token and tenant ids to retrieve data.
client = Xeroizer::OAuth2Application.new(
YOUR_OAUTH2_CLIENT_ID,
YOUR_OAUTH2_CLIENT_SECRET,
access_token: access_token,
tenant_id: tenant_id
)
# OR
client = Xeroizer::OAuth2Application.new(
YOUR_OAUTH2_CLIENT_ID,
YOUR_OAUTH2_CLIENT_SECRET,
tenant_id: tenant_id
).authorize_from_access(access_token)
# use the client
client.Organisation.first
AccessToken Renewal
Renewal of an access token requires the refresh token generated for this organisation. To renew:
client = Xeroizer::OAuth2Application.new(
YOUR_OAUTH2_CLIENT_ID,
YOUR_OAUTH2_CLIENT_SECRET,
access_token: access_token,
refresh_token: refresh_token
)
client.renew_access_token
If you lose these details at any stage you can always reauthorise by redirecting the user back to the Xero OAuth gateway.
Custom Connections
Custom Connections are a paid-for option for private M2M applications. The generated token expires and needs recreating if expired.
client = Xeroizer::OAuth2Application.new(
YOUR_OAUTH2_CLIENT_ID,
YOUR_OAUTH2_CLIENT_SECRET
)
token = client.authorize_from_client_credentials
You can check the status of the token with the expires? and expired? methods.
Retrieving Data
Each of the below record types is implemented within this library. To allow for multiple access tokens to be used at the same time in a single application, the model classes are accessed from the instance of OAuth2Application. All class-level operations occur on this singleton. For example:
xero = Xeroizer::OAuth2Application.new(YOUR_OAUTH2_CLIENT_ID, YOUR_OAUTH2_CLIENT_SECRET, tenant_id: tenant_id)
xero.authorize_from_access(session[:xero_auth][:access_token])
contacts = xero.Contact.all(:order => 'Name')
new_contact = xero.Contact.build(:name => 'ABC Development')
saved = new_contact.save
#all([options])
Retrieves list of all records with matching options.
Note: Some records (Invoice, CreditNote) only return summary information for the contact and no line items when returning them this list operation. This library takes care of automatically retrieving the contact and line items from Xero on first access however, this first access has a large performance penalty and will count as an extra query towards your 5,000/day and 60/minute request per organisation limit.
Valid options are:
:modified_since
Records modified after this
Time(must be specified in UTC).
:order
Field to order by. Should be formatted as Xero-based field (e.g. 'Name', 'ContactID', etc)
:status
Status field for PurchaseOrder. Should be a valid Xero purchase order status.
:date_from
DateFrom field for PurchaseOrder. Should be in YYYY-MM-DD format.
:date_to
DateTo field for PurchaseOrder. Should be in YYYY-MM-DD format.
:where
See Where Filters section below.
#first([options])
This is a shortcut method for all and actually runs all however, this method only returns the
first entry returned by all and never an array.
#find(id)
Looks up a single record matching id. This ID can either be the internal GUID Xero uses for the record
or, in the case of Invoice, CreditNote and Contact records, your own custom reference number used when
creating these records.
Where filters
Hash
You can specify find filters by providing the :where option with a hash. For example:
invoices = Xero.Invoice.all(:where => {:type => 'ACCREC', :amount_due_is_not => 0})
will automatically create the Xero string:
Type=="ACCREC"&&AmountDue<>0
The default method for filtering is the equality '==' operator however, these can be overridden by modifying the postfix of the attribute name (as you can see for the :amount_due field above).
\{attribute_name}_is_not will use '<>'
\{attribute_name}_is_greater_than will use '>'
\{attribute_name}_is_greater_than_or_equal_to will use '>='
\{attribute_name}_is_less_than will use '<'
\{attribute_name}_is_less_than_or_equal_to will use '<='
The default is '=='
Note: Currently, the hash-conversion library only allows for AND-based criteria and doesn't take into account associations. For these, please use the custom filter method below.
Custom Xero-formatted string
Xero allows advanced custom filters to be added to a request. The where parameter can reference any XML element in the resulting response, including all nested XML elements.
Example 1: Retrieve all invoices for a specific contact ID:
invoices = xero.Invoice.all(:where => 'Contact.ContactID.ToString()=="cd09aa49-134d-40fb-a52b-b63c6a91d712"')
Example 2: Retrieve all unpaid ACCREC Invoices against a particular Contact Name:
invoices = xero.Invoice.all(:where => 'Contact.Name=="Basket Case" && Type=="ACCREC" && AmountDue<>0')
Example 3: Retrieve all Invoices PAID between certain dates
invoices = xero.Invoice.all(:where => 'FullyPaidOnDate>=DateTime.Parse("2010-01-01T00:00:00")&&FullyPaidOnDate<=DateTime.Parse("2010-01-08T00:00:00")')
Example 4: Retrieve all Invoices using Paging (batches of 100)
invoices = xero.Invoice.find_in_batches({page_number: 1}) do |invoice_batch|
invoice_batch.each do |invoice|
...
end
end
Example 5: Retrieve all Bank Accounts:
accounts = xero.Account.all(:where => 'Type=="BANK"')
Example 6: Retrieve all DELETED or VOIDED Invoices:
invoices = xero.Invoice.all(:where => 'Status=="VOIDED" OR Status=="DELETED"')
Example 7: Retrieve all contacts with specific text in the contact name:
contacts = xero.Contact.all(:where => 'Name.Contains("Peter")')
contacts = xero.Contact.all(:where => 'Name.StartsWith("Pet")')
contacts = xero.Contact.all(:where => 'Name.EndsWith("er")')
Associations
Records may be associated with each other via two diffe
Related Skills
beanquery-mcp
43Beancount MCP Server is an experimental implementation that utilizes the Model Context Protocol (MCP) to enable AI assistants to query and analyze Beancount ledger files using Beancount Query Language (BQL) and the beanquery tool.
REFERENCE
An intelligent middleware layer between crypto wallets and traditional payment systems.
cashu-skill
A Cashu wallet skill for AI agents
mcp-yfinance-server
49Real-time stock API with Python, MCP server example, yfinance stock analysis dashboard
