Oracle to Salesforce Integration: Handling Inbound REST API
Introduction
This blog extends our previous guide on Salesforce-to-Oracle outbound integration by focusing on an inbound REST API integration where Oracle sends customer data (including Orders and Addresses) to Salesforce to create or update records. We’ll provide a detailed Apex REST service with comprehensive comments to explain the @RestResource and @HttpPost annotations and their purpose. Additionally, we’ll clarify when and how to use a Named Credential in inbound integrations, particularly for scenarios requiring outbound callbacks to Oracle. This guide is beginner-friendly, assuming basic Salesforce admin/developer knowledge and familiarity with the objects from the outbound integration.
Use Case
When a customer record is updated in Oracle (e.g., status changes or new orders are added), Oracle sends a REST API request to Salesforce to:
Update or create a Customer__c record and its related Order__c and Address__c records.
Log the request and response in Integration_Log__c for tracking.
Return a success or failure message to Oracle.
Optional Callback: Salesforce may call Oracle to validate data or confirm receipt, using a Named Credential for secure authentication.
Example Scenario: Oracle sends a JSON payload with customer details, orders, and addresses. Salesforce updates the records, logs the transaction, and optionally calls Oracle to confirm processing.
Why Oracle-to-Salesforce Integration?
Data Consistency: Sync Oracle’s operational data with Salesforce’s customer data.
Automation: Reflect Oracle updates in Salesforce without manual intervention.
Auditability: Log all requests and responses for debugging and compliance.
Flexibility: Support callbacks to Oracle for validation or confirmation using Named Credentials.
Salesforce-Side Prerequisites
The prerequisites remain the same as in the previous blog, with additions for Named Credentials:
Custom Objects:
Customer__c: Standard object with fields like Name, Status__c, Email__c, and Oracle_Customer_ID__c (External ID, Unique).
Order__c: Child of Customer__c with fields like Order_Date__c, Amount__c, and Oracle_Order_ID__c (External ID, Unique).
Address__c: Child of Customer__c with fields like Street__c, City__c, State__c, Zip_Code__c, Country__c.
Integration_Log__c: Stores integration details with fields:
Customer__c (Lookup to Customer__c)
Request_Body__c (Long Text Area)
Response_Body__c (Long Text Area)
Status_Code__c (Text)
Timestamp__c (DateTime)
Success__c (Checkbox)
Error_Message__c (Long Text Area)
Integration User:
Use a Salesforce Integration User with the Minimum Access – API Only Integrations profile.
Assign a permission set with read/write access to Customer__c, Order__c, Address__c, Integration_Log__c, and API access.
Generate a security token for OAuth or username/password authentication.
Connected App:
Create a Connected App (Setup > Apps > App Manager > New Connected App) for Oracle to authenticate via OAuth 2.0.
Set scopes: api, id, refresh_token.
Share the Client ID, Client Secret, and login URL (e.g., https://login.salesforce.com) with the Oracle team.
Named Credential (For Callbacks):
When Needed: If Salesforce needs to make an outbound call to Oracle (e.g., to validate the customer ID or send a confirmation), use a Named Credential to securely store Oracle’s API endpoint and authentication details.
Setup:
Go to Setup > Security > Named Credentials > New.
Name: Oracle_Callback
URL: Oracle’s API endpoint (e.g., https://oracle-erp.com/api).
Identity Type: Named Principal.
Authentication Protocol: OAuth 2.0 or Password Authentication.
Details: Provide Oracle’s Client ID, Client Secret, or username/password (consult Oracle team).
Allow Merge Fields in HTTP Body: Enable for dynamic payloads.
Usage: In Apex, use callout:Oracle_Callback to make secure HTTP requests without hardcoding credentials.
Sandbox Environment:
Test in a sandbox to avoid impacting production data.
Create test records for Customer__c, Order__c, and Address__c.
API Access:
Ensure Enterprise or higher edition with REST API access.
Verify the integration user has API permissions.
Step-by-Step Implementation
Step 1: Get API Details from Oracle Team
Salesforce Endpoint: You’ll provide the REST endpoint URL after creating the Apex REST service (e.g., https://yourInstance.salesforce.com/services/apexrest/oracle/customer/update/).
Authentication: Share the Connected App’s Client ID, Client Secret, and login URL for OAuth 2.0.
JSON Payload: Request a sample JSON from Oracle, e.g.:
{ "oracleCustomerId": "CUST123", "name": "John Smith", "email": "john@example.com", "status": "Completed", "orders": [ { "orderId": "ORD001", "orderDate": "2024-04-01", "amount": 100 }, { "orderId": "ORD002", "orderDate": "2024-04-02", "amount": 150 } ], "addresses": [ { "street": "Main St", "city": "Mumbai", "state": "MH", "zipCode": "400001", "country": "India" } ] }Callback Endpoint (If Needed): Ask Oracle for their API endpoint, authentication details (e.g., OAuth or API key), and expected payload for callbacks.
Step 2: Verify Custom Objects
Confirm Customer__c, Order__c, Address__c, and Integration_Log__c are set up.
Ensure Oracle_Customer_ID__c (Customer__c) and Oracle_Order_ID__c (Order__c) are External ID fields for upsert operations.
Step 3: Set Up Named Credential (For Callbacks)
Scenario: Salesforce calls Oracle to validate the oracleCustomerId before processing or to confirm successful processing.
Steps:
Go to Setup > Security > Named Credentials > New.
Label: Oracle_Callback
Name: Oracle_Callback
URL: Oracle’s API endpoint (e.g., https://oracle-erp.com/api/validate).
Identity Type: Named Principal.
Authentication Protocol: Choose based on Oracle’s requirements (e.g., OAuth 2.0 or Password Authentication).
Authentication Details: Enter Client ID, Client Secret, or username/password provided by Oracle.
Allow Merge Fields in HTTP Body: Enable for dynamic JSON payloads.
Why Use Named Credential?:
Securely stores Oracle’s endpoint and credentials, avoiding hardcoding.
Simplifies Apex callouts using callout:Oracle_Callback.
Supports OAuth or password authentication, reducing manual token management.
When Not Needed: If Salesforce only receives and processes Oracle’s data without calling Oracle, skip this step.
Step 4: Create Apex REST Service
Below is the updated Apex REST service with detailed comments explaining @RestResource, @HttpPost, and Named Credential usage. The code includes a callback to Oracle using a Named Credential to validate the customer ID.
// @RestResource annotation exposes this Apex class as a REST endpoint// urlMapping defines the URL path for the endpoint (e.g., /services/apexrest/oracle/customer/update/)// This allows external systems like Oracle to send HTTP requests to Salesforce@RestResource(urlMapping='/oracle/customer/update/*')global with sharing class OracleCustomerReceiver {// @HttpPost annotation indicates this method handles HTTP POST requests// POST is used because Oracle is sending data to create/update records// The method processes the incoming JSON, updates Salesforce records, and returns a response@HttpPostglobal static void handleCustomerUpdate() {// Get the REST request and response objectsRestRequest req = RestContext.request;RestResponse res = RestContext.response;// Initialize log record to store request/response detailsIntegration_Log__c log = new Integration_Log__c();try {// Step 1: Capture request detailsString requestBody = req.requestBody.toString();log.Request_Body__c = requestBody;log.Timestamp__c = System.now();// Step 2: Parse JSON payloadMap<String, Object> payload = (Map<String, Object>) JSON.deserializeUntyped(requestBody);String oracleCustomerId = (String) payload.get('oracleCustomerId');String name = (String) payload.get('name');String email = (String) payload.get('email');String status = (String) payload.get('status');List<Object> orders = (List<Object>) payload.get('orders');List<Object> addresses = (List<Object>) payload.get('addresses');// Step 3: Validate payloadif (String.isBlank(oracleCustomerId) || String.isBlank(name)) {throw new CustomException('Missing required fields: oracleCustomerId or name');}// Step 4: Validate customer ID with Oracle using Named Credential// Named Credential (Oracle_Callback) securely stores Oracle's endpoint and credentials// This callout checks if the oracleCustomerId exists in OracleHttpRequest validateReq = new HttpRequest();validateReq.setEndpoint('callout:Oracle_Callback/validateCustomer?customerId=' + EncodingUtil.urlEncode(oracleCustomerId, 'UTF-8'));validateReq.setMethod('GET');validateReq.setHeader('Content-Type', 'application/json');Http http = new Http();HttpResponse validateRes = http.send(validateReq);if (validateRes.getStatusCode() != 200) {throw new CustomException('Invalid customer ID: ' + validateRes.getBody());}// Step 5: Upsert Customer__c// Uses Oracle_Customer_ID__c as External ID to update existing record or create newCustomer__c customer = new Customer__c(Oracle_Customer_ID__c = oracleCustomerId,Name = name,Email__c = email,Status__c = status);upsert customer Oracle_Customer_ID__c;log.Customer__c = customer.Id;// Step 6: Upsert OrdersList<Order__c> ordersToUpsert = new List<Order__c>();for (Object ord : orders) {Map<String, Object> orderData = (Map<String, Object>) ord;ordersToUpsert.add(new Order__c(Customer__c = customer.Id,Oracle_Order_ID__c = (String) orderData.get('orderId'),Order_Date__c = Date.valueOf((String) orderData.get('orderDate')),Amount__c = (Decimal) orderData.get('amount')));}if (!ordersToUpsert.isEmpty()) {upsert ordersToUpsert Oracle_Order_ID__c;}// Step 7: Upsert Addresses// Note: Addresses lack an External ID, so deduplication logic may be neededList<Address__c> addressesToUpsert = new List<Address__c>();for (Object addr : addresses) {Map<String, Object> addrData = (Map<String, Object>) addr;addressesToUpsert.add(new Address__c(Customer__c = customer.Id,Street__c = (String) addrData.get('street'),City__c = (String) addrData.get('city'),State__c = (String) addrData.get('state'),Zip_Code__c = (String) addrData.get('zipCode'),Country__c = (String) addrData.get('country')));}if (!addressesToUpsert.isEmpty()) {upsert addressesToUpsert;}// Step 8: Send confirmation callback to Oracle using Named Credential// This notifies Oracle that the data was processed successfullyHttpRequest confirmReq = new HttpRequest();confirmReq.setEndpoint('callout:Oracle_Callback/confirm');confirmReq.setMethod('POST');confirmReq.setHeader('Content-Type', 'application/json');confirmReq.setBody('{"customerId": "' + oracleCustomerId + '", "status": "Processed"}');HttpResponse confirmRes = http.send(confirmReq);// Log callback response (optional)log.Response_Body__c = 'Customer updated; Confirmation sent: ' + confirmRes.getBody();// Step 9: Log successlog.Status_Code__c = '200';log.Success__c = true;insert log;// Step 10: Return success response to Oracleres.statusCode = 200;res.responseBody = Blob.valueOf('{"message": "Customer updated successfully"}');} catch (Exception ex) {// Log error detailslog.Response_Body__c = ex.getMessage();log.Status_Code__c = '500';log.Success__c = false;log.Error_Message__c = ex.getMessage();insert log;// Return error response to Oracleres.statusCode = 500;res.responseBody = Blob.valueOf('{"error": "' + ex.getMessage() + '"}');}}// Custom exception class for throwing specific errorspublic class CustomException extends Exception {}}
Key Comments Explained:
@RestResource: Marks the class as a REST endpoint, making it accessible via a URL (e.g., /services/apexrest/oracle/customer/update/). The urlMapping parameter defines the endpoint path.
@HttpPost: Specifies that the handleCustomerUpdate method handles HTTP POST requests, which is appropriate for Oracle sending data to create/update records.
Named Credential: Used in the validateReq and confirmReq callouts to securely call Oracle’s API. The callout:Oracle_Callback syntax references the Named Credential, eliminating the need to hardcode endpoints or credentials.
Step 5: Configure Named Credential
When to Use: In this inbound integration, a Named Credential is used for outbound callouts from Salesforce to Oracle, such as:
Validating the oracleCustomerId before processing the request.
Sending a confirmation to Oracle after processing.
Setup Steps:
Go to Setup > Security > Named Credentials > New.
Label: Oracle_Callback
Name: Oracle_Callback
URL: Oracle’s base API endpoint (e.g., https://oracle-erp.com/api).
Identity Type: Named Principal.
Authentication Protocol: OAuth 2.0 (preferred) or Password Authentication.
Details: Enter Client ID, Client Secret, or username/password (provided by Oracle).
Allow Merge Fields in HTTP Body: Enable for dynamic payloads.
In Apex: Reference the Named Credential with callout:Oracle_Callback, as shown in the code (e.g., callout:Oracle_Callback/validateCustomer).
When Not Needed: If Salesforce only processes Oracle’s incoming request without calling Oracle, skip the Named Credential.
Step 6: Expose the REST Endpoint
Endpoint URL: https://yourInstance.salesforce.com/services/apexrest/oracle/customer/update/
Authentication: Oracle must use OAuth 2.0 (preferred) or username/password with security token.
OAuth Example:
POST /services/oauth2/token Host: login.salesforce.com Content-Type: application/x-www-form-urlencoded grant_type=client_credentials&client_id=<Client_ID>&client_secret=<Client_Secret>Response provides an access_token for the Authorization header.
Share the endpoint URL, Client ID, Client Secret, and authentication instructions with the Oracle team.
Step 7: Test the Integration
Prepare Test Data:
Create a Customer__c record with Oracle_Customer_ID__c = "CUST123".
Add sample Order__c and Address__c records.
Simulate Oracle’s Request:
Use Postman to send a POST request:
POST /services/apexrest/oracle/customer/update/Host: yourInstance.salesforce.comAuthorization: Bearer <access_token>Content-Type: application/json{"oracleCustomerId": "CUST123","name": "John Smith","email": "john@example.com","status": "Completed","orders": [{ "orderId": "ORD001", "orderDate": "2024-04-01", "amount": 100 },{ "orderId": "ORD002", "orderDate": "2024-04-02", "amount": 150 }],"addresses": [{ "street": "Main St", "city": "Mumbai", "state": "MH", "zipCode": "400001", "country": "India" }]}
Verify Results:
Confirm Customer__c, Order__c, and Address__c records are updated.
Check Integration_Log__c for:
Request_Body__c: JSON from Oracle.
Response_Body__c: Success or error message, including callback response.
Status_Code__c: 200 or 500.
Success__c: True or False.
Verify the callback to Oracle (check Oracle logs or ask the Oracle team).
Test Edge Cases:
Send invalid JSON (e.g., missing oracleCustomerId).
Simulate a failed callback response from Oracle.
Step 8: Monitor and Debug
Integration_Log__c: Review logs for errors or failed requests.
Debug Logs: Enable for the integration user to troubleshoot Apex issues.
API Usage: Monitor via Setup > Integrations > API Usage to stay within limits.
Best Practices
Clear Comments: Use detailed comments in Apex to explain annotations like @RestResource and @HttpPost, making the code self-documenting.
Secure Callouts: Use Named Credentials for all outbound calls to Oracle to avoid hardcoding credentials.
Error Handling: Log all errors in Integration_Log__c and return meaningful responses to Oracle.
Data Validation: Validate incoming JSON and use External IDs to prevent duplicates.
Testing: Test in a sandbox with various scenarios (valid/invalid data, callback failures).
Compliance: Ensure data handling complies with GDPR, CCPA, or other regulations.
JSON Payload Explained
Oracle’s JSON payload:
{"oracleCustomerId": "CUST123","name": "John Smith","email": "john@example.com","status": "Completed","orders": [{ "orderId": "ORD001", "orderDate": "2024-04-01", "amount": 100 },{ "orderId": "ORD002", "orderDate": "2024-04-02", "amount": 150 }],"addresses": [{ "street": "Main St", "city": "Mumbai", "state": "MH", "zipCode": "400001","country": "India" }]}
Conclusion
This Oracle-to-Salesforce inbound REST API integration enables Oracle to update Salesforce records seamlessly. The Apex REST service, with clear comments on @RestResource and @HttpPost, processes incoming data and logs transactions. Named Credentials simplify secure outbound callouts to Oracle for validation or confirmation. Test thoroughly in a sandbox and collaborate with the Oracle team to ensure smooth integration.
Explore Salesforce REST API Documentation and Oracle REST API Documentation for more details. Try deploying the Apex service and share your results!
Thank you for exploring
I hope this guide provided valuable insights into real-time inbound REST API integration connections.
For a better experience, I recommend viewing this blog on a desktop, as the mobile version is still being optimized.
Your feedback and thoughts mean a lot—please share your comments below.
Happy integrating!
Blog by Yeshwanth

Comments