Skip to content
 


How to : integrate my invoicing system with Xero

Overview

The Xero Customer API provides an easy way for developers to integrate a custom built invoicing system with Xero. Invoices need to be transformed into a Xero specified XML format and sent to our REST based Customer API along with a Xero API key and an organisation key. Once invoices have been approved in Xero they can be queried periodically to see if they have been paid.

We will walk through an example of how to use the Xero API to populate a Xero organisation with AR (Accounts Receivable) invoices generated in another invoicing system.

All invoices stored in Xero are linked to a Xero Contact so before you add an invoice it is recommended that you enter or update the contact details for the invoice. Using this approach we will use two API methods to enter the invoice data in Xero – POST Contact and PUT Invoice.

Later on we will use the GET Invoices method to query an invoice to see if it has been paid.

addinginvoicesusingxeroapi2

  1. Add or update a contact in Xero using the POST Contact method
  2. Add AR invoice to Xero with the PUT Invoice method
  3. Query the GET Invoice method periodically to see if invoices have bene paid (optional)

1. Adding and updating contacts

  • Use the POST contact method before you send an invoice to Xero to make sure a contact record exists for the invoice.
  • The ContactNumber field cannot be entered in the Xero UI but can be entered using the Xero API. The purpose of this field is to store a unique identifier for contacts from another system.
  • The contact Name is a also a unique field in Xero.
  • The ContactStatus should be set to ACTIVE
  • The ContactID is a GUID generated by Xero which uniquely identifies each contact in an organisation. The ContactID is returned in responses and cannot be altered. Once you have created a contact in Xero you should send the ContactID with future updates.You shouldn’t specify this element if you don’t already have the contact in Xero.
  • Address Type can be POBOX or STREET
  • Phone Type can be DEFAULT, DDI, MOBILE or FAX

Using the POST Contact method to add a new contact– sending the request

You can use a server side language (such as ASP.net, Coldfusion, Java or PHP) to send the following XML using a HTTP Post to https://networktest.xero.com/api.xro/1.0/Contact?apiKey=[API KEY GOES HERE]&xeroKey=[XERO ORGANISATION KEY GOES HERE]

<Contact>
	<ContactNumber>C20081234</ContactNumber>
	<ContactStatus>ACTIVE</ContactStatus>
	<Name>Red House Reads</Name>
	<EmailAddress>accounts@redhousereads.co.nz</EmailAddress>
	<Addresses>
		<Address>
			<AddressType>POBOX</AddressType>
			<AddressLine1>Lvl 1</AddressLine1>
			<AddressLine2>Herd St Building</AddressLine2>
			<AddressLine3>Herd St</AddressLine3>
			<AddressLine4>Wellington</AddressLine4>
			<City>Wellington</City>
			<Region>Wellington</Region>
			<PostalCode>6011</PostalCode>
			<Country>New Zealand</Country>
		</Address>
	</Addresses>
	<Phones>
		<Phone>
			<PhoneType>DEFAULT</PhoneType>
			<PhoneNumber>1234567</PhoneNumber>
			<PhoneAreaCode>4</PhoneAreaCode>
			<PhoneCountryCode>64</PhoneCountryCode>
		</Phone>
	</Phones>
</Contact>

Using the POST Contact method – handling an OK response

We need to make sure we have logic in our code to handle responses from calls to the Xero API. The example below shows the standard XML response when you have successfully added a contact.

We need to check that the Status element has returned OK. We recommend to store the ContactID returned in the response against this contact in your invoicing system and include it in future updates to this contact – that way you can be sure you are updating an existing Xero contact.

<Response xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
	<ID>751ec648-919f-41bd-9fac-4068e27fece6</ID>
	<Status>OK</Status>
	<ProviderName>Xero</ProviderName>
	<DateTimeUTC>2008-12-02T21:09:24.654875Z</DateTimeUTC>
	<Contact>
		<ContactID>74141f5b-c409-4ddc-8f10-a2e6823c2b19</ContactID>
		<ContactNumber>C20081234</ContactNumber>
		<ContactStatus>ACTIVE</ContactStatus>
		<Name>Red House Reads</Name>
		<EmailAddress>accounts@redhousereads.co.nz</EmailAddress>
		<Addresses>
			<Address>

........

Using the POST Contact method – handling an error response

Below is an example of getting an error response to an API call. This error response is only useful to a developer so the description of the error message shouldn’t be shown to the end user. In this case because there was no Status element containing an OK response we should check to see if there is an Errors node with child nodes called Error.

We should log the error and display the user with an easy to interpret message that an error has occurred. An error type of this nature is unlikely to be resolved by offering the user to retry the previous action so we should give the user an appropriate choice of next action.

<Response xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <Errors>
    <Error>
      <Description>MDC4OGNLOWI3NZKXNDLINGFMMWRHNW is not a valid Xero authentication key for XeroTest. A key for XeroTest must be set up by each Xero customer</Description>

..........
</Response>

Handling other errors

  • Authentication error – If an incorrect Xero key has been provided then Xero will respond with an error. It would be useful to treat this error separately from a general exception.
  • No response or timeout – Our application should handle the case that the Xero API doesn’t respond or complete a response within 10000ms that there is an error. We should provide the user with the option to retry their request.

2. Adding invoices

  • The InvoiceType can be ACCREC or ACCPAY
  • Adding the contact details for an invoice can be reduced down to just the ContactID if you have already created a contact.
  • It is important to note that if you specify full contact information in the PUT invoice method and the contact already exists then the contact record won’t be updated. If the contact doesn’t exist then a new contact will be added.
  • You need to specify a unique InvoiceNumber for each invoice. Consider including an alpha prefix to clearly show that an invoice has originated from your invoicing system.
  • IncludesTax can be true or false
  • Subtotal is the sum of the line items tax exclusive
  • Totaltax is the sum of the tax on each line item
  • The Invoice Total should be the sum of the SubTotal and TotalTax
  • The individual line item LineAmount should be the product of Quantity x UnitAmount, i.e. tax exclusive.

Using the PUT Invoice method

https://networktest.xero.com/api.xro/1.0/Invoice

<Invoice>
	<InvoiceType>ACCREC</InvoiceType>
	<Contact>
		<ContactID>74141f5b-c409-4ddc-8f10-a2e6823c2b19
		</ContactID>
	</Contact>
	<InvoiceDate>2008-02-25T00:00:00</InvoiceDate>
	<DueDate>2008-02-15T00:00:00</DueDate>
	<InvoiceNumber>171208</InvoiceNumber>
	<Reference></Reference>
	<IncludesTax>true</IncludesTax>
	<SubTotal>379.5300</SubTotal>
	<TotalTax>47.4400</TotalTax>
	<Total>426.9700</Total>
	<LineItems>
		<LineItem>
			<Description>Copies of Windows for Mother</Description>
			<Quantity>10.0000</Quantity>
			<UnitAmount>39.9500</UnitAmount>
			<TaxType>OUTPUT</TaxType>
			<TaxAmount>49.9400</TaxAmount>
			<LineAmount>399.5000</LineAmount>
			<AccountCode>200</AccountCode>
			<Tracking>
				<TrackingCategory>
					<Name>Activity/Workstream</Name>
					<Option>Publications</Option>
				</TrackingCategory>
			</Tracking>
		</LineItem>
	</LineItems>
</Invoice>

Using the PUT Invoice method – handling an OK response

The response should have a status of OK and also contain an InvoiceID. The InvoiceID is a GUID generated by Xero which cannot be altered and is generally hidden other than sometimes being visible in a URL. We recommend to store the InvoiceID in your system and query invoices using this identifier.

<Response xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
	<ID>dd3f5207-83a4-4e48-a220-9876d421ff41</ID>
	<Status>OK</Status>
	<ProviderName>XeroTest</ProviderName>
	<DateTimeUTC>2009-01-11T22:33:36.403875Z</DateTimeUTC>
	<Invoice>
		<InvoiceType>ACCREC</InvoiceType>
		<InvoiceID>9054cae0-97b8-49f0-864e-12558c2f7e8c</InvoiceID>
		<Contact>

3. Query GET Invoices periodically to see if invoices have been paid

https://networktest.xero.com/api.xro/1.0/Invoices

  • Apply a filter to this query to see just payments received since a timestamp
  • modifiedSince is an optional DateTime parameter to filter invoices by. If specified only invoices with an UpdatedDateUTC greater than the date time specified will be returned, assumed to be in Coordinated Universal Time
<Invoices>
<Invoice>
...................
     <Payments>
            <Payment>
                <Date>2008-10-01T00:00:00</Date>
                <Amount>5.0000</Amount>
            </Payment>
            <Payment>
                <Date>2008-10-29T00:00:00</Date>
                <Amount>411.0000</Amount>
            </Payment>
        </Payments>
  <FullyPaidOnDate>2008-10-29T00:00:00</FullyPaidOnDate>
  <AmountDue>0</AmountDue>
  <AmountPaid>426.0000</AmountPaid>
  <AmountCredited>10.000</AmountCredited>
</Invoice>
......
</Invoices>