Xero Ruby SDK for OAuth 2.0 generated from Xero API OpenAPI Spec
Xero Ruby SDK supports Xero's OAuth2.0 authentication (token generation & refresh) and supports the following Xero API sets.
Coming soon
- bank feeds
- payroll (AU))
- payroll (NZ/UK)
- files
- xero hq
Check out the Xeroizer gem (maintained by community)
This SDK is published as a gem on RubyGems as xero-ruby To install this gem to your current gemset, run:
gem install 'xero-ruby'
Or, add this to your gemfile:
gem 'xero-ruby'
- Create a free Xero user account
- Login to your Xero developer /myapps dashboard & create an API application and note your API app's credentials.
Require the gem:
require 'xero-ruby'
Then create a client by passing in a named hash object credentials:
.
client_id, client_secret, redirect_uri: Get this from your API application in /myapps dashboard. scopes: Include scopes as comma seperated list, https://developer.xero.com/documentation/oauth2/scopes ex: 'openid profile email accounting.transactions'
creds = {
client_id: ENV['CLIENT_ID'],
client_secret: ENV['CLIENT_SECRET'],
redirect_uri: ENV['REDIRECT_URI'],
scopes: ENV['SCOPES']
}
xero_client ||= XeroRuby::ApiClient.new(credentials: creds)
All API requests require a valid access token to be set on the client. If this is the first time you are calling the Xero API on a users behalf you will need to generate an authorized token set, which will look something like this:
{
"id_token": "xxx.yyy.zz",
"access_token": "xxx.yyy.zzz",
"expires_in": 1800,
"token_type": "Bearer",
"refresh_token": "xxxxxx",
"scope": "email profile openid accounting.transactions offline_access"
}
To generate a valid token_set with this SDK from Xero, have your user follow the authorization url:
@authorization_url = xero_client.authorization_url
# https://login.xero.com/identity/connect/authorize?response_type=code&client_id=<xxx>&redirect_uri=<redirect_uri>&scope=<scopes>
The
get_token_set_from_callback
method will set thetoken_set
on the client, however you can also initialize a client and set thetoken_set
explicitly usingset_token_set
orrefresh_token_set
.
# /my-redirect-uri
token_set = xero_client.get_token_set_from_callback(params)
# this is where you will want to save the token set for future API usage..
# ex: user.update!(xero_token_set: token_set)
# if you already saved a token_set you don't need the user to authenticate via UI
# and can just set the token on the client by refreshing it.
xero_client.refresh_token_set(user.token_set)
Token Sets contain information about your API connection, but most important are the access_token, refresh_token, and the expiry:
- An
access_token
is valid 30 minutes and arefresh_token
is valid for 60 days
@token_set = xero_client.refresh_token_set(user.token_set)
# TIP: the `updatedDateUtc` will show you the most recently authorized Tenant (AKA Organisation)
connections = xero_client.connections
[{
"id" => "xxx-yyy-zzz",
"tenantId" => "xxx-yyy-zzz",
"tenantType" => "ORGANISATION",
"tenantName" => "Demo Company (US)",
"createdDateUtc" => "2019-11-01T20:08:03.0766400",
"updatedDateUtc" => "2020-04-15T22:37:10.4943410"
}]
# disconnect an org from a user's connections. Pass the connection ['id'] not ['tenantId'].
remaining_connections = xero_client.disconnect(connections[0]['id'])
# set token_set
token_set = xero_client.set_token_set(user.token_set)
# access token_set
token_set = xero_client.token_set
Comprehensive xero-ruby API usage is showcased here: https://github.com/XeroAPI/xero-ruby-oauth2-app
Here is the basic workflow of using SDK once you have a valid access_token
(and token_set
) stored on an instance of the xero_client
require 'xero-ruby'
# reference `Authorization & Callback` to first store a valid token_set on the `xero_client`
xero_client.refresh_token_set(user.token_set)
# Using the Accounting API set (https://github.com/XeroAPI/xero-ruby/blob/master/accounting/lib/xero-ruby/api/accounting_api.rb)
# Examples
invoices = xero_client.accounting_api.get_invoices(user.active_tenant_id).invoices
accounts = xero_client.accounting_api.get_accounts(user.active_tenant_id).accounts
contacts = xero_client.accounting_api.get_contacts(user.active_tenant_id).contacts
contacts = xero_client.accounting_api.get_contacts(current_user.active_tenant_id).contacts
invoices = { invoices: [{ type: XeroRuby::Accounting::Invoice::ACCREC, contact: { contact_id: contacts[0].contact_id }, line_items: [{ description: "Acme Tires", quantity: BigDecimal("2.0"), unit_amount: BigDecimal("20.99"), account_code: "600", tax_type: XeroRuby::Accounting::TaxType::NONE }], date: "2019-03-11", due_date: "2018-12-10", reference: "Website Design", status: XeroRuby::Accounting::Invoice::DRAFT }]}
invoice = xero_client.accounting_api.create_invoices(current_user.active_tenant_id, invoices).invoices.first
# all money and fields requiring advanced precision utilize BigDecimal
puts invoice.unit_amount
=> 0.2099e2
puts invoice.unit_amount.class
=> BigDecimal
puts invoice.unit_amount.to_s("F")
=> "20.99"
# or if using Rails https://api.rubyonrails.org/classes/ActionView/Helpers/NumberHelper.html#method-i-number_to_currency
number_to_currency(invoice.unit_amount, :unit => "$")
# creating an object History record
payment = xero_client.accounting_api.get_payments(current_user.active_tenant_id).payments.first
history_records = { history_records:[ { details: "This payment now has some History #{rand(10000)}" } ]}
payment_history = xero_client.accounting_api.create_payment_history(user.active_tenant_id, payment.payment_id, history_records)
# creating an object Attachment record
account = xero_client.accounting_api.get_accounts(current_user.active_tenant_id).accounts.first
file_name = "an-account-filename.png"
opts = {
include_online: true # Boolean | Allows an attachment to be seen by the end customer within their online invoice
}
file = File.read(Rails.root.join('app/assets/images/xero-api.png'))
attachment = xero_client.accounting_api.create_account_attachment_by_file_name(current_user.active_tenant_id, @account.account_id, file_name, file, opts)
# Using the Asset API set (https://github.com/XeroAPI/xero-ruby/blob/master/accounting/lib/xero-ruby/api/asset_api.rb)
asset = {
"assetName": "AssetName: #{rand(10000)}",
"assetNumber": "Asset: #{rand(10000)}",
"assetStatus": "DRAFT"
}
asset = xero_client.asset_api.create_asset(current_user.active_tenant_id, asset)
# Using the Project API set (https://github.com/XeroAPI/xero-ruby/blob/master/docs/projects/ProjectApi.md)
projects = xero_client.project_api.get_projects(current_user.active_tenant_id).items
If you have use cases outside of these examples or this readmy, please let us know!
The best resource to understanding how to best leverage this SDK is to clone down our Sample Rails application which showcases all the features of this project. The sample app can help you quickly understand how to:
- Complete the OAuth2.0 Authorization flow
- Store token_sets against a user object in a DB
- Storing info about active connections
- Change the active tenant & make api calls to multiple orgs
- Refreshing your token sets
- Decoding your token_set items and strategy around how/when to refresh
- Disconnecting a connection for a user