Salesforce to Xero Integration via Apex

[dipi_table_of_content heading_tags=”off|on|on|on|on|on” _builder_version=”4.23″ _module_preset=”default” global_colors_info=”{}”][/dipi_table_of_content]

Overview of Integration

If you are using Salesforce and Xero for your business, you may want to integrate these two systems. Integrating Salesforce with Xero will allow you to easily create or read Xero Customers and Invoices. While pre-built Xero Salesforce Integration may not be sufficient for your business needs, you can write custom Apex and develop your own solution. In this post, you will learn how to do it!

To integrate Xero with Salesforce, you’ll need admin access to Xero and admin access to Salesforce (Enterprise Edition or higher, or a Dev/Sandbox org for testing). You’ll also need some experience with Apex code. If you lack experience with Apex, you may want to consider using a no-code integration with Zapier or use Breadwinner’s no-code integration between Salesforce and Xero.

Remote Site Settings

To make a callout to an external website from Salesforce, it is crucial to register the target site in the Remote Site Settings. If the site is not registered, the callout will fail because Salesforce restricts calls to unregistered network addresses.

Before calling Xero Endpoints, we need to create two remote site settings in Salesforce. Follow these steps to create them:

  1. Go to Setup.
  2. In the Quick Find search bar, enter “Remote Site.”
  3. Click on “Remote Site Settings.”
  4. Create the following two remote site settings, each serving a specific purpose.
    1. For authentication and obtaining the Access Token, use:
      URL: https://identity.xero.com/
    2. For performing operations on data, such as Contacts, Invoices, Bills, or Purchase Orders, use:
      URL: https://api.xero.com/

Create Remote Site Settings

 

Connecting to Xero using OAuth 2.0 Custom Connection

To create a Custom Connection App on Xero, navigate to “https://developer.xero.com,” then go to the “My Apps” section and provide all the necessary details. Once you have completed the application configuration, you can obtain your unique Client ID and Client Secret. Please note that your Client ID and Secret will look different from the examples given.

Client ID: 8459AA********************5C8E0
Client Secret: 3hZBw*********************************895nPi

Create Xero Custom Connection

You can use the above-generated codes to obtain the Access Token by requesting the endpoint “https://identity.xero.com/connect/token.”

Please see the sample code provided below.

[et_pb_dmb_code_snippet code=”cHVibGljIGNsYXNzIFhlcm9BdXRoIHsKICAgIHB1YmxpYyBzdGF0aWMgc3RyaW5nIGdldEFjY2Vzc1Rva2VuKCl7CiAgICAgICAgU3RyaW5nIGNsaWVudElkID0gJzg0NTlBQUI4NEVBQjQ0RDk5MjBDNTUxMjkzMjVDOEUwJzsKICAgICAgICBTdHJpbmcgY2xpZW50U2VjcmV0ID0gJzNoWkJ3VW9qWDY3SUpSSktjZEpueXoxTjR3VV8tQTRGUUV3b2I4cFZnWTg5NW5QaSc7CiAgICAgICAgQmxvYiBoZWFkZXJWYWx1ZSA9IEJsb2IudmFsdWVPZihjbGllbnRJZCArICc6JyArIGNsaWVudFNlY3JldCk7CiAgICAgICAgU3RyaW5nIGF1dGhvcml6YXRpb25IZWFkZXIgPSAnQmFzaWMgJyArIEVuY29kaW5nVXRpbC5iYXNlNjRFbmNvZGUoaGVhZGVyVmFsdWUpOwogICAgICAgIFN0cmluZyBwYXlsb2FkID0gJ2dyYW50X3R5cGU9Y2xpZW50X2NyZWRlbnRpYWxzJnNjb3BlPWFjY291bnRpbmcudHJhbnNhY3Rpb25zIGFjY291bnRpbmcuY29udGFjdHMnOwoKICAgICAgICBIdHRwUmVxdWVzdCByZXEgPSBuZXcgSHR0cFJlcXVlc3QoKTsKICAgICAJcmVxLnNldEVuZHBvaW50KCdodHRwczovL2lkZW50aXR5Lnhlcm8uY29tL2Nvbm5lY3QvdG9rZW4nKTsKICAgICAJcmVxLnNldE1ldGhvZCgnUE9TVCcpOwogICAgICAgIHJlcS5zZXRIZWFkZXIoJ0F1dGhvcml6YXRpb24nLCBhdXRob3JpemF0aW9uSGVhZGVyKTsKICAgICAgICByZXEuc2V0SGVhZGVyKCdDb250ZW50LVR5cGUnLCAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyk7CiAgICAgICAgcmVxLnNldEJvZHkocGF5bG9hZCk7CiAgICAgICAgCiAgICAgICAgSHR0cCBodHRwID0gbmV3IEh0dHAoKTsKICAgICAJSFRUUFJlc3BvbnNlIHJlcyA9IGh0dHAuc2VuZChyZXEpOwogICAgICAgIAogICAgICAgIGlmKHJlcy5nZXRTdGF0dXNDb2RlKCkgIT0gMjAwICYmIHJlcy5nZXRCb2R5KCkgIT0gTlVMTCl7CiAgICAgICAgICAgIFN0cmluZyByZXNwQm9keSA9IHJlcy5nZXRCb2R5KCk7ICAgICAgICAKICAgICAgICAJTWFwPFN0cmluZywgT2JqZWN0PiByZXNwTWFwID0gKE1hcDxTdHJpbmcsIE9iamVjdD4pSlNPTi5kZXNlcmlhbGl6ZVVudHlwZWQocmVzcEJvZHkpOyAKCQlpZihyZXNwTWFwLmNvbnRhaW5zS2V5KCdhY2Nlc3NfdG9rZW4nKSkKICAgICAgICAgICAgCXJldHVybiBTdHJpbmcudmFsdWVPZihyZXNwTWFwLmdldCgnYWNjZXNzX3Rva2VuJykpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAKICAgIH0KfQ==” admin_label=”Code Snippet – Xero OAuth 2.0 Custom Connection” linenums=”on” line_wrap=”on” copy_button=”on” _builder_version=”4.23″ _module_preset=”default” global_colors_info=”{}”][/et_pb_dmb_code_snippet]

Use the Access Token generated (which is valid for 1800 seconds) from the above class for any further requests.

Xero Contacts

Reading Contacts

Use the following code to retrieve Xero Contact(s) information from Xero. You can also access individual Xero Contact information by specifying the “IDs” parameter within the endpoint.

[et_pb_dmb_code_snippet code=”cHVibGljIGNsYXNzIFhlcm9Db250YWN0IHsKCXB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGFwaUVuZHBvaW50ID0gJ2h0dHBzOi8vYXBpLnhlcm8uY29tL2FwaS54cm8vMi4wLyc7CiAgICAKICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEFsbFhlcm9Db250YWN0cygpewogICAgICAgIFN0cmluZyBhY2Nlc3NUb2tlbiA9IFhlcm9BdXRoLmdldEFjY2Vzc1Rva2VuKCk7CiAgICAgICAgc3lzdGVtLmRlYnVnKGFjY2Vzc1Rva2VuKTsKICAgICAgICAKICAgICAgICBpZihhY2Nlc3NUb2tlbiAhPSBOVUxMKXsKICAgICAgICAgICAgSHR0cFJlcXVlc3QgcmVxID0gbmV3IEh0dHBSZXF1ZXN0KCk7CiAgICAgICAgICAgIHJlcS5zZXRFbmRwb2ludChhcGlFbmRwb2ludCsnQ29udGFjdHMnKTsKICAgICAgICAgICAgcmVxLnNldE1ldGhvZCgnR0VUJyk7CiAgICAgICAgICAgIHJlcS5zZXRIZWFkZXIoJ0F1dGhvcml6YXRpb24nLCAnQmVhcmVyICcrYWNjZXNzVG9rZW4pOwogICAgICAgICAgICBzeXN0ZW0uZGVidWcocmVxKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIEh0dHAgaHR0cCA9IG5ldyBIdHRwKCk7CiAgICAgICAgICAgIEhUVFBSZXNwb25zZSByZXMgPSBodHRwLnNlbmQocmVxKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmKHJlcy5nZXRTdGF0dXNDb2RlKCkgPT0gMjAwICYmIHJlcy5nZXRCb2R5KCkgIT0gTlVMTCl7CiAgICAgICAgICAgICAgICBTdHJpbmcgY29udGFjdHNKU09OUmVzcG9uc2UgPSByZXMuZ2V0Qm9keSgpOwogICAgICAgICAgICAgICAgc3lzdGVtLmRlYnVnKGNvbnRhY3RzSlNPTlJlc3BvbnNlKTsKICAgICAgICAgICAgICAgIHJldHVybiBjb250YWN0c0pTT05SZXNwb25zZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbCA7CiAgICB9Cn0=” admin_label=”Read Contacts Code Snippet” linenums=”on” line_wrap=”on” copy_button=”on” _builder_version=”4.23″ _module_preset=”default” global_colors_info=”{}”][/et_pb_dmb_code_snippet]

You can retrieve individual Xero contacts with the provided code by including the “IDs” parameter, as shown in the following endpoint.

https://api.xero.com/api.xro/2.0/Contacts?IDs=220ddca8-3144-4085-9a88-2d72c5133734,88192a99-cbc5-4a66-bf1a-2f9fea2d36d0

Managing Xero Contacts – Creation and Update

When creating a Xero Contact, certain mandatory fields should be provided as per the Xero API regulations. On the other hand, when updating a Xero Contact, it is crucial to include the “ContactID” in the request body.

The code below can be used for both creating and updating a Xero Contact based on the value of the “isCreate” parameter.
If the “isCreate” parameter is set to TRUE, then the request method will be configured as PUT, otherwise, it will be configured as POST.

[et_pb_dmb_code_snippet code=”cHVibGljIGNsYXNzIFhlcm9Db250YWN0IHsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGFwaUVuZHBvaW50ID0gJ2h0dHBzOi8vYXBpLnhlcm8uY29tL2FwaS54cm8vMi4wLyc7CiAgICAgICAgCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBjcmVhdGVVcGRhdGVYZXJvQ29udGFjdChCb29sZWFuIGlzQ3JlYXRlKXsKICAgICAgICBTdHJpbmcgYWNjZXNzVG9rZW4gPSBYZXJvQXV0aC5nZXRBY2Nlc3NUb2tlbigpOwogICAgICAgIHN5c3RlbS5kZWJ1ZyhhY2Nlc3NUb2tlbik7CgoJCWlmKGFjY2Vzc1Rva2VuICE9IE5VTEwpewoJCQlTdHJpbmcganNvbkJvZHkgPSAneyAiQ29udGFjdHMiOiBbIHsgIk5hbWUiOiAiQnJ1Y2UgQmFubmVyIiwgIkVtYWlsQWRkcmVzcyI6ICJodWxrQGF2ZW5nZXJzLmNvbSIsICJQaG9uZXMiOiBbIHsgIlBob25lVHlwZSI6ICJNT0JJTEUiLCAiUGhvbmVOdW1iZXIiOiAiNTU1LTEyMTIiLCAiUGhvbmVBcmVhQ29kZSI6ICI0MTUiIH0gXSwgIlBheW1lbnRUZXJtcyI6IHsgIkJpbGxzIjogeyAiRGF5IjogMTUsICJUeXBlIjogIk9GQ1VSUkVOVE1PTlRIIiB9LCAiU2FsZXMiOiB7ICJEYXkiOiAxMCwgIlR5cGUiOiAiREFZU0FGVEVSQklMTE1PTlRIIiB9IH0gfSBdIH0nOwoKICAgICAgICAgICAgSHR0cFJlcXVlc3QgcmVxID0gbmV3IEh0dHBSZXF1ZXN0KCk7CiAgICAgICAgICAgIHJlcS5zZXRFbmRwb2ludChhcGlFbmRwb2ludCsnQ29udGFjdHMnKTsKICAgICAgICAgICAgcmVxLnNldE1ldGhvZChpc0NyZWF0ZSA/ICdQVVQnIDogJ1BPU1QnKTsKICAgICAgICAgICAgcmVxLnNldEhlYWRlcignQXV0aG9yaXphdGlvbicsICdCZWFyZXIgJythY2Nlc3NUb2tlbik7CiAgICAgICAgICAgIHJlcS5zZXRIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi9qc29uJyk7CiAgICAgICAgICAgIHJlcS5zZXRIZWFkZXIoJ0FjY2VwdCcsICdhcHBsaWNhdGlvbi9qc29uJyk7CiAgICAgICAgICAgIHJlcS5zZXRCb2R5KGpzb25Cb2R5KTsKICAgICAgICAgICAgc3lzdGVtLmRlYnVnKHJlcSk7CiAgICAgICAgICAgIAogICAgICAgICAgICBIdHRwIGh0dHAgPSBuZXcgSHR0cCgpOwogICAgICAgICAgICBIVFRQUmVzcG9uc2UgcmVzID0gaHR0cC5zZW5kKHJlcSk7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZihyZXMuZ2V0U3RhdHVzQ29kZSgpID09IDIwMCAmJiByZXMuZ2V0Qm9keSgpICE9IE5VTEwpewogICAgICAgICAgICAgICAgU3RyaW5nIGNvbnRhY3RKU09OUmVzcG9uc2UgPSByZXMuZ2V0Qm9keSgpOwogICAgICAgICAgICAgICAgc3lzdGVtLmRlYnVnKGNvbnRhY3RKU09OUmVzcG9uc2UpOwogICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRhY3RKU09OUmVzcG9uc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGwgOwogICAgfQp9″ admin_label=”Manage Contacts Code Snippet” linenums=”on” line_wrap=”on” copy_button=”on” _builder_version=”4.23″ _module_preset=”default” global_colors_info=”{}”][/et_pb_dmb_code_snippet]

Xero Invoices

Reading Invoices

Use the following code to retrieve Xero Invoice(s) information from Xero. You can also access individual Xero Invoice information by specifying the “IDs” parameter within the endpoint.

[et_pb_dmb_code_snippet code=”cHVibGljIGNsYXNzIFhlcm9JbnZvaWNlIHsKCXB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGFwaUVuZHBvaW50ID0gJ2h0dHBzOi8vYXBpLnhlcm8uY29tL2FwaS54cm8vMi4wLyc7CiAgICAKICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEFsbFhlcm9JbnZvaWNlcygpewogICAgICAgIFN0cmluZyBhY2Nlc3NUb2tlbiA9IFhlcm9BdXRoLmdldEFjY2Vzc1Rva2VuKCk7CiAgICAgICAgc3lzdGVtLmRlYnVnKGFjY2Vzc1Rva2VuKTsKICAgICAgICAKICAgICAgICBpZihhY2Nlc3NUb2tlbiAhPSBOVUxMKXsKICAgICAgICAgICAgSHR0cFJlcXVlc3QgcmVxID0gbmV3IEh0dHBSZXF1ZXN0KCk7CiAgICAgICAgICAgIHJlcS5zZXRFbmRwb2ludChhcGlFbmRwb2ludCsnSW52b2ljZXMnKTsKICAgICAgICAgICAgcmVxLnNldE1ldGhvZCgnR0VUJyk7CiAgICAgICAgICAgIHJlcS5zZXRIZWFkZXIoJ0F1dGhvcml6YXRpb24nLCAnQmVhcmVyICcrYWNjZXNzVG9rZW4pOwogICAgICAgICAgICBzeXN0ZW0uZGVidWcocmVxKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIEh0dHAgaHR0cCA9IG5ldyBIdHRwKCk7CiAgICAgICAgICAgIEhUVFBSZXNwb25zZSByZXMgPSBodHRwLnNlbmQocmVxKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmKHJlcy5nZXRTdGF0dXNDb2RlKCkgPT0gMjAwICYmIHJlcy5nZXRCb2R5KCkgIT0gTlVMTCl7CiAgICAgICAgICAgICAgICBTdHJpbmcgaW52b2ljZXNKU09OUmVzcG9uc2UgPSByZXMuZ2V0Qm9keSgpOwogICAgICAgICAgICAgICAgc3lzdGVtLmRlYnVnKGludm9pY2VzSlNPTlJlc3BvbnNlKTsKICAgICAgICAgICAgICAgIHJldHVybiBpbnZvaWNlc0pTT05SZXNwb25zZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KfQ==” admin_label=”Read Invoices Code Snippet” linenums=”on” line_wrap=”on” copy_button=”on” _builder_version=”4.23″ _module_preset=”default” global_colors_info=”{}”][/et_pb_dmb_code_snippet]

You can retrieve individual Xero Invoices with the provided code by including the “IDs” parameter, as shown in the following endpoint.

https://api.xero.com/api.xro/2.0/Invoices?IDs=fee88eea-f2aa-4a71-a372-33d6d83d3c45,9f5bca33-8590-4b6f-acfb-e85712b10217

Managing Xero Invoices – Creation and Update

When creating a Xero Invoice, certain mandatory fields should be provided as per the Xero API regulations. On the other hand, when updating a Xero Invoice, it is crucial to include the “InvoiceID” in the request body.

The code below can be used for both creating and updating a Xero Invoice based on the value of the “isCreate” parameter.
If the “isCreate” parameter is set to TRUE, then the request method will be configured as PUT, otherwise, it will be configured as POST.

[et_pb_dmb_code_snippet code=”cHVibGljIGNsYXNzIFhlcm9JbnZvaWNlIHsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIGFwaUVuZHBvaW50ID0gJ2h0dHBzOi8vYXBpLnhlcm8uY29tL2FwaS54cm8vMi4wLyc7CiAgICAgICAgCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBjcmVhdGVVcGRhdGVYZXJvSW52b2ljZShCb29sZWFuIGlzQ3JlYXRlKXsKICAgICAgICBTdHJpbmcgYWNjZXNzVG9rZW4gPSBYZXJvQXV0aC5nZXRBY2Nlc3NUb2tlbigpOwogICAgICAgIHN5c3RlbS5kZWJ1ZyhhY2Nlc3NUb2tlbik7CgoJCWlmKGFjY2Vzc1Rva2VuICE9IE5VTEwpewoJCQlTdHJpbmcganNvbkJvZHkgPSAneyAiSW52b2ljZXMiOiBbIHsgIlR5cGUiOiAiQUNDUkVDIiwgIkNvbnRhY3QiOiB7ICJDb250YWN0SUQiOiAiNDMwZmExNGEtZjk0NS00NGQzLTlmOTctNWRmNWUyODQ0MWI4IiB9LCAiTGluZUl0ZW1zIjogWyB7ICJEZXNjcmlwdGlvbiI6ICJBY21lIFRpcmVzIiwgIlF1YW50aXR5IjogMiwgIlVuaXRBbW91bnQiOiAyMCwgIkFjY291bnRDb2RlIjogIjIwMCIsICJUYXhUeXBlIjogIk5PTkUiLCAiTGluZUFtb3VudCI6IDQwIH0gXSwgIkRhdGUiOiAiMjAxOS0wMy0xMSIsICJEdWVEYXRlIjogIjIwMTgtMTItMTAiLCAiUmVmZXJlbmNlIjogIldlYnNpdGUgRGVzaWduIiwgIlN0YXR1cyI6ICJBVVRIT1JJU0VEIiB9IF0gfSc7CgogICAgICAgICAgICBIdHRwUmVxdWVzdCByZXEgPSBuZXcgSHR0cFJlcXVlc3QoKTsKICAgICAgICAgICAgcmVxLnNldEVuZHBvaW50KGFwaUVuZHBvaW50KydJbnZvaWNlcycpOwogICAgICAgICAgICByZXEuc2V0TWV0aG9kKGlzQ3JlYXRlID8gJ1BVVCcgOiAnUE9TVCcpOwogICAgICAgICAgICByZXEuc2V0SGVhZGVyKCdBdXRob3JpemF0aW9uJywgJ0JlYXJlciAnK2FjY2Vzc1Rva2VuKTsKICAgICAgICAgICAgcmVxLnNldEhlYWRlcignQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKTsKICAgICAgICAgICAgcmVxLnNldEhlYWRlcignQWNjZXB0JywgJ2FwcGxpY2F0aW9uL2pzb24nKTsKICAgICAgICAgICAgcmVxLnNldEJvZHkoanNvbkJvZHkpOwogICAgICAgICAgICBzeXN0ZW0uZGVidWcocmVxKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIEh0dHAgaHR0cCA9IG5ldyBIdHRwKCk7CiAgICAgICAgICAgIEhUVFBSZXNwb25zZSByZXMgPSBodHRwLnNlbmQocmVxKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmKHJlcy5nZXRTdGF0dXNDb2RlKCkgPT0gMjAwICYmIHJlcy5nZXRCb2R5KCkgIT0gTlVMTCl7CiAgICAgICAgICAgICAgICBTdHJpbmcgaW52b2ljZUpTT05SZXNwb25zZSA9IHJlcy5nZXRCb2R5KCk7CiAgICAgICAgICAgICAgICBzeXN0ZW0uZGVidWcoaW52b2ljZUpTT05SZXNwb25zZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gaW52b2ljZUpTT05SZXNwb25zZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbCA7CiAgICB9Cn0=” admin_label=”Manage Invoices Code Snippet” linenums=”on” line_wrap=”on” copy_button=”on” _builder_version=”4.23″ _module_preset=”default” global_colors_info=”{}”][/et_pb_dmb_code_snippet]

Alternatives to a Custom Integration

If you find it challenging to write a custom integration with Apex because it lacks LWC components or cannot handle updates, race conditions, or other unusual issues, then consider using Breadwinner’s Xero Salesforce Integration. It has clearly defined costs and can help your business grow and scale quickly.

Alternatively, you can also integrate Salesforce and Xero by using Zapier or Workato.