The current implementation of Sage100 (C5+) uses gRPC calls to a satellite web service on the client's local Sage100 machine to integrate with Sage100.
Sage 100 Documentation Link Sage 100 Help & File Layouts (2022)
Prior versions (years):
Sage 100 does not have an open API endpoint, which means the connector must be hosted on the same network as Sage 100. The Sage 100 connector has been built to work as a separate software that can be installed on the same server as Sage 100. The Server Agent is very lightweight and creates an Open API that the rest of Clarity Connect is able to connect with over the internet. We will need approval from the client/vendor hosting Sage 100 to install the Server Agent. Once installed, the agent will need to have the ability to call out to Clarity Connect. Creating firewall rules and a site-to-site VPN are possible methods to provide that access. Further elaboration can be had with the help of a Connect team member.
4.7/developsupport/clients/care/dev/PushToProductionsupport/clients/gqm/feature/96808-AddsSalesOrderDeletesFunction{
"Sage100AgentOptions": {
"Path": "C:\\Sage 100\\v2018\\MAS90\\",
"Username": "User",
"Password": "p@$5",
"Company": "ABC",
"IsDebug": true
}
}
(ex. "C:\\Sage 100\\v2018\\MAS90\\")
(ex. "\\\\SageServer\\Sage\\MAS90").This Link contains refrences to some of these methods
Key Property
In the satellite create request you must include the GetKeyName
This is usually “nGet{keyname}”
In the integration service you must invoke the GetNextKey method followed by a SetKey method
Properties
STR, the property is in parentheses, and no ”$” after the property name1. Create the method that you need with a descriptive title in the job itself
[This is in the Connect Job]
Note: Ensure that the method does not already exist in the Sage100Service file
[This is in the Integration]
2. In Sage100Service create the method that will call the Sage100AgentService method that you will create next.
[This in the Integration Service]
Note: Follow the pattern of similar methods in the files. For example, if you need a create method, find another create method and follow its pattern.
3. In the Sage100AgentService (Place the method in the corresponding partial class) create your new method.
4. Following the pattern, create your new method that will Read, Create, or List the data that you need.
5. Use the list request object to create the appropriate object to pass to the list request. This same pattern is followed for all other methods as well. If you have a create request, it will be a new CreateRequest. The Module Name, Program Name, Business Object name and the Key Column can be found in the Sage 100 NFR on 10.100.70.2.
The Corresponding partial class should exist as most Entities are being used. If the partial class, for a new Entity does not exist, please create a new partial class.
Note: You may also use the search bar to search for the particular entity for which you need to create a request. This will give you the business object itself, its properties, and its methods.
6. Update the partial interface at the bottom of the partial class with the new method.
Note: Any parameters in the Sage100AgentService must be JSONWrapped due to the constraints of the satellite.
1. This is where your different connect jobs are created
a. Your jobs will call Sage 100 connector
public async Task<Customer[]> ListCustomers(
DateTime? compareDate,
DateTime? maxCompareDate,
CancellationToken token)
{
try
{
var response = await _service.ListCustomers(
compareDate,
maxCompareDate,
token).ConfigureAwait(false);
var retVal = ThrowIfFailedOrReturnResult(response);
return retVal;
}
catch (Exception ex)
{
var test = ex.Message;
throw;
}
}
1. This is an example of a service calling the Sage 100 Satellite
a. This is calling the satellite not the integrations service
b. The Primary difference that includes a “ThrowIfFailedOrReturnResult(response)” Method
public async Task<SatelliteResponse<Customer[]>> ListCustomers(
JSONWrapped<DateTime?> compareDate,
JSONWrapped<DateTime?> maxCompareDate,
JSONWrapped<CancellationToken> token)
{
try
{
ListRequestObject listRequestObject = new ListRequestObject
{
CompareDate = compareDate,
MaxDateToCompare = maxCompareDate,
ModuleName = "A/R",
ProgramName = "AR_Customer_ui",
BusObjName = "AR_Customer_bus",
KeyColumn = "ARDivisionNo$+CustomerNo$",
DescColumn = Customer.DefaultDesc,
DefaultDescColumn = Record.DefaultDesc,
Filter = "",
Begin = "",
End = "",
};
var request = new CustomerListRequest<Customer>(listRequestObject);
var result = await _service
.List<Customer, CustomerListRequest<Customer>>(request);
return SatelliteResponseExt.SuccessResponse(result);
}
catch (Exception ex)
{
return SatelliteResponseExt.FailedResponse<Customer[]>(ex.Message, ex);
throw;
}
}
If any object in the call is abstract you will not be able to cast to the Record

It can be from the entity or the mapping profile
(Rare) If the object you are using isn’t abstract you could be using the incorrect object with the same number of properties that will throw a casting error due to a type mismatch
The properties are mapped in an array are matched using the default descending
Default descending on the entity
This is the mapper profile of the entity
In the module name/program name/business object name, one of those is incorrect or some combination
Make sure they are correct in your request object
Phase 2