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
- Bottom line: Use Oracle Integration Cloud (OIC) with pre-built Salesforce and ERP Cloud adapters for the fastest path to production; use FBDI for bulk/batch imports (>100 records) and REST API for real-time individual record sync.
- Key limit: Oracle ERP Cloud REST API caps POST operations at 500 records; for anything larger, FBDI (File-Based Data Import) via UCM upload + ESS job is mandatory.
- Watch out for: FBDI CSV templates are entity-specific with strict column ordering -- a single misplaced column causes silent import failures; always generate templates from Oracle ERP Cloud's export function, not manually.
- Best for: Lead-to-Cash automation where Salesforce owns the customer relationship and pipeline, Oracle ERP Cloud owns order management, fulfillment, AR invoicing, and financial close.
- Authentication: Salesforce OAuth 2.0 JWT Bearer (server-to-server) + Oracle ERP Cloud OAuth 2.0 via IDCS (client credentials or JWT assertion); OIC manages both connections natively.
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.
| System | Role | API Surface | Direction |
| Salesforce (API v62.0) | CRM -- source of truth for leads, accounts, opportunities, quotes | REST API, Composite API, Bulk API 2.0, Platform Events, CDC | Outbound (account/order data) + Inbound (invoice/payment sync-back) |
| Oracle ERP Cloud (24B/25A) | ERP -- financial master for customers, orders, invoicing, GL | REST API, SOAP (ERP Integration Service), FBDI via UCM, Business Events | Inbound (customer/order from SF) + Outbound (invoice/receipt to SF) |
| Oracle Integration Cloud (OIC Gen 3) | Middleware -- orchestration, transformation, error handling | Salesforce Adapter, ERP Cloud Adapter, FTP Adapter, REST/SOAP | Bidirectional orchestrator |
API Surfaces & Capabilities
| API Surface | System | Protocol | Best For | Max Records/Request | Rate Limit | Real-time? | Bulk? |
| REST API v62.0 | Salesforce | HTTPS/JSON | Individual record CRUD, SOQL queries | 2,000 per query page | 100K calls/24h (Enterprise) | Yes | No |
| Composite API | Salesforce | HTTPS/JSON | Multi-object operations in single call | 25 subrequests | Shared with REST | Yes | No |
| Bulk API 2.0 | Salesforce | HTTPS/CSV | Data migration, ETL, >2K records | 150 MB per file | 15,000 batches/24h | No | Yes |
| Platform Events / CDC | Salesforce | Bayeux/CometD | Real-time change notifications | N/A (streaming) | Edition-dependent | Yes | N/A |
| REST API | Oracle ERP Cloud | HTTPS/JSON | Individual record CRUD, queries | 500 per POST | Throttled (fair use) | Yes | No |
| SOAP (ErpIntegrationService) | Oracle ERP Cloud | HTTPS/XML | FBDI file upload to UCM, ESS job submission | N/A (file-based) | ESS concurrency limit | No | Yes |
| FBDI (File-Based Data Import) | Oracle ERP Cloud | CSV via UCM | Bulk import: customers, orders, invoices, journals | 250 MB per file | 16-24 concurrent ESS jobs | No | Yes |
| Business Events | Oracle ERP Cloud | JMS/OIC subscription | ERP-initiated notifications | N/A | N/A | Yes | N/A |
| OIC Salesforce Adapter | OIC | SFDC API (SOAP) | Trigger on SF record changes, invoke SF operations | Adapter-managed | OIC message pack | Yes | No |
| OIC ERP Cloud Adapter | OIC | Native | FBDI import, business event subscription, callback | Adapter-managed | OIC message pack | Both | Yes |
Rate Limits & Quotas
Per-Request Limits
| Limit Type | Value | System | Notes |
| Max records per SOQL query page | 2,000 | Salesforce | Use queryMore/nextRecordsUrl for pagination |
| Max Composite subrequests | 25 | Salesforce | All-or-nothing by default |
| Max REST request body | 50 MB | Salesforce | |
| Max Bulk API file size | 150 MB | Salesforce | Split larger files |
| Max records per REST POST | 500 | Oracle ERP Cloud | Use FBDI for larger volumes |
| Max FBDI file size (UCM upload) | 250 MB | Oracle ERP Cloud | Split larger data sets into multiple files |
| Max OIC payload size | 10 MB | OIC | Use stage file for larger payloads |
| Apex callout timeout | 120 seconds | Salesforce | Per individual callout |
Rolling / Daily Limits
| Limit Type | Value | Window | Notes |
| Salesforce API calls | 100,000 + 1,000 per user license | 24h rolling | Enterprise edition base |
| Salesforce Bulk API batches | 15,000 | 24h rolling | Shared across all editions |
| Oracle ERP Cloud concurrent ESS jobs | 16-24 (pod-dependent) | Real-time | Shared across ALL scheduled processes |
| OIC messages | Per message pack (5K/20K/50K/100K per hour) | Hourly | Exceeded = throttled, not blocked |
| Salesforce Streaming events | 100K-10M | 24h | Depends on add-on licenses |
| Salesforce concurrent long-running requests | 25 | Per org, real-time | Requests >20s count as long-running |
Transaction / Governor Limits
| Limit Type | Per-Transaction Value | System | Notes |
| SOQL queries | 100 | Salesforce | Includes queries from triggers -- cascading triggers consume from same pool |
| DML statements | 150 | Salesforce | Each insert/update/delete counts as 1, regardless of record count |
| Callouts (HTTP) | 100 | Salesforce | External HTTP requests within a transaction |
| CPU time | 10,000 ms (sync), 60,000 ms (async) | Salesforce | Exceeded = transaction abort |
| Heap size | 6 MB (sync), 12 MB (async) | Salesforce | |
| Total email invocations | 10 | Salesforce | Per Apex transaction |
Authentication
| System | Flow | Use When | Token Lifetime | Refresh? | Notes |
| Salesforce | OAuth 2.0 JWT Bearer | Server-to-server integration (recommended) | Session timeout (default 2h) | New JWT per request | Requires Connected App + digital certificate |
| Salesforce | OAuth 2.0 Web Server | User-context operations | Access: 2h, Refresh: until revoked | Yes | Requires callback URL |
| Salesforce | Client Credentials | First-party server-to-server | Access: 2h | No | Simpler than JWT, limited scope |
| Oracle ERP Cloud | OAuth 2.0 Client Credentials via IDCS | Server-to-server (recommended for OIC) | Access: 1h (configurable) | Yes | Register OAuth client in IDCS; scope to ERP Cloud |
| Oracle ERP Cloud | OAuth 2.0 JWT Assertion via IDCS | Automated integration without user context | Access: 1h | New JWT per request | Requires IDCS app registration + certificate |
| Oracle ERP Cloud | Basic Auth (username/password) | Legacy or quick testing only | Session-based | N/A | Do NOT use in production -- no token rotation, no MFA |
| OIC | Managed Connections | All OIC integrations | OIC-managed | OIC-managed | OIC stores and refreshes credentials for both SF and ERP |
Authentication Gotchas
- Oracle IDCS OAuth client setup requires Domain Administrator: The ERP Cloud Service Administrator alone cannot register the OAuth client. Plan for cross-team coordination and 1-2 week lead time. [src3]
- Salesforce JWT flow requires per-environment certificates: Self-signed works for sandbox; CA-signed recommended for production. The Connected App must pre-authorize the integration user. [src1]
- Oracle ERP Cloud session timeout is admin-configurable: Don't hardcode token lifetimes. Default is 60 minutes but admins can change it. Always implement token refresh logic. [src3]
- OIC Salesforce Adapter uses SOAP API internally: Even though you configure REST-like operations, the adapter authenticates via SOAP login. Ensure the integration user has "API Enabled" permission AND SOAP API access. [src2]
- OAuth refresh tokens expire after 90 days of non-use in Salesforce: Unattended integrations that go dormant silently fail. Implement a keep-alive token refresh cycle. [src1]
Constraints
- Oracle ERP Cloud REST API is not designed for bulk operations: Max 500 records per POST. For anything over ~100 records, Oracle's own guidance is to use FBDI. REST is for real-time, individual record operations only.
- FBDI CSV templates are entity-specific and column-order-dependent: A single misplaced or missing column causes the ESS import job to fail silently or with cryptic "Hierarchy Error" messages. Always download the template from Oracle ERP Cloud.
- OIC message pack governs total throughput: Every adapter invocation (trigger + invoke) counts as messages. A single integration that syncs 10,000 orders/day with 5 lookups each consumes 60,000 messages.
- Salesforce governor limits apply to the ENTIRE transaction: A trigger that fires on 200 records has ONE pool of 100 SOQL queries and 100 callouts for ALL 200 records combined. Bulkify all Apex code.
- Oracle ERP Cloud ESS job concurrency is shared: The 16-24 concurrent job slots are shared across ALL scheduled processes -- not just integrations. Month-end GL close can consume all slots.
- Bidirectional sync requires explicit conflict resolution: Without a defined "source of truth" per field, update loops between Salesforce and Oracle ERP Cloud will oscillate and consume API limits.
- Oracle ERP Cloud FBDI customer import requires manual batch identifier: Unlike other entities, customer FBDI import needs a pre-created batch ID that cannot be auto-generated by OIC.
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
| Step | Source System | Action | Target System | Data Objects | Method | Failure Handling |
| 1 | Salesforce | Account created/updated | Oracle ERP Cloud | Receivables Customer | OIC: SF Adapter → REST API or FBDI | Retry 3x, then OIC error hospital |
| 2 | Salesforce | Opportunity Closed-Won | Oracle ERP Cloud | Sales Order + Lines | OIC: SF Adapter → FBDI or REST API | Validate customer exists; retry 3x, then DLQ |
| 3 | Oracle ERP Cloud | Order booked (Business Event) | Salesforce | Opportunity status update | OIC: ERP Adapter → SF REST API | Retry 3x, manual review |
| 4 | Oracle ERP Cloud | Shipment confirmed | Salesforce | Order fulfillment status | OIC: ERP Adapter → SF REST API | Retry 3x, log to pipeline |
| 5 | Oracle ERP Cloud | AR Invoice created | Salesforce | Custom Invoice object | OIC: ERP Adapter → SF REST API | Retry 3x, then DLQ |
| 6 | Oracle ERP Cloud | Receipt applied | Salesforce | Payment record update | OIC: Scheduled → SF REST API | Nightly reconciliation |
| 7 | Oracle ERP Cloud | Item master changed | Salesforce | Product2 / PricebookEntry | OIC: Scheduled poll → SF Bulk API | Log 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 Field | Oracle ERP Cloud Field | Type | Transform | Gotcha |
| Account.Name | receivablesCustomers.CustomerName | String | Truncate to 360 chars | SF allows 255, Oracle allows 360 -- watch for special characters |
| Account.Id (18-char) | receivablesCustomers.OrigSystemReference | String | Direct (cross-reference key) | Oracle OrigSystemReference max 240 chars |
| Account.BillingStreet | CustomerAddress.Address1 | String | Truncate to 240 chars | SF multi-line textarea; Oracle Address1 is single line |
| Account.BillingCountry | CustomerAddress.Country | String | Map SF country name to Oracle ISO code | SF stores "United States"; Oracle expects "US" |
| Account.CurrencyIsoCode | receivablesCustomers.CurrencyCode | String | Direct if multi-currency | Mismatch causes invoice posting failures |
| Opportunity.Amount | salesOrdersForOrderHub.OrderTotal | Currency | Convert currency if multi-currency org | Exchange rate must match Oracle GL daily rate |
| OpportunityLineItem.Quantity | OrderLine.OrderedQuantity | Decimal | Direct | SF allows 8 decimals; Oracle typically 2-6 depending on UOM |
| OpportunityLineItem.UnitPrice | OrderLine.UnitSellingPrice | Currency | Direct | Must match Oracle price list or pass override flag |
| OpportunityLineItem.Product2.ProductCode | OrderLine.ProductNumber | String | Lookup: SF ProductCode to Oracle Item Number | Must exist in Oracle Item Master |
| Opportunity.CloseDate | salesOrdersForOrderHub.RequestedShipDate | Date | Direct or business logic | Timezone mismatch can shift date by one day |
Data Type Gotchas
- Country codes: Salesforce stores full country names by default; Oracle expects ISO 3166 alpha-2 codes. Enable State/Country Picklists in Salesforce or maintain a mapping table in OIC. [src5]
- Currency handling: If Salesforce org is multi-currency, CurrencyIsoCode may differ from Oracle ledger currency. Oracle rejects transactions where currency doesn't match the customer's profile. [src3]
- Address line splitting: Salesforce BillingStreet is a single textarea. Oracle has Address1-Address4 (each 240 chars). Split on newlines or truncate. [src4]
- Date/timezone mismatch: Oracle REST API uses ISO 8601; Salesforce dates are YYYY-MM-DD. Timezone differences between SF user timezone and Oracle server timezone can shift dates by one day. [src3]
- Null handling: Salesforce returns null for empty fields. Oracle REST API ignores null on create but treats explicit null as "clear the value" on update. [src3]
Error Handling & Failure Points
Common Error Codes
| Code/Error | System | Meaning | Cause | Resolution |
| 429 Too Many Requests | Both | Rate limit exceeded | Too many API calls | Exponential backoff: wait 2^n seconds, max 5 retries |
| FBDI "Hierarchy Error" | Oracle ERP Cloud | FBDI validation failure | Missing/misplaced column or invalid parent reference | Re-download CSV template from Oracle; validate all columns |
| ESS JOB_STATUS = ERROR | Oracle ERP Cloud | Scheduled process failed | Data validation, duplicate key, or missing lookup | Check ESS job log; search for row-level errors |
| INVALID_FIELD | Salesforce | Field not writable or missing | Wrong API version or field-level security | Check FLS for integration user profile |
| UNABLE_TO_LOCK_ROW | Salesforce | Record locked | Concurrent updates to same record | Retry with jitter (1-5s random delay) |
| DUPLICATE_VALUE | Salesforce | Unique field constraint violation | Cross-reference ID already exists | Use upsert with ExternalId instead of insert |
| ORA-20001 | Oracle ERP Cloud | Custom validation rule failure | Business rule violation | Review Oracle setup data; ensure lookup values exist |
| UCM Upload Timeout | Oracle ERP Cloud | File upload timed out | File too large or network latency | Split files <100 MB; retry with increased timeout |
Failure Points in Production
- FBDI import succeeds but creates zero records: ESS job completes SUCCESS but interface table has row-level validation errors. Always check the ESS output log AND interface table error columns. Fix:
query fscmRestApi/resources/latest/erpintegrations to retrieve import log from UCM. [src4, src6]
- CDC event gaps between Salesforce and OIC: If OIC goes down, CDC events older than 3 days are purged. OIC does not replay automatically. Fix:
implement a catch-up integration with time-windowed SOQL query on reconnection. [src2]
- Currency mismatch between SF Opportunity and Oracle Order: Oracle validates against customer's allowed transaction currencies. Mismatch causes silent order creation failure. Fix:
validate currency against Oracle setup before submitting order. [src3, src5]
- Month-end ESS job contention: GL period close, revenue recognition jobs consume all ESS slots, blocking FBDI imports indefinitely. Fix:
schedule integration FBDI jobs outside month-end windows (avoid days 1-3 of each month). [src3, src7]
- Salesforce FLS blocks sync-back: Integration user profile lacks write access to custom Oracle cross-reference fields. Update silently succeeds but field remains empty. Fix:
create dedicated integration user profile with explicit FLS grants. [src1]
- OIC connection token expiry during long-running batch: Oracle OAuth token expires mid-integration for batches >1 hour. Fix:
set connection idle timeout to match batch duration; add explicit token refresh step. [src2, src3]
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
- Not syncing customers before orders: Oracle ERP Cloud requires a valid Customer record before a Sales Order can reference it. Fix:
always run Account-to-Customer sync first; add pre-validation lookup in order sync flow. [src4, src5]
- Ignoring Oracle ERP Cloud setup data dependencies: Orders require valid Order Type, Price List, Warehouse, Shipping Method, and Payment Terms. Fix:
maintain a mapping/validation table in OIC for all lookup values. [src3]
- Using sandbox for load testing: Both Salesforce sandbox and Oracle test instances have lower limits than production. Fix:
request full-copy sandbox (SF) and production-mirrored test pod (Oracle). [src1]
- Not handling FBDI partial failures: An FBDI import of 1,000 records may succeed at job level but have 50 row-level failures. Fix:
always download and parse the FBDI output log from UCM after every import. [src4, src6]
- Hardcoding API versions: Salesforce API v62.0 will become v63.0 in Summer '26. Oracle 24B will become 25A. Fix:
use environment variables or OIC connection properties for API versions. [src1]
- Single integration user with broad permissions: Admin-level permissions for all integrations creates security and audit risk. Fix:
create dedicated integration users per integration with minimum-required permissions. [src1, src3]
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
| Component | Version | Release Date | Status | Breaking Changes | Notes |
| Salesforce API | v62.0 (Spring '26) | 2026-02 | Current | None | |
| Salesforce API | v61.0 (Winter '26) | 2025-10 | Supported | None | |
| Salesforce API | v60.0 (Summer '25) | 2025-06 | Supported | Deprecated SOAP API for new dev | Existing SOAP integrations still work |
| Oracle ERP Cloud | 25A | 2025-01 | Current | New REST endpoints for Order Management | Additional fields on salesOrdersForOrderHub |
| Oracle ERP Cloud | 24B | 2024-07 | Supported | FBDI template changes for Customer Import | Re-download templates after upgrade |
| OIC | Gen 3 | 2025-06 | Current | New throttling engine, message pack model | OIC Gen 2 EOL announced |
| OIC | Gen 2 | 2023-01 | Supported (EOL planned) | N/A | Migrate to Gen 3 before EOL |
When to Use / When Not to Use
| Use When | Don't Use When | Use Instead |
| Salesforce is CRM and Oracle ERP Cloud (Fusion) is financial ERP | Oracle ERP is EBS (on-premise), not Fusion Cloud | Oracle EBS-specific integration patterns |
| Lead-to-Cash, Order-to-Cash, or Quote-to-Cash flow | Procurement or P2P flow (PO, AP, Supplier management) | Oracle ERP Cloud P2P integration playbook |
| OIC is available as middleware | Committed to MuleSoft or non-Oracle middleware only | MuleSoft Anypoint Salesforce-Oracle connector patterns |
| Volume <100K records/day per entity | Volume >1M records/day requiring near-real-time | Custom data pipeline (Kafka/streaming) with Oracle BICC extraction |
| Standard Salesforce objects (Account, Opportunity, Order) | Heavy Salesforce CPQ with complex pricing and bundling | Salesforce CPQ-to-Oracle integration playbook |
Important Caveats
- Oracle ERP Cloud license may include OIC entitlements -- check your Oracle contract before purchasing a third-party iPaaS.
- FBDI template changes between Oracle releases (24A, 24B, 25A). Always re-download and validate templates after each Oracle upgrade.
- Salesforce API version retirement: Pin to a specific version and monitor release notes. v62.0 is current as of Spring '26.
- Oracle ERP Cloud REST API coverage is expanding but incomplete -- not all objects have REST endpoints. Some entities still require SOAP or FBDI.
- OIC Gen 3 message pack model changes pricing from connections-based to throughput-based. Estimate actual message volume before committing.
- Rate limits and concurrent ESS job limits are subject to change with each Oracle release -- always verify against current documentation.
Related Units