You are here:
Configure Delivery Estimation for a B2C Store
Connect the Commerce Delivery Service to your B2C store and implement the delivery estimation service for checkout. Use this section as a guideline only. Your configuration may differ.
Required Editions
-
Add a role, instance, and scope.
- In Commerce Account Manager, select Account Manager | API Client.
- Add the Salesforce Commerce API role and its associated instances.
- Add the sfcc.commercedeliveryservice.shopper allowed scope.
-
In Business Manager, create custom product line attributes.
- Log in to Business Manager with Administrative privileges.
- Go to Administration | Site Development | System Object Types, and select ProductLineItem.
-
On the Attribute Definitions tab, click New and
create these attributes.
Attributes Value EarliestEstimatedDeliveryDateTime Type Date+Time LatestEstimatedDeliveryDateTime Type Date+Time EstimatedDeliveryReference Type String
-
(Optional) Add the product line attributes to a group.
- On the Attribute Grouping tab, add a group named Commerce Delivery Service.
-
Edit the group, and add the attributes that you created.
Attributes Value EarliestEstimatedDeliveryDateTime Type Date+Time LatestEstimatedDeliveryDateTime Type Date+Time EstimatedDeliveryReference Type String
-
(Optional) Create custom site attributes.
- In Business Manager, select Administration | Site Development | System Object Types | SitePreferences.
-
On the Attribute Definitions tab, click New and
create these attributes.
Attributes Value accountManager Value Type: Enum of Strings
Value = account.demandware.com
Display Value = Prod
cdsClientId Value Type: String
The UUID in Account Manager
cdsPassword Value Type: String
Password associated with your UUID/ClientID
realmInstanceId Value Type: String
Realm_instance identifier
-
(Optional) Set custom site preferences.
- In Business Manager, select Merchant Tools | Site Preferences | Custom Preferences.
- For Commerce Delivery Service, click ID Link.
-
Enter these properties, and then click
Save.
Attributes Value cdsClientId Find in Account Manager. cdsPassword Password associated with the UUID/ClientID. RealmInstanceId To find, go to Administration | Global Preferences | Salesforce Order Management Integration Administration.
-
(Optional) Call Account Manager to receive the correct bearer token. Use the
token in the request that calls the Commerce Delivery Service.
function callAccountManager() { var sitePrefs : SitePreferences = dw.system.Site.getCurrent().getPreferences(); var realmInstanceId : String = sitePrefs.getCustom()["realmInstanceId"]; var clientId : String = sitePrefs.getCustom()["cdsClientId"]; var password : String = sitePrefs.getCustom()["cdsPassword"]; var url : String = sitePrefs.getCustom()["accountManager"]; var wholeUrl : String = 'https://'+ url + '/dw/oauth2/access_token?grant_type=client_credentials&scope=SALESFORCE_COMMERCE_API%3A'+realmInstanceId+'%20sfcc.commercedeliveryservice.shopper'; var httpClient : HTTPClient = new HTTPClient(); var message : String; httpClient.open('POST', wholeUrl,''+ clientId + '',''+ password +''); httpClient.setRequestHeader('Accept','application/json'); httpClient.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); httpClient.setTimeout(3000); httpClient.send(); if (httpClient.statusCode == 200) { message = httpClient.text; } else { // error handling message="An error occurred with status code "+httpClient.text; } return JSON.parse(message).access_token; } -
Create a request to use in the body for the call to the CDS Service.
-
Create a request function.
function createCdsRequest(applicableShippingMethods, products) { var siteName: String = dw.system.Site.getCurrent().name; let jsonObj = {}; jsonObj.deliveryEstimationSetupName = dw.system.Site.getCurrent().name; jsonObj.shippingCarrier.methods = []; jsonObj.products = []; jsonObj.deliveryAddress = {}; for (var i = 0; i < products.length; i++) { jsonObj.products.push({}); jsonObj.products[i]['stockKeepingUnit'] = products[i].productID; jsonObj.products[i]['quantity'] = products[i].quantityValue; } jsonObj.deliveryAddress.country = request.httpParameterMap.countryCode.stringValue; jsonObj.deliveryAddress.state = request.httpParameterMap.stateCode.stringValue; jsonObj.deliveryAddress.postalCode = request.httpParameterMap.postalCode.stringValue; jsonObj.deliveryAddress.city = request.httpParameterMap.city.stringValue; for (i = 0; i < applicableShippingMethods.length; i++) { jsonObj.shippingCarrier.methods.push({}); jsonObj.shippingCarrier.methods[i]['name'] = applicableShippingMethods[i].ID; } return jsonObj; } -
Call your request function.
applicableShippingMethods = cart.getApplicableShippingMethods(address); products = cart.getProductLineItems(); ... createCdsRequest(applicableShippingMethods, products)
-
Create a request function.
-
(Optional) Use the dates and reference numbers in the storefront. Call the CDS
Service to pull the response and use the dates and reference numbers in the
storefront.
function callCdsService(bearer, request) { var httpClient: HTTPClient = new HTTPClient(); var message: String; var sitePrefs: SitePreferences = dw.system.Site.getCurrent().getPreferences(); var realmInstanceId: String = sitePrefs.getCustom()["realmInstanceId"]; httpClient.open('POST', 'https://api.salesforce.com/commerce/delivery/v1/estimate/delivery-date'); httpClient.setRequestHeader('Authorization', 'Bearer ' + bearer + ''); httpClient.setRequestHeader('Accept', '*/*'); httpClient.setRequestHeader('Content-Type', 'application/json'); httpClient.setRequestHeader('Accept-Encoding', 'gzip, deflate, br'); httpClient.setRequestHeader('Connection', 'keep-alive'); httpClient.setRequestHeader('Correlation-ID', '12345'); httpClient.setRequestHeader('SALESFORCE_COMMERCE_API', '' + realmInstanceId + ''); httpClient.setRequestHeader('x-salesforce-region', 'us-east-2'); httpClient.setTimeout(5000); httpClient.setBody(payload); httpClient.send(request); if (httpClient.statusCode == 200) { message = httpClient.text; } else { // error handling message = "An error occurred with status code " + httpClient.errorText; } return message; }Sample request
These fields are mandatory: methods, name, products, stockKeepingUnit.
{ “deliveryEstimationSetupName”: “{externalName}”, "shippingCarrier": { "name": "FEDEX", "methods": [ { "name": "GROUND" } ] }, "products": [ { "stockKeepingUnit": "PROD123", "quantity": 3, } ], "deliveryAddress": { "country": "USA", "state": "WA", "city": "Seattle", "postalCode": "98108", "latitude": 25.191274, "longitude": -80.13145 }, "excludedLocations": [ "US-EAST", "US-WEST" ] }Sample response
{ "estimatedDeliveryReference": "e40cf167-dbd7-11ee-ae25-f1239303df20", "deliveryEstimates": [{ "shippingCarrierMethod": "Ground", "productDeliverEstimations": [{ "stockKeepingUnit": "1", "quantity": 2, "routingCalculationType": "NONE", "estimatedShipDate": { "type": "Default", "min": "2024-03-08T13:00:00", "max": "2024-03-08T13:00:00" }, "estimatedDeliveryDate": { "type": "Default", "min": "2024-03-14T13:00:00", "max": "2024-03-17T13:00:00" } }, { "stockKeepingUnit": "2", "quantity": 3, "routingCalculationType": "NONE", "estimatedShipDate": { "type": "Default", "min": "2024-03-08T13:00:00", "max": "2024-03-08T13:00:00" }, "estimatedDeliveryDate": { "type": "Default", "min": "2024-03-14T13:00:00", "max": "2024-03-17T13:00:00" } } ] }, { "shippingCarrierMethod": "2-Day", "productDeliverEstimations": [{ "stockKeepingUnit": "1", "quantity": 2, "routingCalculationType": "NONE", "estimatedShipDate": { "type": "Default", "min": "2024-03-08T13:00:00", "max": "2024-03-08T13:00:00" }, "estimatedDeliveryDate": { "type": "Default", "min": "2024-03-10T13:00:00", "max": "2024-03-12T13:00:00" } }, { "stockKeepingUnit": "2", "quantity": 3, "routingCalculationType": "NONE", "estimatedShipDate": { "type": "Default", "min": "2024-03-08T13:00:00", "max": "2024-03-08T13:00:00" }, "estimatedDeliveryDate": { "type": "Default", "min": "2024-03-10T13:00:00", "max": "2024-03-12T13:00:00" } } ] }, { "shippingCarrierMethod": "Overnight", "productDeliverEstimations": [{ "stockKeepingUnit": "1", "quantity": 2, "routingCalculationType": "NONE", "estimatedShipDate": { "type": "Default", "min": "2024-03-08T13:00:00", "max": "2024-03-08T13:00:00" }, "estimatedDeliveryDate": { "type": "Default", "min": "2024-03-08T13:00:00", "max": "2024-03-09T13:00:00" } }, { "stockKeepingUnit": "2", "quantity": 3, "routingCalculationType": "NONE", "estimatedShipDate": { "type": "Default", "min": "2024-03-08T13:00:00", "max": "2024-03-08T13:00:00" }, "estimatedDeliveryDate": { "type": "Default", "min": "2024-03-08T13:00:00", "max": "2024-03-09T13:00:00" } } ] } ] }Sample parse through response
// Create two maps, min and max var maxDate = new Map(); var minDate = new Map(); ... // Apply response values to display when seeing all Shipping Methods in the order for (i = 0; i < JSON.parse(response).deliveryEstimates.length; i++) { if (JSON.parse(response).deliveryEstimates[i].shippingCarrierMethod == applicableShippingMethods[i].ID) { minDate.set(JSON.parse(response).deliveryEstimates[i].shippingCarrierMethod, new Date(Date.parse(JSON.parse(response).deliveryEstimates[i].productDeliverEstimations[0].estimatedDeliveryDate.min)).toLocaleDateString()); maxDate.set(JSON.parse(response).deliveryEstimates[i].shippingCarrierMethod, new Date(Date.parse(JSON.parse(response).deliveryEstimates[i].productDeliverEstimations[0].estimatedDeliveryDate.max)).toLocaleDateString()); } } ... // Apply response values to each Product Line Item (OrderItem) for (var i = 0; i < JSON.parse(response).deliveryEstimates.length; i++) { if (JSON.parse(response).deliveryEstimates[i].shippingCarrierMethod == cart.getDefaultShipment().getShippingMethod().ID) { for (var c = 0; c < cart.object.productLineItems.length; c++) { cart.object.productLineItems[c].custom.EstimatedDeliveryReference = JSON.parse(response).estimatedDeliveryReference; cart.object.productLineItems[c].custom.EarliestEstimatedDeliveryDateTime = new Date(Date.parse(JSON.parse(response).deliveryEstimates[i].productDeliverEstimations[0].estimatedDeliveryDate.min)); cart.object.productLineItems[c].custom.LatestEstimatedDeliveryDateTime = new Date(Date.parse(JSON.parse(response).deliveryEstimates[i].productDeliverEstimations[0].estimatedDeliveryDate.max)); } } } -
(Optional) Update any .isml pages to use the values returned in the response
from the Commerce Delivery Service.
In this example, to display the dates, minimum and maximum dates are placed in a new Map() and then displayed based on the shipping method.
<isif condition = "${!empty(shippingMethod.description)}" > <div class = "form-caption" > Delivery Estimation: $ { pdict.MinDate.get(shippingMethod.ID)} - $ { pdict.MaxDate.get(shippingMethod.ID)} < /div> </isif>

