Salesforce-Oracle ERP Cloud Integration: End-to-End Playbook

Type: ERP Integration Systems: Salesforce (API v62.0) + Oracle ERP Cloud (24B/25A) + OIC Gen 3 Confidence: 0.85 Sources: 7 Verified: 2026-03-07 Freshness: evolving

TL;DR

System Profile

This integration playbook covers the end-to-end data flow between Salesforce CRM and Oracle ERP Cloud (Fusion Applications) for the Lead-to-Cash (L2C) process. Salesforce serves as the system of record for leads, accounts, opportunities, and quotes. Oracle ERP Cloud serves as the system of record for customers, sales orders, fulfillment, AR invoices, receipts, and the general ledger. Oracle Integration Cloud (OIC) serves as the recommended middleware, providing pre-built adapters for both systems with native support for FBDI imports, business event subscriptions, and error handling.

This card does NOT cover: Salesforce CPQ-to-Oracle ERP Cloud pricing sync, Oracle ERP Cloud Procurement (P2P) flows, or Oracle ERP Cloud HCM integration.

SystemRoleAPI SurfaceDirection
Salesforce (API v62.0)CRM -- source of truth for leads, accounts, opportunities, quotesREST API, Composite API, Bulk API 2.0, Platform Events, CDCOutbound (account/order data) + Inbound (invoice/payment sync-back)
Oracle ERP Cloud (24B/25A)ERP -- financial master for customers, orders, invoicing, GLREST API, SOAP (ERP Integration Service), FBDI via UCM, Business EventsInbound (customer/order from SF) + Outbound (invoice/receipt to SF)
Oracle Integration Cloud (OIC Gen 3)Middleware -- orchestration, transformation, error handlingSalesforce Adapter, ERP Cloud Adapter, FTP Adapter, REST/SOAPBidirectional orchestrator

API Surfaces & Capabilities

API SurfaceSystemProtocolBest ForMax Records/RequestRate LimitReal-time?Bulk?
REST API v62.0SalesforceHTTPS/JSONIndividual record CRUD, SOQL queries2,000 per query page100K calls/24h (Enterprise)YesNo
Composite APISalesforceHTTPS/JSONMulti-object operations in single call25 subrequestsShared with RESTYesNo
Bulk API 2.0SalesforceHTTPS/CSVData migration, ETL, >2K records150 MB per file15,000 batches/24hNoYes
Platform Events / CDCSalesforceBayeux/CometDReal-time change notificationsN/A (streaming)Edition-dependentYesN/A
REST APIOracle ERP CloudHTTPS/JSONIndividual record CRUD, queries500 per POSTThrottled (fair use)YesNo
SOAP (ErpIntegrationService)Oracle ERP CloudHTTPS/XMLFBDI file upload to UCM, ESS job submissionN/A (file-based)ESS concurrency limitNoYes
FBDI (File-Based Data Import)Oracle ERP CloudCSV via UCMBulk import: customers, orders, invoices, journals250 MB per file16-24 concurrent ESS jobsNoYes
Business EventsOracle ERP CloudJMS/OIC subscriptionERP-initiated notificationsN/AN/AYesN/A
OIC Salesforce AdapterOICSFDC API (SOAP)Trigger on SF record changes, invoke SF operationsAdapter-managedOIC message packYesNo
OIC ERP Cloud AdapterOICNativeFBDI import, business event subscription, callbackAdapter-managedOIC message packBothYes

Rate Limits & Quotas

Per-Request Limits

Limit TypeValueSystemNotes
Max records per SOQL query page2,000SalesforceUse queryMore/nextRecordsUrl for pagination
Max Composite subrequests25SalesforceAll-or-nothing by default
Max REST request body50 MBSalesforce
Max Bulk API file size150 MBSalesforceSplit larger files
Max records per REST POST500Oracle ERP CloudUse FBDI for larger volumes
Max FBDI file size (UCM upload)250 MBOracle ERP CloudSplit larger data sets into multiple files
Max OIC payload size10 MBOICUse stage file for larger payloads
Apex callout timeout120 secondsSalesforcePer individual callout

Rolling / Daily Limits

Limit TypeValueWindowNotes
Salesforce API calls100,000 + 1,000 per user license24h rollingEnterprise edition base
Salesforce Bulk API batches15,00024h rollingShared across all editions
Oracle ERP Cloud concurrent ESS jobs16-24 (pod-dependent)Real-timeShared across ALL scheduled processes
OIC messagesPer message pack (5K/20K/50K/100K per hour)HourlyExceeded = throttled, not blocked
Salesforce Streaming events100K-10M24hDepends on add-on licenses
Salesforce concurrent long-running requests25Per org, real-timeRequests >20s count as long-running

Transaction / Governor Limits

Limit TypePer-Transaction ValueSystemNotes
SOQL queries100SalesforceIncludes queries from triggers -- cascading triggers consume from same pool
DML statements150SalesforceEach insert/update/delete counts as 1, regardless of record count
Callouts (HTTP)100SalesforceExternal HTTP requests within a transaction
CPU time10,000 ms (sync), 60,000 ms (async)SalesforceExceeded = transaction abort
Heap size6 MB (sync), 12 MB (async)Salesforce
Total email invocations10SalesforcePer Apex transaction

Authentication

SystemFlowUse WhenToken LifetimeRefresh?Notes
SalesforceOAuth 2.0 JWT BearerServer-to-server integration (recommended)Session timeout (default 2h)New JWT per requestRequires Connected App + digital certificate
SalesforceOAuth 2.0 Web ServerUser-context operationsAccess: 2h, Refresh: until revokedYesRequires callback URL
SalesforceClient CredentialsFirst-party server-to-serverAccess: 2hNoSimpler than JWT, limited scope
Oracle ERP CloudOAuth 2.0 Client Credentials via IDCSServer-to-server (recommended for OIC)Access: 1h (configurable)YesRegister OAuth client in IDCS; scope to ERP Cloud
Oracle ERP CloudOAuth 2.0 JWT Assertion via IDCSAutomated integration without user contextAccess: 1hNew JWT per requestRequires IDCS app registration + certificate
Oracle ERP CloudBasic Auth (username/password)Legacy or quick testing onlySession-basedN/ADo NOT use in production -- no token rotation, no MFA
OICManaged ConnectionsAll OIC integrationsOIC-managedOIC-managedOIC stores and refreshes credentials for both SF and ERP

Authentication Gotchas

Constraints

Integration Pattern Decision Tree

START -- Salesforce <-> Oracle ERP Cloud L2C Integration
|
+-- What entity are you syncing?
|   +-- Accounts/Customers
|   |   +-- Direction: SF Account --> Oracle Customer
|   |   +-- Volume < 100/batch? --> Oracle REST API
|   |   +-- Volume > 100/batch? --> FBDI: Customer Interface CSV
|   |   +-- Real-time? --> OIC triggered by SF Platform Event or CDC
|   |   +-- ALWAYS sync customers BEFORE orders
|   |
|   +-- Opportunities/Orders
|   |   +-- Trigger: Opportunity Closed-Won in SF
|   |   +-- Volume < 100/batch? --> Oracle REST API
|   |   +-- Volume > 100/batch? --> FBDI: Order Import CSV
|   |   +-- Pre-check: Customer + Items exist in Oracle
|   |   +-- Store Oracle Order Number back in SF
|   |
|   +-- Invoices (sync-back)
|   |   +-- Trigger: AR Invoice created in Oracle
|   |   +-- Direction: Oracle --> SF via OIC + Business Events
|   |
|   +-- Payments/Receipts (sync-back)
|   |   +-- Trigger: Receipt applied in Oracle AR
|   |   +-- Direction: Oracle --> SF via OIC scheduled poll
|   |
|   +-- Products/Items
|       +-- Direction: Oracle Item Master --> SF Product2
|       +-- Sync: Scheduled batch (items change infrequently)
|
+-- Which integration pattern?
|   +-- Real-time (<1s) --> OIC + SF Adapter trigger + Oracle REST API
|   +-- Near-real-time (1-15 min) --> OIC scheduled poll or Platform Events
|   +-- Batch/bulk --> OIC with FBDI pattern (CSV + UCM + ESS)
|   +-- Event-driven --> SF Platform Events + Oracle Business Events via OIC
|
+-- Error tolerance?
    +-- Zero-loss --> Idempotency + OIC error hospital + DLQ
    +-- Best-effort --> OIC with retry + email notification

Quick Reference

StepSource SystemActionTarget SystemData ObjectsMethodFailure Handling
1SalesforceAccount created/updatedOracle ERP CloudReceivables CustomerOIC: SF Adapter → REST API or FBDIRetry 3x, then OIC error hospital
2SalesforceOpportunity Closed-WonOracle ERP CloudSales Order + LinesOIC: SF Adapter → FBDI or REST APIValidate customer exists; retry 3x, then DLQ
3Oracle ERP CloudOrder booked (Business Event)SalesforceOpportunity status updateOIC: ERP Adapter → SF REST APIRetry 3x, manual review
4Oracle ERP CloudShipment confirmedSalesforceOrder fulfillment statusOIC: ERP Adapter → SF REST APIRetry 3x, log to pipeline
5Oracle ERP CloudAR Invoice createdSalesforceCustom Invoice objectOIC: ERP Adapter → SF REST APIRetry 3x, then DLQ
6Oracle ERP CloudReceipt appliedSalesforcePayment record updateOIC: Scheduled → SF REST APINightly reconciliation
7Oracle ERP CloudItem master changedSalesforceProduct2 / PricebookEntryOIC: Scheduled poll → SF Bulk APILog mismatches, manual review

Step-by-Step Integration Guide

1. Configure OIC Connections

Set up OIC connections for both Salesforce and Oracle ERP Cloud. The Salesforce Adapter requires a Connected App with OAuth 2.0 credentials. The Oracle ERP Cloud Adapter uses the native Fusion connection. [src2, src5]

OIC Console --> Connections --> Create
  Salesforce Connection:
    Adapter: Salesforce
    Connection Type: Invoke + Trigger
    Security Policy: OAuth 2.0 JWT Bearer or Username/Password
    Salesforce Instance URL: https://yourorg.my.salesforce.com

  Oracle ERP Cloud Connection:
    Adapter: Oracle ERP Cloud
    Connection Type: Invoke + Trigger
    ERP Cloud Host: https://your-erp-instance.fa.ocs.oraclecloud.com
    Security Policy: Username/Password or OAuth

Verify: Test both connections in OIC Console -- green checkmark indicates successful authentication.

2. Build Account-to-Customer Sync

Create an OIC integration that triggers on Salesforce Account changes and creates/updates Oracle ERP Cloud Receivables Customers. [src4, src5]

OIC Integration Flow:
  Trigger: Salesforce Adapter (Platform Events or Scheduled Query)
    --> Object: Account
    --> Fields: Id, Name, BillingStreet, BillingCity, BillingState, BillingPostalCode, BillingCountry

  Map: Salesforce Account --> Oracle Customer fields (see Data Mapping section)

  Invoke: Oracle ERP Cloud Adapter
    --> < 100 records: REST API POST /fscmRestApi/resources/latest/receivablesCustomers
    --> > 100 records: FBDI pattern (CSV + UCM + ESS job)

  Response: Log Oracle Customer Number, write back to SF Account custom field

Verify: Create a test Account in Salesforce sandbox -- confirm Customer appears in Oracle ERP Cloud Receivables.

3. Build Order Sync (Opportunity Closed-Won)

Trigger on Salesforce Opportunity stage change to "Closed Won" and create a Sales Order in Oracle ERP Cloud. [src4, src5]

OIC Integration Flow:
  Trigger: Salesforce Adapter
    --> Object: Opportunity (StageName = 'Closed Won')
    --> Include: OpportunityLineItems

  Pre-Validation:
    --> Customer exists in Oracle? If no, create first
    --> All items exist in Oracle? If no, fail with error

  Invoke: Oracle ERP Cloud Adapter
    --> REST API: POST /fscmRestApi/resources/latest/salesOrdersForOrderHub
    --> Or FBDI: Order Import template

  Post: Write Oracle Order Number back to SF Opportunity

Verify: Close an Opportunity in Salesforce sandbox -- confirm Sales Order in Oracle ERP Cloud Order Management.

4. Build Invoice Sync-Back

Subscribe to Oracle ERP Cloud Business Events for AR Invoice creation and push invoice data back to Salesforce. [src3, src5]

OIC Integration Flow:
  Trigger: Oracle ERP Cloud Adapter (Business Event)
    --> Event: oracle.apps.financials.receivables.invoices.invoiceCreated

  Map: Oracle Invoice --> Salesforce Invoice fields
  Invoke: Salesforce REST API --> Create/Update Invoice__c or Opportunity fields

  Error Handling: Retry with exponential backoff (3 attempts)

Verify: Create AR Invoice in Oracle ERP Cloud -- confirm invoice data in Salesforce.

Code Examples

Python: Authenticate to Oracle ERP Cloud REST API (OAuth 2.0)

# Input:  IDCS credentials (client_id, client_secret, idcs_url)
# Output: Access token for Oracle ERP Cloud REST API calls

import requests

def get_oracle_erp_token(idcs_url, client_id, client_secret, erp_scope):
    """Obtain OAuth 2.0 access token from Oracle IDCS for ERP Cloud."""
    token_url = f"{idcs_url}/oauth2/v1/token"
    response = requests.post(
        token_url,
        auth=(client_id, client_secret),
        data={
            "grant_type": "client_credentials",
            "scope": erp_scope  # e.g., "urn:opc:idm:__myscopes__"
        },
        headers={"Content-Type": "application/x-www-form-urlencoded"},
        timeout=30
    )
    response.raise_for_status()
    return response.json()["access_token"]  # Valid for ~3600 seconds

Python: Create Oracle ERP Cloud Customer from Salesforce Account

# Input:  Salesforce Account dict, Oracle ERP Cloud access token
# Output: Oracle Customer Number

import requests

def create_oracle_customer(erp_host, token, sf_account):
    """Create Receivables Customer in Oracle ERP Cloud from SF Account."""
    url = f"{erp_host}/fscmRestApi/resources/latest/receivablesCustomers"
    payload = {
        "CustomerName": sf_account["Name"][:360],
        "CustomerType": "R",  # R = External
        "Address1": sf_account.get("BillingStreet", "")[:240],
        "City": sf_account.get("BillingCity", ""),
        "Country": sf_account.get("BillingCountry", ""),
        "OrigSystemReference": sf_account["Id"],  # Cross-reference key
    }
    headers = {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json",
        "REST-Framework-Version": "4"
    }
    response = requests.post(url, json=payload, headers=headers, timeout=60)
    if response.status_code == 429:
        raise Exception("Rate limited -- implement exponential backoff")
    response.raise_for_status()
    return response.json()["CustomerNumber"]

cURL: Test Oracle ERP Cloud and Salesforce API Access

# Step 1: Get OAuth token from Oracle IDCS
curl -X POST "https://idcs-abc123.identity.oraclecloud.com/oauth2/v1/token" \
  -u "client_id:client_secret" \
  -d "grant_type=client_credentials&scope=urn:opc:idm:__myscopes__"

# Step 2: Query Oracle ERP Cloud customers
curl "https://your-erp.fa.ocs.oraclecloud.com/fscmRestApi/resources/latest/receivablesCustomers?limit=5" \
  -H "Authorization: Bearer YOUR_TOKEN" -H "REST-Framework-Version: 4"

# Step 3: Check Salesforce API limits
curl "https://yourorg.my.salesforce.com/services/data/v62.0/limits" \
  -H "Authorization: Bearer SF_TOKEN"

Data Mapping

Field Mapping Reference

Salesforce FieldOracle ERP Cloud FieldTypeTransformGotcha
Account.NamereceivablesCustomers.CustomerNameStringTruncate to 360 charsSF allows 255, Oracle allows 360 -- watch for special characters
Account.Id (18-char)receivablesCustomers.OrigSystemReferenceStringDirect (cross-reference key)Oracle OrigSystemReference max 240 chars
Account.BillingStreetCustomerAddress.Address1StringTruncate to 240 charsSF multi-line textarea; Oracle Address1 is single line
Account.BillingCountryCustomerAddress.CountryStringMap SF country name to Oracle ISO codeSF stores "United States"; Oracle expects "US"
Account.CurrencyIsoCodereceivablesCustomers.CurrencyCodeStringDirect if multi-currencyMismatch causes invoice posting failures
Opportunity.AmountsalesOrdersForOrderHub.OrderTotalCurrencyConvert currency if multi-currency orgExchange rate must match Oracle GL daily rate
OpportunityLineItem.QuantityOrderLine.OrderedQuantityDecimalDirectSF allows 8 decimals; Oracle typically 2-6 depending on UOM
OpportunityLineItem.UnitPriceOrderLine.UnitSellingPriceCurrencyDirectMust match Oracle price list or pass override flag
OpportunityLineItem.Product2.ProductCodeOrderLine.ProductNumberStringLookup: SF ProductCode to Oracle Item NumberMust exist in Oracle Item Master
Opportunity.CloseDatesalesOrdersForOrderHub.RequestedShipDateDateDirect or business logicTimezone mismatch can shift date by one day

Data Type Gotchas

Error Handling & Failure Points

Common Error Codes

Code/ErrorSystemMeaningCauseResolution
429 Too Many RequestsBothRate limit exceededToo many API callsExponential backoff: wait 2^n seconds, max 5 retries
FBDI "Hierarchy Error"Oracle ERP CloudFBDI validation failureMissing/misplaced column or invalid parent referenceRe-download CSV template from Oracle; validate all columns
ESS JOB_STATUS = ERROROracle ERP CloudScheduled process failedData validation, duplicate key, or missing lookupCheck ESS job log; search for row-level errors
INVALID_FIELDSalesforceField not writable or missingWrong API version or field-level securityCheck FLS for integration user profile
UNABLE_TO_LOCK_ROWSalesforceRecord lockedConcurrent updates to same recordRetry with jitter (1-5s random delay)
DUPLICATE_VALUESalesforceUnique field constraint violationCross-reference ID already existsUse upsert with ExternalId instead of insert
ORA-20001Oracle ERP CloudCustom validation rule failureBusiness rule violationReview Oracle setup data; ensure lookup values exist
UCM Upload TimeoutOracle ERP CloudFile upload timed outFile too large or network latencySplit files <100 MB; retry with increased timeout

Failure Points in Production

Anti-Patterns

Wrong: Synchronous callouts from Salesforce triggers to Oracle ERP Cloud

// BAD -- Apex trigger makes synchronous HTTP callout to Oracle for every Account update
// This will hit governor limits (100 callouts per transaction) when bulk updates occur
trigger AccountSync on Account (after update) {
    for (Account acc : Trigger.new) {
        Http h = new Http();
        HttpRequest req = new HttpRequest();
        req.setEndpoint('https://erp.oraclecloud.com/fscmRestApi/...');
        req.setMethod('POST');
        h.send(req);  // 200 accounts = 200 callouts = GOVERNOR LIMIT EXCEEDED
    }
}

Correct: Publish Platform Events; let OIC subscribe and process asynchronously

// GOOD -- Trigger publishes Platform Event; OIC subscribes and processes in batches
trigger AccountSync on Account (after update) {
    List<Account_Change__e> events = new List<Account_Change__e>();
    for (Account acc : Trigger.new) {
        events.add(new Account_Change__e(
            Account_Id__c = acc.Id,
            Change_Type__c = 'UPDATE'
        ));
    }
    EventBus.publish(events);  // One DML, no callouts, no governor limit risk
}
// OIC Salesforce Adapter subscribes to Account_Change__e

Wrong: Polling Oracle ERP Cloud REST API every 60 seconds for status changes

# BAD -- Polling REST API wastes API quota and may miss changes between polls
import time
while True:
    response = requests.get(f"{erp_host}/fscmRestApi/resources/latest/salesOrders"
                           f"?q=LastUpdateDate>{last_poll_time}")
    process_orders(response.json())
    time.sleep(60)  # Burns quota; misses sub-second changes; no error handling

Correct: Subscribe to Oracle Business Events via OIC

# GOOD -- Oracle publishes Business Events on status change; OIC subscribes
OIC Integration:
  Trigger: Oracle ERP Cloud Adapter
    --> Business Event: oracle.apps.scm.orderManagement.orders.orderBookedEvent
  Process: Extract Order Number, Status
  Invoke: Salesforce REST API --> Update Opportunity
  Error: Route to OIC error hospital

Wrong: Building FBDI CSV files with hardcoded column positions

# BAD -- Hardcoded column order breaks when Oracle adds/removes columns
csv_row = f"{customer_name},{address1},{city},{state},{zip},{country}"
# Column order changed in 24B release -- entire import silently fails

Correct: Use Oracle-provided FBDI template and map by column header

# GOOD -- Download template from Oracle, map by header name
template_headers = get_template_headers("CustomerInterface.csv")
row = {col: "" for col in template_headers}  # Initialize all columns
row["CUSTOMER_NAME"] = sf_account["Name"][:360]
row["ADDRESS1"] = sf_account.get("BillingStreet", "")[:240]
row["ORIG_SYSTEM_REFERENCE"] = sf_account["Id"]
# Only populated columns mapped; rest stay empty -- Oracle handles defaults

Common Pitfalls

Diagnostic Commands

# ====== SALESFORCE DIAGNOSTICS ======

# Check Salesforce API usage / remaining daily limits
curl "https://yourorg.my.salesforce.com/services/data/v62.0/limits" \
  -H "Authorization: Bearer $SF_TOKEN"

# Test Salesforce authentication (JWT bearer flow)
curl -X POST "https://login.salesforce.com/services/oauth2/token" \
  -d "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=$JWT"

# ====== ORACLE ERP CLOUD DIAGNOSTICS ======

# Get OAuth token from Oracle IDCS
curl -X POST "https://idcs-abc123.identity.oraclecloud.com/oauth2/v1/token" \
  -u "$ORA_CLIENT_ID:$ORA_CLIENT_SECRET" \
  -d "grant_type=client_credentials&scope=urn:opc:idm:__myscopes__"

# Verify Oracle ERP Cloud REST API access
curl "https://your-erp.fa.ocs.oraclecloud.com/fscmRestApi/resources/latest/receivablesCustomers?limit=1" \
  -H "Authorization: Bearer $ORA_TOKEN" -H "REST-Framework-Version: 4"

# Check FBDI/ESS job status
curl "https://your-erp.fa.ocs.oraclecloud.com/fscmRestApi/resources/latest/erpintegrations" \
  -H "Authorization: Bearer $ORA_TOKEN" -H "REST-Framework-Version: 4"

# ====== OIC DIAGNOSTICS ======

# Check OIC integration run history
curl "https://your-oic.integration.ocp.oraclecloud.com/ic/api/integration/v1/monitoring/runs?limit=10" \
  -H "Authorization: Bearer $OIC_TOKEN"

Version History & Compatibility

ComponentVersionRelease DateStatusBreaking ChangesNotes
Salesforce APIv62.0 (Spring '26)2026-02CurrentNone
Salesforce APIv61.0 (Winter '26)2025-10SupportedNone
Salesforce APIv60.0 (Summer '25)2025-06SupportedDeprecated SOAP API for new devExisting SOAP integrations still work
Oracle ERP Cloud25A2025-01CurrentNew REST endpoints for Order ManagementAdditional fields on salesOrdersForOrderHub
Oracle ERP Cloud24B2024-07SupportedFBDI template changes for Customer ImportRe-download templates after upgrade
OICGen 32025-06CurrentNew throttling engine, message pack modelOIC Gen 2 EOL announced
OICGen 22023-01Supported (EOL planned)N/AMigrate to Gen 3 before EOL

When to Use / When Not to Use

Use WhenDon't Use WhenUse Instead
Salesforce is CRM and Oracle ERP Cloud (Fusion) is financial ERPOracle ERP is EBS (on-premise), not Fusion CloudOracle EBS-specific integration patterns
Lead-to-Cash, Order-to-Cash, or Quote-to-Cash flowProcurement or P2P flow (PO, AP, Supplier management)Oracle ERP Cloud P2P integration playbook
OIC is available as middlewareCommitted to MuleSoft or non-Oracle middleware onlyMuleSoft Anypoint Salesforce-Oracle connector patterns
Volume <100K records/day per entityVolume >1M records/day requiring near-real-timeCustom data pipeline (Kafka/streaming) with Oracle BICC extraction
Standard Salesforce objects (Account, Opportunity, Order)Heavy Salesforce CPQ with complex pricing and bundlingSalesforce CPQ-to-Oracle integration playbook

Important Caveats

Related Units