Salesforce → ERP¶
This is the call ERP receives when Salesforce created the Ship To. The sample is Whitefield Warehouse under Sharma Distributors.
ShipTo_AfterSave calls ErpOutboundSyncInvocable with integration Ship_To_Sync only after ShipToCodeGenerator returns Success. That is an Internal insert that is already Active, or a Community record whose status just changed from Pending Approval to Active, and whose Ship_To_Code__c was blank. Bypass_Automation__c.Is_Bypassed__c true skips the flow. A record ERP itself created (Origin__c = ERP) is not posted back on this path.
POST /webhook/ship-to¶
Timeout 15000 ms. Log_Operation__c is Create. Max_Retries__c is 3 and Retry_Policy__c is PendingUntilSynced. That policy does not chain another queueable after a failed callout, and Sync_Status_Field__c is blank, so the Ship To record itself is not stamped Pending, Synced, or Failed. The integration log is Synced on any HTTP status from 200 to 299, and Pending when the call fails. There is no response mapping, so shipToCode and status in the body below are not written back onto Ship_To__c. The code is already on the record.
What Salesforce sends¶
Address keys are flat. Every mapping is active, direction blank (so it is sent and not read from the response), and data type String.
{
"salesforceRecordId": "a0S000000000001AAA",
"soldToCode": "DIST001",
"shipToCode": "DIST001_1",
"shipToName": "Whitefield Warehouse",
"shippingStreet": "Plot 7, EPIP Zone",
"shippingCity": "Bengaluru",
"shippingState": "Karnataka",
"shippingPincode": "560066",
"gstRegistrationNumber": "29ABCDE1234F1Z5",
"contactPerson": "Meena Rao",
"contactPhone": "9900112233",
"origin": "Internal"
}
| Sort | Mapping | JSON key | Salesforce field | Where ERP stores it |
|---|---|---|---|---|
| 10 | Ship_To_Sync_SF_Id |
salesforceRecordId |
Id |
salesforceRecordId. Required |
| 20 | Ship_To_Sync_Sold_To |
soldToCode |
Sold_To__r.Sold_To_Code__c |
soldToCode. Required. Must already be a Sold To in ERP |
| 30 | Ship_To_Sync_Ship_To_Code |
shipToCode |
Ship_To_Code__c |
shipToCode, stored as sent. Required |
| 40 | Ship_To_Sync_Name |
shipToName |
Ship_To_Name__c |
shipToName. Required |
| 50 | Ship_To_Sync_Street |
shippingStreet |
Shipping_Street__c |
street |
| 60 | Ship_To_Sync_City |
shippingCity |
Shipping_City__c |
city |
| 70 | Ship_To_Sync_State |
shippingState |
Shipping_State__c |
state, stored as sent |
| 80 | Ship_To_Sync_Pincode |
shippingPincode |
Shipping_Pincode__c |
pincode. Must be 6 digits |
| 90 | Ship_To_Sync_GST |
gstRegistrationNumber |
GST_Registration_Number__c |
GSTIN, uppercased. Not checked as a GSTIN |
| 100 | Ship_To_Sync_Contact_Person |
contactPerson |
Contact_Person__c |
contact person |
| 110 | Ship_To_Sync_Contact_Phone |
contactPhone |
Contact_Phone__c |
10 digits when present. Blank is allowed |
| 120 | Ship_To_Sync_Origin |
origin |
Origin__c |
not stored from this key |
ERP also accepts a nested shippingAddress object (street, city, state, pincode). A nested street wins over shippingStreet. Salesforce does not send the nested object.
origin in the example is Internal. A Community approval sends Community. ERP stores the row origin as Salesforce either way.
What ERP does¶
- Reject a body that is not JSON.
- Require
salesforceRecordId,soldToCode, andshipToCode. - Require a name and a 6-digit pincode. A contact phone, when present, must be 10 digits. Street, city, state, and GSTIN may be blank.
- If this Salesforce Id is already stored, update the name, address, GSTIN, and contact on that row and return the code already stored. The code, the Sold To, and the origin are left as they were.
- Otherwise require a Sold To
DIST001in ERP, then insert the Ship To with status Active, sync status Synced, and the Salesforce Id already filled.
The inbound log reference is ship-to inbound sfId=a0S000000000001AAA soldTo=DIST001 code=DIST001_1. A repeat appends (idempotent, code=DIST001_1).
What ERP sends back¶
HTTP 200
The same body is returned for a first insert and for a repeat of the same Salesforce Id.
Errors¶
| HTTP | error |
message |
|---|---|---|
| 400 | invalid_json |
invalid request body |
| 400 | validation_error |
salesforceRecordId is required |
| 400 | validation_error |
soldToCode is required |
| 400 | validation_error |
shipToCode is required |
| 400 | validation_error |
ship to name is required |
| 404 | not_found |
sold to account not found |
| 422 | unprocessable_entity |
pincode must be exactly 6 digits |
| 422 | unprocessable_entity |
contact phone must be exactly 10 digits |
| 500 | internal_error |
internal error: ... |
A 400 or 422 inserts nothing. A 404 means DIST001 is not in this ERP database.