ml-connector
Sage 300Salesforce

Sage 300 and Salesforce integration

Sage 300 runs order-to-cash and procure-to-pay for mid-market businesses. Salesforce manages the sales pipeline and customer relationships. Connecting the two ensures that every vendor and customer in Sage 300 is visible in Salesforce, that GL entries from Sage 300 can be tracked against Salesforce opportunities and orders, and that new opportunities in Salesforce flow back into Sage 300 as orders. This eliminates duplicate data entry and keeps revenue recognition aligned across both systems.

How Sage 300 works

Sage 300 is an on-premise ERP hosted on Windows IIS with SQL Server. It exposes REST and OData APIs at a customer-specific URL, requiring HTTP Basic Authentication with uppercase username and password on every request. Key entities include APVendors, ARCustomers, GLAccounts, GLJournalBatches, POPurchaseOrders, and OEOrders. Sage 300 has no webhooks or push notifications, so all syncing is pull-based. The API user must be created in Administrative Services with Web API security group privileges, and IIS must be configured with Anonymous Authentication enabled. Polling uses OData filters and pagination to fetch records modified since the last sync.

How Salesforce works

Salesforce is a cloud CRM accessed via REST APIs and secured with OAuth2 Client Credentials Flow. It manages Accounts, Contacts, Opportunities, Orders, and custom objects. The system supports real-time change notifications through CDC and Pub/Sub API (gRPC streaming) with 3-day event retention, and also allows polling for updates within a datetime range. Session tokens expire after 2 hours and must be refreshed before each sync batch. Salesforce enforces rate limits per organization and license type, and custom objects can be created to hold Sage 300 GL entries, batch references, or order mappings.

What moves between them

The primary flow moves vendor and customer master data from Sage 300 into Salesforce Accounts and Contacts. GL journal entries from Sage 300 are synced into a custom Salesforce object so revenue and expense transactions are visible alongside opportunities. A secondary flow captures Salesforce opportunities and orders, mapping them back to Sage 300 OEOrders so the sales pipeline feeds the order entry system. Syncing occurs on a configurable schedule tied to business cycles (daily for GL, weekly for master data updates).

How ml-connector handles it

ml-connector stores HTTP Basic Auth credentials for Sage 300 encrypted and passes them with every request, using OData $filter parameters (DocumentDate gt datetime) and $skip/$top pagination to fetch only new or modified records since the last poll. For Salesforce, it exchanges OAuth2 client credentials for a bearer token, monitors token expiry, and refreshes before it expires. The integration maps Sage 300 APVendors and ARCustomers to Salesforce Account records, aligning on company name and tax ID. Sage 300 GL journal batches are inserted into a custom Salesforce object (SageGLEntry__c) with the journal batch number, GL account code, and amount, allowing the sales team to see financial impact of opportunities. Opportunities flow back as draft orders in Sage 300, with mapping rules ensuring the order goes to the correct customer and GL cost center. Since Sage 300 polling can be slow at scale, ml-connector caches master data (GL accounts, customer/vendor lookups) to avoid repeated identical queries, and batches GL journal inserts to Salesforce to stay within rate limits. Every synced record carries an audit trail, and failed inserts are logged so they can be retried or investigated.

A real-world example

A mid-sized wholesale distributor runs Sage 300 for inventory, AP, and AR, and Salesforce for sales team territory management and opportunity tracking. Before the integration, the sales team manually entered customer data from Sage 300 into Salesforce, and the finance team never saw the impact of open opportunities on cash flow forecasting. New GL posting dates to Sage 300 were invisible to sales, and order entry clerks had to re-key opportunity data from Salesforce into Sage 300 when the deal closed. With Sage 300 and Salesforce connected, the sales team sees all vendors and customers from Sage 300 in their CRM on day one, GL postings appear in a side panel so they can discuss financial impact with customers, and closed opportunities automatically become orders in Sage 300, with the customer, line items, and GL cost center pre-populated. Month-end close happens faster because the finance team can instantly reconcile Salesforce pipeline value against Sage 300 open orders.

What you can do

  • Sync Sage 300 vendors and customers into Salesforce Accounts, matching on company name and tax identifier.
  • Pull GL journal entries from Sage 300 into a custom Salesforce object so sales can see the financial impact of transactions.
  • Map Salesforce opportunities and orders back to Sage 300 OEOrders with correct customer and GL account assignment.
  • Handle HTTP Basic Auth for the on-premise Sage 300 instance and OAuth2 token refresh for Salesforce on every poll cycle.
  • Poll Sage 300 on a schedule, cache lookups to avoid repeated API calls, and batch Salesforce inserts to stay within rate limits.

Questions

How does ml-connector access Sage 300 if it runs on-premise behind a firewall?
ml-connector requires the Sage 300 IIS server to be reachable over HTTPS from your network or a dedicated outbound connection. The customer provides the full Sage 300 URL (e.g., https://sage300.customerdomain.com/Sage300WebApi/), and ml-connector presents HTTP Basic Auth credentials with every request. The API user must have Web API security group privileges in Sage 300's Administrative Services.
What happens when Salesforce OAuth tokens expire?
Salesforce OAuth2 tokens expire after 2 hours. ml-connector monitors token age and refreshes automatically before making the next API call by exchanging the client credentials again. If a call returns a 401 Unauthorized, ml-connector immediately refreshes and retries the operation, so token expiry never causes data loss.
How are Sage 300 GL entries and Salesforce opportunities kept synchronized?
ml-connector polls Sage 300 GLJournalBatches on a schedule (daily or as configured) and inserts new entries into a custom Salesforce object (SageGLEntry__c) with the batch ID, GL account code, and amount. The sales team can then view GL impact alongside their opportunities. Opportunities flow back to Sage 300 as draft orders, matched to the correct customer and cost center so order entry clerks can review and post them without re-keying.

Related integrations

Connect Sage 300 and Salesforce

Free to use. Add your credentials, ping your real systems, and see if we fit.

Get started