diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 00000000..d05f4bc0
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,74 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and maintainers pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, gender identity and expression, level of experience,
+nationality, personal appearance, race, religion, or sexual identity and
+orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or
+advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic
+ address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable
+behavior and are expected to take appropriate and fair corrective action in
+response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or
+reject comments, commits, code, wiki edits, issues, and other contributions
+that are not aligned to this Code of Conduct, or to ban temporarily or
+permanently any contributor for other behaviors that they deem inappropriate,
+threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community. Examples of
+representing a project or community include using an official project e-mail
+address, posting via an official social media account, or acting as an appointed
+representative at an online or offline event. Representation of a project may be
+further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported by contacting the project team at [INSERT EMAIL ADDRESS]. All
+complaints will be reviewed and investigated and will result in a response that
+is deemed necessary and appropriate to the circumstances. The project team is
+obligated to maintain confidentiality with regard to the reporter of an incident.
+Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good
+faith may face temporary or permanent repercussions as determined by other
+members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
+available at [http://contributor-covenant.org/version/1/4][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/4/
diff --git a/README.md b/README.md
index 2ce89bea..01e7ca76 100644
--- a/README.md
+++ b/README.md
@@ -1,110 +1,140 @@
Xero API wrapper [![Build Status](https://travis-ci.org/xero-gateway/xero_gateway.svg?branch=master)](https://travis-ci.org/xero-gateway/xero_gateway) [![Gem Version](https://badge.fury.io/rb/xero_gateway.svg)](https://badge.fury.io/rb/xero_gateway)
================
-Introduction
-------------
+# Getting Started
-This library is designed to help ruby / rails based applications
-communicate with the publicly available API for Xero. If you are
-unfamiliar with the API, you should first read the documentation,
-located here
+This is a Ruby gem for communicating with the Xero API.
+You can find more information about the Xero API at .
-Usage
------
+## Installation
- require 'xero_gateway'
- gateway = XeroGateway::Gateway.new(YOUR_OAUTH_CONSUMER_KEY, YOUR_OAUTH_CONSUMER_SECRET)
+Just add the `xero_gateway` gem to your Gemfile, like so:
-Authenticating with OAuth
--------------------------
+```ruby
+ gem 'xero_gateway'
+```
-OAuth is built into this library in a very similar manner to the Twitter
-gem by John Nunemaker
-([http://github.com/jnunemaker/twitter](http://github.com/jnunemaker/twitter)).
-So if you've used that before this will all seem familiar.
+## Usage
-### Consumer Key & Secret
+```ruby
+ gateway = XeroGateway::Gateway.new(YOUR_OAUTH_CONSUMER_KEY, YOUR_OAUTH_CONSUMER_SECRET)
+```
-First off, you'll need to get a Consumer Key/Secret pair for your
-application from Xero.\
-Head to , log in and then click My Applications
-> Add Application.
+### Authenticating with OAuth
-If you want to create a private application (that accesses your own Xero
-account rather than your users), you'll need to generate an RSA keypair
-and an X509 certificate. This can be done with OpenSSL as below:
+The Xero Gateway uses [OAuth 1.0a](https://oauth.net/core/1.0a/) for authentication. Xero Gateway
+implements OAuth in a very similar manner to the [Twitter gem by John Nunemaker](http://github.com/jnunemaker/twitter)
+, so if you've used that before this will all seem familiar.
- openssl genrsa –out privatekey.pem 1024
- openssl req –newkey rsa:1024 –x509 –key privatekey.pem –out publickey.cer –days 365
- openssl pkcs12 –export –out public_privatekey.pfx –inkey privatekey.pem –in publickey.cer
+ 1. **Get a Consumer Key & Secret**
-On the right-hand-side of your application's page there's a box titled
-"OAuth Credentials". Use the Key and Secret from this box in order to
-set up a new Gateway instance.
+ First off, you'll need to get a Consumer Key/Secret pair for your
+ application from Xero.\
+ Head to , log in and then click My Applications
+ > Add Application.
-(If you're unsure about the Callback URL, specify nothing - it will
-become clear a bit later)
+ If you want to create a private application (that accesses your own Xero
+ account rather than your users), you'll need to generate an RSA keypair
+ and an X509 certificate. This can be done with OpenSSL as below:
-### Xero Gateway Initialization
+ ```
+ openssl genrsa –out privatekey.pem 1024
+ openssl req –newkey rsa:1024 –x509 –key privatekey.pem –out publickey.cer –days 365
+ openssl pkcs12 –export –out public_privatekey.pfx –inkey privatekey.pem –in publickey.cer
+ ```
- require 'xero_gateway'
- gateway = XeroGateway::Gateway.new(YOUR_OAUTH_CONSUMER_KEY, YOUR_OAUTH_CONSUMER_SECRET)
+ On the right-hand-side of your application's page there's a box titled
+ "OAuth Credentials". Use the Key and Secret from this box in order to
+ set up a new Gateway instance.
-or for private applications
+ (If you're unsure about the Callback URL, specify nothing - it will
+ become clear a bit later)
- require 'xero_gateway'
- gateway = XeroGateway::PrivateApp.new(YOUR_OAUTH_CONSUMER_KEY, YOUR_OAUTH_CONSUMER_SECRET, PATH_TO_YOUR_PRIVATE_KEY)
+ 2. **Create a Xero Gateway in your App**
-### Request Token
+ ```ruby
+ gateway = XeroGateway::Gateway.new(YOUR_OAUTH_CONSUMER_KEY, YOUR_OAUTH_CONSUMER_SECRET)
+ ```
-You'll then need to get a Request Token from Xero.
+ or for Private applications
- request_token = gateway.request_token
+ ```ruby
+ require 'xero_gateway'
+ gateway = XeroGateway::PrivateApp.new(YOUR_OAUTH_CONSUMER_KEY, YOUR_OAUTH_CONSUMER_SECRET, PATH_TO_YOUR_PRIVATE_KEY)
+ ```
-You should keep this around - you'll need it to exchange for an Access
-Token later. (If you're using Rails, this means storing it in the
-session or something similar)
+ 3. **Creating a Request Token**
-Next, you need to redirect your user to the authorisation url for this
-request token. In Rails, that looks something like this:
+ You'll then need to get a Request Token from Xero.
- redirect_to request_token.authorize_url
+ ```ruby
+ request_token = gateway.request_token
+ ```
-You may also provide a callback parameter, which is the URL within your
-app the user will be redirected to. See next section for more
-information on what parameters Xero sends with this request.
+ You should keep this around - you'll need it to exchange for an Access
+ Token later. (If you're using Rails, this means storing it in the
+ session or something similar)
- redirect_to request_token(:oauth_callback => "http://www.something.com/xero/complete").authorize_url
+ Next, you need to redirect your user to the authorization url for this
+ request token. In Rails, that looks something like this:
-### Retrieving an Access Token
+ ```ruby
+ redirect_to request_token.authorize_url
+ ```
-If you've specified a Callback URL when setting up your application or
-provided an oauth\_callback parameter on your request token, your user
-will be redirected to that URL with an OAuth Verifier as a GET
-parameter. You can then exchange your Request Token for an Access Token
-like this (assuming Rails, once again):
+ You may also provide a callback parameter, which is the URL within your
+ app the user will be redirected to. See next section for more
+ information on what parameters Xero sends with this request.
- gateway.authorize_from_request(request_token.token, request_token.secret, :oauth_verifier => params[:oauth_verifier])
+ ```ruby
+ request_token = request_token(oauth_callback: "http://yourapp.comcom/xero/callback")
+ redirect_to request_token.authorize_url
+ ```
-(If you haven't specified a Callback URL, the user will be presented
-with a numeric verifier which they must copy+paste into your
-application; see examples/oauth.rb for an example)
+ 4. **Retrieving an Access Token**
-Now you can access Xero API methods:
+ If you've specified a Callback URL when setting up your application or
+ provided an oauth\_callback parameter on your request token, your user
+ will be redirected to that URL with an OAuth Verifier as a GET
+ parameter. You can then exchange your Request Token for an Access Token
+ like this (assuming Rails, once again):
- gateway.get_contacts
+ ```ruby
+ gateway.authorize_from_request(request_token.token, request_token.secret, oauth_verifier: params[:oauth_verifier])
+ ```
+
+ (If you haven't specified a Callback URL, the user will be presented
+ with a numeric verifier which they must copy+paste into your
+ application; see examples/oauth.rb for an example)
+
+ Now you can access Xero API methods:
+
+ ```ruby
+ gateway.get_contacts
+ # => # params[:oauth_verifier])
+ def create
+ @xero_gateway.authorize_from_request(session[:request_token], session[:request_secret],
+ oauth_verifier: params[:oauth_verifier])
- session[:xero_auth] = { :access_token => @xero_gateway.access_token.token,
- :access_secret => @xero_gateway.access_token.secret }
+ session[:xero_auth] = { access_token: @xero_gateway.access_token.token,
+ access_secret: @xero_gateway.access_token.secret }
- session.data.delete(:request_token); session.data.delete(:request_secret)
- end
+ session.data.delete(:request_token)
+ session.data.delete(:request_secret)
+ end
- def destroy
- session.data.delete(:xero_auth)
- end
+ def destroy
+ session.data.delete(:xero_auth)
+ end
- private
-
- def get_xero_gateway
- @xero_gateway = XeroGateway::Gateway.new(YOUR_OAUTH_CONSUMER_KEY, YOUR_OAUTH_CONSUMER_SECRET)
- end
+ private
+ def get_xero_gateway
+ @xero_gateway = XeroGateway::Gateway.new(YOUR_OAUTH_CONSUMER_KEY, YOUR_OAUTH_CONSUMER_SECRET)
end
+ end
+```
+
Note that I'm just storing the Access Token + Secret in the session here
- you could equally store them in the database if you felt like
refreshing them every 30 minutes ;)
-Implemented interface methods
------------------------------
-
-### GET /api.xro/2.0/contact (get\_contact\_by\_id)
-
-Gets a contact record for a specific Xero organisation
-
- result = gateway.get_contact_by_id(contact_id)
- contact = result.contact if result.success?
-
-### GET /api.xro/2.0/contact (get\_contact\_by\_number)
-
-Gets a contact record for a specific Xero organisation
-
- gateway.get_contact_by_number(contact_number)
-
-### GET /api.xro/2.0/contacts (get\_contacts)
-
-Gets all contact records for a particular Xero customer.
-
- gateway.get_contacts(:type => :all, :sort => :name, :direction => :desc)
- gateway.get_contacts(:type => :all, :modified_since => 1.month.ago) # modified since 1 month ago
-
-### PUT /api.xro/2.0/contact
-
-Saves a contact record for a particular Xero customer.
-
- contact = gateway.build_contact
- contact.name = "The contacts name"
- contact.email = "whoever@something.com"
- contact.phone.number = "555 123 4567"
- contact.address.line_1 = "LINE 1 OF THE ADDRESS"
- contact.address.line_2 = "LINE 2 OF THE ADDRESS"
- contact.address.city = "WELLINGTON"
- contact.address.region = "WELLINGTON"
- contact.address.country = "NEW ZEALAND"
- contact.address.post_code = "6021"
-
- contact.save
-
-### POST /api.xro/2.0/contact
-
-Updates an existing contact record.
-
- contact_retrieved_from_xero.email = "something_new@something.com"
- contact_retrieved_from_xero.save
-
-### POST /api.xro/2.0/contacts
-
-Creates a list of contacts or updates them if they have a matching
-contact\_id, contact\_number or name.\
-This method uses only a single API request to create/update multiple
-contacts.
-
- contacts = [XeroGateway::Contact.new(:name => 'Joe Bloggs'), XeroGateway::Contact.new(:name => 'Jane Doe')]
- result = gateway.update_contacts(contacts)
-
-### GET /api.xro/2.0/invoice (get\_invoice)
-
-Gets an invoice record for a specific Xero organisation by either id or
-number
-
- gateway.get_invoice(invoice_id_or_number)
-
-### GET /api.xro/2.0/invoices (get\_invoices)
-
-Gets all invoice records for a particular Xero customer.
-
- gateway.get_invoices
- gateway.get_invoices(:modified_since => 1.month.ago) # modified since 1 month ago
-
-### PUT /api.xro/2.0/invoice
-
-Inserts an invoice for a specific organization in Xero (Currently only
-adding new invoices is allowed).
-
-Invoice and line item totals are calculated automatically.
-
- invoice = gateway.build_invoice({
- :invoice_type => "ACCREC",
- :due_date => 1.month.from_now,
- :invoice_number => "YOUR INVOICE NUMBER",
- :reference => "YOUR REFERENCE (NOT NECESSARILY UNIQUE!)",
- :line_amount_types => "Inclusive" # "Inclusive", "Exclusive" or "NoTax"
- })
- invoice.contact.name = "THE NAME OF THE CONTACT"
- invoice.contact.phone.number = "12345"
- invoice.contact.address.line_1 = "LINE 1 OF THE ADDRESS"
-
- line_item = XeroGateway::LineItem.new(
- :description => "THE DESCRIPTION OF THE LINE ITEM",
- :account_code => 200,
- :unit_amount => 1000
- )
-
- line_item.tracking << XeroGateway::TrackingCategory.new(:name => "tracking category", :options => "tracking option")
-
- invoice.line_items << line_item
-
- invoice.create
-
-### POST /api.xro/2.0/invoice
-
-Updates an existing invoice record.
+## API Methods
- invoice_retrieved_from_xero.due_date = Date.today
- invoice_retrieved_from_xero.save
+You can find a full listing of all implemented methods on [the wiki page](https://github.com/xero-gateway/xero_gateway/wiki/API-Methods).
-### PUT /api.xro/2.0/invoices
+## Logging
-Inserts multiple invoices for a specific organization in Xero (currently
-only adding new invoices is allowed).\
-This method uses only a single API request to create/update multiple
-contacts.
-
- invoices = [XeroGateway::Invoice.new(...), XeroGateway::Invoice.new(...)]
- result = gateway.create_invoices(invoices)
-
-### GET /api.xro/2.0/credit\_note (get\_credit\_note\_by\_id)
-
-Gets an credit\_note record for a specific Xero organisation
-
- gateway.get_credit_note_by_id(credit_note_id)
-
-### GET /api.xro/2.0/credit\_note (get\_credit\_note\_by\_number)
-
-Gets a credit note record for a specific Xero organisation
-
- gateway.get_credit_note_by_number(credit_note_number)
-
-### GET /api.xro/2.0/credit\_notes (get\_credit\_notes)
-
-Gets all credit note records for a particular Xero customer.
-
- gateway.get_credit_notes
- gateway.get_credit_notes(:modified_since => 1.month.ago) # modified since 1 month ago
-
-### PUT /api.xro/2.0/credit\_note
-
-Inserts a credit note for a specific organization in Xero (Currently
-only adding new credit notes is allowed).
-
-CreditNote and line item totals are calculated automatically.
-
- credit_note = gateway.build_credit_note({
- :credit_note_type => "ACCRECCREDIT",
- :credit_note_number => "YOUR CREDIT NOTE NUMBER",
- :reference => "YOUR REFERENCE (NOT NECESSARILY UNIQUE!)",
- :line_amount_types => "Inclusive" # "Inclusive", "Exclusive" or "NoTax"
- })
- credit_note.contact.name = "THE NAME OF THE CONTACT"
- credit_note.contact.phone.number = "12345"
- credit_note.contact.address.line_1 = "LINE 1 OF THE ADDRESS"
- credit_note.add_line_item({
- :description => "THE DESCRIPTION OF THE LINE ITEM",
- :unit_amount => 1000,
- :tax_amount => 125,
- :tracking_category => "THE TRACKING CATEGORY FOR THE LINE ITEM",
- :tracking_option => "THE TRACKING OPTION FOR THE LINE ITEM"
- })
-
- credit_note.create
-
-### PUT /api.xro/2.0/credit\_notes
-
-Inserts multiple credit notes for a specific organization in Xero
-(currently only adding new credit notes is allowed).\
-This method uses only a single API request to create/update multiple
-contacts.
-
- credit_notes = [XeroGateway::CreditNote.new(...), XeroGateway::CreditNote.new(...)]
- result = gateway.create_credit_notes(credit_notes)
-
-### GET /api.xro/2.0/accounts
-
-Gets all accounts for a specific organization in Xero.
-
- gateway.get_accounts
-
-For more advanced (and cached) access to the accounts list, use the
-following.
-
- accounts_list = gateway.get_accounts_list
-
-Finds account with code of '200'
-
- sales_account = accounts_list.find_by_code(200)
-
-Finds all EXPENSE accounts. For a list of valid account types see
-XeroGateway::Account::TYPE
-
- all_expense_accounts = accounts_list.find_all_by_type('EXPENSE')
-
-Finds all accounts with tax\_type == 'OUTPUT'. For a list of valid tax
-types see XeroGateway::Account::TAX\_TYPE
-
- all_output_tax_accounts = accounts_list.find_all_by_tax_type('OUTPUT')
-
-### GET /api.xro/2.0/tracking
-
-Gets all tracking categories and their options for a specific
-organization in Xero.
-
- gateway.get_tracking_categories
-
-### GET /api.xero/2.0/Organisation
-
-Retrieves organisation details for the authorised application.
-
- gateway.get_organisation.organisation
-
-### GET /api.xero/2.0/Currencies
-
-Retrieves currencies in use for the authorised application.
-
- gateway.get_currencies.currencies
-
-### GET /api.xero/2.0/TaxRates
+You can specify a logger to use (so you can track down those tricky
+exceptions) by using:
-Retrieves Tax Rates in use for the authorised application.
+```ruby
+ gateway.logger = ActiveSupport::BufferedLogger.new("log_file_name.log")
+```
- gateway.get_tax_rates.tax_rates
+Your logger simply needs to respond to `info`.
-Logging
--------
+## Contributing
-You can specify a logger to use (so you can track down those tricky
-exceptions) by using:
+We welcome contributions, thanks for pitching in! :sparkles:
- gateway.logger = ActiveSupport::BufferedLogger.new("log_file_name.log")
+1. Fork the repo
+2. Create your feature branch (`git checkout -b my-new-feature`)
+3. Make sure you have some tests, and they pass! (`bundle exec rake`)
+4. Commit your changes (`git commit -am 'Added some feature'`)
+5. Push to the branch (`git push origin my-new-feature`)
+6. Create new Pull Request
-It doesn't have to be a buffered logger - anything that responds to
-"info" will do just fine.
+This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.