ERPNext Integration with Salesforce
Introduction:
ERPNext is the world’s top Open Source ERP solution rated by Gartner. This ERP solution can be self-hosted for processing products, invoicing, and other business processes. Businesses working on ERPNext can have their processes integrated with Salesforce using a custom-built two-way integration based on REST architecture. This blog discusses the basics of ERPNext Integration with Salesforce. Since Salesforce provides Salesforce1 and easy to configure Quotes OOB, hence Quotes from Salesforce can be pushed to ERPNext for processing invoices against the same in ERPNext.
Better way of connectivity:
If you try to self-host ERPNext, you will come to know that its build on top of Python programming language. It also provides proper documentation as well as authentication methods such that easy integrations can be built around ERPNext.
Salesforce Standard APIs can be consumed from ERPNext webhooks such that any changes in ERPNext are reflected to Salesforce in real-time or vice-versa using REST APIs
Getting started with the Two-way syncing
In order to achieve bi-directional syncing the steps mentioned below must be followed:
ERPNext to Salesforce
ERPNext calls their database records as Document and table names are categorised as to be DocType of the document. ERPNext support Webhooks wherein Apex Webservices can be requested to send the Document information to Salesforce. DocType in ERPNext provides the Model and View information for each specific type of Document stored in the form of JSON objects in ERPNext.
To process these documents in Salesforce, you will need to parse the document as per the DocType using Apex Wrapper Class for the specific DocType. You can refer for more details on DocType in ERPNext on below reference:
Understanding ERPNext Doctypes
For parsing the Document in Apex, an apex class needs to be exposed as Webservice. Webhooks available in ERPNext will consume the endpoint created for the web service.
If required, this can also be done using Salesforce standard APIs for creating or updating records in Salesforce by importing below Python Package for Salesforce:
Simple Salesforce – A python package
The code snippet mentioned below from same, shows how python can be used to authenticate with your Salesforce Org, to create records in Salesforce.
from simple_salesforce import Salesforce sf = Salesforce(username='myemail@example.com', password='password', security_token='token') //Creating a Contact record in Salesforce sf.Contact.create({'LastName':'Smith','Email':'example@example.com'}) //Calling an Apex REST API payload = { "activity": [ { "user": "12345", "action": "update page", "time": "2014-04-21T13:00:15Z"} ] } result = sf.apexecute('User/Activity', method='POST', data=payload)
In the above code snippet, you can send the ERPNext Document (JSON object) to salesforce as data while calling an Apex REST API.
Salesforce to ERPNext
ERPNext is flexible in terms of authentication, since it provides number of authentication methods which can be viewed over here:
Out of this Authentication methods, we will be discussing here Simple Authentication method using Named Credentials. This method of Authentication accepts Username and Password for authenticating the API consumer hence Simple Authentication. More details on Simple Authentication in ERPNext: ERPNExt Simple Authentication
If we want to integrate a particular Object/Document in two-way sync, we need to persist the External Id (Unique Id) of the Document in Salesforce, as well as the Salesforce record Id in the same Document on ERPNext site, thus keeping records intact. ERPNext Documents can be retrieved or updated using Name (ID) of the Document in ERPNext using their respective GET or PUT API. Creating new Documents in ERPNext, we can use the POST endpoints for that specific DocType.
Below reference includes proper documentation on how Documents can be manipulated in Salesforce using their APIs:
Manipulating ERPNext Documents using API
Example:
In order to Authenticate with ERPNext, we need to use the below endpoint and provide Username and Password using HTTP Post request.
POST https://{your frappe instance}/api/method/login
If we want to integrate a particular Object/Document in two-way sync, we need to persist the External Id (Unique Id) of the Document in To keep the username, password as well as endpoint in one place, we explored the Salesforce OOB Named Credentials feature which increases Manageability, Security and Usability of Credentials like this of other systems on your Salesforce Orgs.
This endpoint on Success returns you sid (Session Id) which we will be required to authenticate your further requests to ERPNext, by including the same sid received as a Cookie. This sid once generated, will remain* valid for three days* after which you can regenerate the same using above endpoint as and when required.
How to send a sample Request for login using Named Credentials ?
HTTP httpClient = new HTTP(); HTTPRequest request = new HTTPRequest(); HTTPResponse response = new HTTPResponse(); request.setMethod('GET'); request.setEndpoint('callout:ERPNEXT/api/method/login'); request.setBody('usr={!$Credential.Username}&pwd={!$Credential.Password}'); connectionResponse = httpClient.send(request);
NOTE:
The above code snippets shows how we can access the username and password stored in Named Credentials inside an API callout request without doing much in the code. These are called the Merge fields from Named Credentials which can be used in Apex Callouts.
For more details on Merge fields in Named Credentials refer the following links:
Salesforce Merge Fields for named credentials
Now, how to send sample request for creating a record using Named Credentials ?
HTTP httpClient = new HTTP(); HTTPRequest request = new HTTPRequest(); HTTPResponse response = new HTTPResponse(); request.setBody(data); //Data here should be JSON serialized data as ERPNext doctype definition, here based on below endpoint it should follow Quotation DocType request.setMethod('POST'); request.setEndpoint('callout:ERPNEXT/api/resource/Quotation/'); request.setHeader('Cookie', connectionResponse.getHeader('Set-Cookie')); //Sid received from above login request should be used over here. request.setHeader('Authorization', 'Base '+ '{!$Credential.AuthorizationHeaderValue}'); //We are using Named Credential merge field instead of generating it ourselves. request.setHeader('Content-Type','application/json'); response = httpClient.send(request);
Conclusion:
You can create REST architecture based complex integrations between ERPNext and Salesforce with help of Webhooks in ERPNext and Apex REST callouts using Simple Authentication.
As a best practice, it is always recommended to use the Named Credentials in Salesforce which makes maintaining the external system credentials more easily manageable, usable and secured.