Salesforce ERP integration connects customer-facing CRM processes with finance, inventory, order management, procurement, manufacturing, and fulfillment data held in an enterprise resource planning system. A sound design defines which system owns each field, selects an integration pattern for each business transaction, protects credentials, and makes retries safe before any API work begins.
This guide explains how to plan, build, secure, test, and operate the integration. It focuses on decisions that affect production orgs: transaction boundaries, API selection, external IDs, middleware, event delivery, governor limits, data reconciliation, and support ownership.
What Is Salesforce ERP Integration?
Salesforce ERP integration is an exchange of data or business actions between Salesforce and an ERP platform. Typical flows include customer master synchronization, product and price updates, quote-to-order submission, order-status updates, invoice visibility, payment status, inventory availability, and shipment tracking.
The integration should not treat every field as bidirectional. In enterprise orgs, a field-level ownership matrix prevents update loops and conflicting values. For example, Salesforce may own lead, opportunity, and selling-contact data, while the ERP owns legal customer numbers, credit status, inventory, invoices, and fulfillment status.
| Business data | Typical system of record | Common direction | Recommended key |
|---|---|---|---|
| Prospect and opportunity | Salesforce | Salesforce to ERP after qualification or order approval | Salesforce record ID plus ERP external ID |
| Customer account | Depends on governance | Controlled two-way synchronization | ERP customer number stored in an External ID field |
| Product, inventory, and price | ERP | ERP to Salesforce | SKU or product code |
| Sales order and invoice | ERP | Salesforce request, ERP response | Client request ID and ERP document number |
| Shipment status | ERP or logistics system | ERP to Salesforce or virtual access | Order number and shipment number |

How Do You Choose a Salesforce ERP Integration Pattern?
Choose a pattern per use case rather than one pattern for the whole program. Salesforce Architects publishes a Data Integration Decision Guide that compares data movement and access options. The main architectural choices are request-reply, fire-and-forget messaging, batch synchronization, event-driven updates, and data virtualization.
Synchronous request and reply
Use a synchronous call when a user or process needs an immediate answer, such as a credit check, tax calculation, or current stock lookup. Keep the operation short. A slow ERP response can consume Apex callout time and leave the user waiting. Do not use a synchronous chain for long-running order creation with several downstream systems.
Asynchronous process integration
Use an asynchronous pattern when Salesforce can submit work and receive the result later. A common design creates an integration request record, sends a message, and updates the originating opportunity or order after the ERP confirms processing. This pattern isolates the Salesforce transaction from ERP latency and supports controlled retries.
Event-driven updates
Platform Events and Pub/Sub API fit business notifications such as “order accepted,” “invoice posted,” or “shipment dispatched.” Salesforce documents Platform Events as event messages published by one process and received by subscribers. Review event allocations, replay behavior, ordering needs, and duplicate handling before using events as a transaction ledger. See the official Platform Events Developer Guide.
Batch data synchronization
Use Bulk API 2.0 for large scheduled loads such as product catalogs, price books, customer updates, or historical order summaries. Bulk API 2.0 supports large ingest jobs and bulk queries. Upsert requires an external ID field, which lets repeated files update the same records rather than create duplicates.
Virtual access with Salesforce Connect
Use Salesforce Connect when users need to view selected ERP data without copying all of it into Salesforce. External objects map to data stored outside Salesforce. This pattern reduces replication but makes page performance and availability dependent on the external source and adapter. Trailhead provides a practical Salesforce Connect quick start.
Salesforce Integration Best Practices for ERP Projects
Salesforce integration best practices for system ownership
Document ownership at object and field level. “Account is shared” is not precise enough. State which system can create the record, which system assigns the legal customer number, which system can change payment terms, and how conflicts are resolved. Reject or route unauthorized updates instead of silently accepting the latest timestamp.
Use stable external IDs and idempotent operations
Store the ERP key in a Salesforce field marked External ID, and make it unique where the business rule permits. Use upsert for repeatable master-data loads. For business transactions, send a client-generated request key such as SFDC-{OpportunityId}-{version}. The ERP or middleware should return the prior result when the same key is received again.
Idempotency matters because network timeouts are ambiguous. Salesforce may not know whether the ERP committed the order before the connection failed. Retrying without a request key can create duplicate orders.
Separate transport status from business status
An HTTP 200 response only confirms that the endpoint handled the request. It does not always mean the ERP accepted the business transaction. Store both statuses:
- Transport status: queued, sent, timed out, authentication failed, or unavailable.
- Business status: accepted, rejected for credit, invalid product, duplicate request, or pending review.
Design for limits and back pressure
Do not start one Apex transaction per ERP row during a large load. Use Bulk API, middleware batching, Queueable Apex, or Batch Apex based on volume and latency requirements. Limit concurrency so Salesforce does not overwhelm the ERP and the ERP does not exhaust Salesforce API capacity. Review the limits page for the APIs and event products selected for the design.
Keep mapping and routing configurable
Store non-secret mappings, feature switches, endpoint routing labels, and business defaults in Custom Metadata Types when deployment across environments is required. Keep passwords, client secrets, tokens, and private keys in the authentication mechanism, not in Custom Metadata, Custom Settings, Apex, or Flow text fields.
Apply SFDC best practices to observability
Useful SFDC best practices include a correlation ID on every request, structured logs, a durable retry queue, an error category, the source record ID, and the external document number. Support teams should be able to answer: what was sent, when it was sent, which endpoint received it, what came back, how many retries occurred, and whether a human must intervene.

When Should You Use Salesforce Middleware?
Salesforce middleware for orchestration and transformation
Salesforce middleware is useful when the integration spans several systems, requires protocol conversion, performs complex transformation, controls message sequencing, or needs centralized monitoring. It can also protect the ERP from traffic spikes by buffering requests and applying rate limits.
A point-to-point connection can be acceptable for one stable endpoint with a small payload and clear ownership. Reconsider it when a second consumer appears, mappings become release-dependent, credentials multiply, or the same business transaction must update several platforms.
| Decision factor | Direct integration may fit | Middleware is usually safer |
|---|---|---|
| Systems involved | One Salesforce org and one ERP endpoint | Several ERPs, data stores, commerce, tax, or logistics systems |
| Transformation | Small field mapping | Canonical models, enrichment, aggregation, or format conversion |
| Process duration | Short request-reply | Long-running orchestration with callbacks |
| Operations | Basic endpoint logs are sufficient | Central replay, dead-letter handling, alerting, and tracing are required |
| Traffic control | Low and predictable volume | Bursts, throttling, prioritization, or back pressure are required |
How partners and applications integrate with Salesforce
External applications that integrate with Salesforce normally authenticate through OAuth and call a supported Salesforce API. Use a connected app or external client app configuration appropriate to the org and authentication model. Grant only required scopes and permissions. Use a dedicated integration identity where the process represents a system rather than an individual user.
Which Salesforce APIs Fit ERP Integration?
| API or feature | Use it for | Watch for |
|---|---|---|
| REST API | Record operations and request-reply integrations | API limits, payload size, composite transaction semantics, and retries |
| Composite resources | Reducing round trips for related operations | Reference handling and all-or-none behavior differ by resource |
| Bulk API 2.0 | Large ingest and query workloads | Asynchronous job monitoring, failed-row files, and external IDs for upsert |
| Pub/Sub API and Platform Events | Event publication and subscription | Replay, retention, duplicate delivery, allocations, and consumer recovery |
| Salesforce Connect | Access to external data without full replication | Adapter support, external latency, feature compatibility, and licensing |
| Apex callouts | Salesforce-initiated calls to ERP services | Governor limits, transaction boundaries, timeout handling, and test mocks |
How to Secure Salesforce ERP Integration
Use Named Credentials and External Credentials for Salesforce-initiated callouts. A named credential defines the endpoint, while the external credential defines the authentication protocol and principals. Salesforce then manages authentication for Apex callouts that use the named credential endpoint. Review the official Named Credentials developer guide.
- Assign the external credential principal through permission sets.
- Use least-privilege Salesforce permissions and ERP service-account permissions.
- Keep secrets outside Apex and source control.
- Encrypt transport with HTTPS and validate certificates.
- Restrict inbound clients by OAuth policy, scope, user permissions, and network controls where required.
- Enforce object and field permissions for Apex that exposes data to users. Integration-mode system code still needs an explicit security design.
- Mask personal or financial fields in logs and error payloads.
Apex callout example with a Named Credential
The following service sends a small order request to an endpoint configured as the Named Credential ERP_API. The class performs one callout per invocation, checks the response, and avoids storing credentials in code.
public with sharing class ErpOrderService {
public class OrderRequest {
public String requestId;
public String accountExternalId;
public Decimal amount;
}
public class OrderResponse {
public String erpOrderNumber;
public String status;
public String message;
}
public class ErpIntegrationException extends Exception {}
public static OrderResponse submitOrder(OrderRequest payload) {
if (payload == null || String.isBlank(payload.requestId)) {
throw new IllegalArgumentException('requestId is required.');
}
HttpRequest request = new HttpRequest();
request.setEndpoint('callout:ERP_API/v1/orders');
request.setMethod('POST');
request.setHeader('Content-Type', 'application/json');
request.setHeader('Idempotency-Key', payload.requestId);
request.setTimeout(20000);
request.setBody(JSON.serialize(payload));
HttpResponse response = new Http().send(request);
Integer statusCode = response.getStatusCode();
if (statusCode == 200 || statusCode == 201 || statusCode == 202) {
return (OrderResponse) JSON.deserialize(
response.getBody(),
OrderResponse.class
);
}
throw new ErpIntegrationException(
'ERP request failed. HTTP status: ' + statusCode
);
}
}
Governor-limit note: do not call this method inside a loop that processes many records. Collect work and use an asynchronous, bulk-aware design. Unit tests must use HttpCalloutMock; tests cannot depend on a live ERP endpoint.
How to Build a Reliable Order-to-ERP Flow
- Define the trigger. Example: an opportunity reaches Closed Won and passes an approval check.
- Create a request record. Store the source ID, request key, payload version, attempt count, and status.
- Commit before the call where needed. Avoid coupling a long external operation to an interactive save transaction.
- Queue the request. Use Queueable Apex, a platform event, or middleware according to the architecture.
- Validate in middleware or ERP. Check customer key, products, currency, quantities, tax inputs, and duplicate request key.
- Return an acknowledgment. Distinguish accepted-for-processing from completed.
- Update Salesforce. Store the ERP order number and business status using a correlation key.
- Retry transient failures. Use bounded retries with increasing delay. Do not retry permanent validation errors automatically.
- Reconcile. Compare accepted requests with ERP orders on a schedule so missed callbacks are detected.

Common Errors in Salesforce ERP Integration
| Problem | Likely cause | Correction |
|---|---|---|
| Duplicate customers or orders | Insert-only logic or retry without idempotency | Use unique external IDs, upsert, and request keys |
| Updates overwrite correct data | No field ownership rules | Define authority by field and reject unauthorized changes |
| Callout timeout | Slow synchronous ERP process | Move to asynchronous submission and callback or polling |
| Authentication works for admins only | External credential principal not assigned | Assign the required permission set and test as the integration user |
| Bulk load partly succeeds | Row validation failures | Read the failed-results file, correct only failed rows, and resubmit safely |
| Event consumer misses updates | Replay position or recovery not implemented | Persist replay state and run reconciliation |
| Users see stale ERP status | Sync interval does not match business need | Set a freshness requirement and choose event, polling, or virtual access accordingly |
How to Test and Deploy the Integration
Test at four levels: unit, contract, integration, and business acceptance. Apex tests must mock callouts and cover success, timeout, malformed response, authentication failure, duplicate request, and permanent rejection. Salesforce requires at least 75% Apex code coverage for deployment, but coverage alone does not prove integration behavior.
- Contract tests: verify required fields, data types, enumerations, version headers, and error formats.
- Volume tests: use realistic batch sizes and concurrent users without exposing production data.
- Resilience tests: simulate timeouts, duplicate events, delayed callbacks, partial ERP outages, and expired credentials.
- Security tests: verify OAuth scope, permission-set assignment, CRUD/FLS behavior, log masking, and user access.
- Deployment checks: confirm endpoint aliases, Named Credentials, external credential principals, certificates, custom metadata, event subscribers, schedules, and alerts in each environment.
Production Checklist for Teams That Integrate with Salesforce
- Every shared field has a named owner.
- Every message has a correlation ID and schema version.
- Every create operation is idempotent or protected by a unique key.
- Transient and permanent errors follow different handling paths.
- Retries are bounded and visible to operators.
- Credentials are stored in supported credential features.
- Bulk loads capture failed-row results.
- Event consumers support replay and duplicate detection.
- Dashboards show latency, success rate, backlog, retry count, and unresolved errors.
- A reconciliation job detects records that callbacks or events missed.
- Runbooks identify owners for Salesforce, middleware, ERP, identity, and networking.
Related SalesforceTutorial resources include Salesforce integration concepts, Salesforce REST API examples, Salesforce Named Credentials, and Salesforce Platform Events.
Frequently Asked Questions
What is the best API for Salesforce ERP integration?
There is no single best API. Use REST for smaller request-reply operations, Bulk API 2.0 for large data loads, Pub/Sub API or Platform Events for event-driven messages, and Salesforce Connect when users need external data without full replication.
Do I need Salesforce middleware to connect an ERP?
No. A direct connection can fit one stable and low-volume interface. Salesforce middleware becomes useful when several systems, complex transformations, orchestration, buffering, centralized monitoring, or reusable APIs are required.
How do I prevent duplicate ERP orders?
Generate a unique request key in Salesforce, send it with every submission and retry, and require the ERP or middleware to return the existing result for a repeated key. Do not rely only on timestamps or user-facing order names.
Should Salesforce or the ERP own customer data?
Ownership depends on the business process and should be defined by field. Salesforce may own selling contacts and account segmentation, while the ERP owns legal customer identifiers, credit terms, tax data, and billing status.
How often should Salesforce and ERP data synchronize?
Set the interval from the business freshness requirement. Inventory checks may need synchronous or near-real-time access, product catalogs may use scheduled bulk loads, and invoices may use events plus periodic reconciliation.