BasketMergeHooks
CalculateHooks
CheckoutHooks
OrderHooks
PaymentHooks
ReturnHooks
ShippingHooks
ShippingOrderHooks
TaxHooks
DID THIS ARTICLE SOLVE YOUR ISSUE?
Let us know so we can improve!
Let us know so we can improve!
This interface represents shipping extension points for Commerce App shipping providers.
These hooks provide integration points for external shipping rate / delivery-estimate services installed via the Commerce App framework.
IMPORTANT: These hooks should only be implemented and registered by Commerce Apps
(applications installed via the Commerce App framework with a CAP file). They are not intended for custom merchant
cartridges or storefront implementations. Merchants who want custom shipping calculation logic should use the legacy
dw.order.calculateShipping extension point instead.
Hook Registration A function must be defined inside a JavaScript source and must be exported. The script
with the exported hook function must be located inside a site cartridge. Inside the site cartridge a
package.json file with a ‘hooks’ entry must exist:
1"hooks": "./hooks.json"The hooks entry links to a JSON file, relative to the package.json file. This file lists all registered
hooks inside the hooks property:
1"hooks": [
2 {"name": "sfcc.app.shipping.quote", "script": "./quote.js"},
3 {"name": "sfcc.app.shipping.calculate", "script": "./calculate.js"}
4]A hook entry has a name and a script property:
namecontains the extension point name (the hook name).scriptcontains the script path relative to the hooks file, with the exported hook function.Function Naming Convention: The exported JavaScript function name must match the last segment of the
extension point name, for example, quote or calculate.
Hook Lifecycle Each hook fires at a specific surface and lifecycle stage:
GET /baskets/{basket_id}/shipments/{shipment_id}/shipping_methods. Lets the Commerce App override native shipping prices and add delivery information for the methods it can quote.ShippingLineItemand may persist provider metadata on the shipment.Hook Precedence
sfcc.app.shipping.calculateis registered and the ShippingAppHooksEnabledtoggle is on, it takes precedence over the legacy dw.order.calculateShippinghook.dw.order.calculateShipping(if registered).ShippingMgr.applyShippingCost).| Constant | Description |
|---|---|
| SHIPPING_DOMAIN: String = “shipping” | The shipping app domain segment used to compose extension-point names under the shared sfcc.app prefix. |
| extensionPointCalculate: String = “sfcc.app.shipping.calculate” | The extension point name sfcc.app.shipping.calculate. |
| extensionPointQuote: String = “sfcc.app.shipping.quote” | The extension point name sfcc.app.shipping.quote. |
This class does not have a constructor, so you cannot create it directly.
| Method | Description |
|---|---|
| calculate(LineItemCtnr) | The function is called by extension point extensionPointCalculate during basket calculation. |
| quote(Shipment, ShippingMethodResultWO) | The function is called by extension point extensionPointQuote on every invocation of GET /baskets/{basket_id}/shipments/{shipment_id}/shipping_methods. |
assign, create, create, defineProperties, defineProperty, entries, freeze, fromEntries, getOwnPropertyDescriptor, getOwnPropertyNames, getOwnPropertySymbols, getPrototypeOf, hasOwnProperty, is, isExtensible, isFrozen, isPrototypeOf, isSealed, keys, preventExtensions, propertyIsEnumerable, seal, setPrototypeOf, toLocaleString, toString, valueOf, values
The shipping app domain segment used to compose extension-point names under the shared
sfcc.app prefix.
The extension point name sfcc.app.shipping.calculate.
The extension point name sfcc.app.shipping.quote.
The function is called by extension point extensionPointCalculate during basket calculation. It
applies provider-supplied shipping rates to the selected ShippingLineItem and may persist
provider metadata (for example, a rate id, carrier code, or delivery window) on the shipment via supported
custom.* attributes. This hook fires on every basket operation that recomputes shipping, not only
before order creation.
The hook owns: native fallback (calling ShippingMgr.applyShippingCost(lineItemCtnr) if it wants to
preserve product-level shipping, surcharges, cleanup, and tax-class setup), provider lookup / rate-cache reuse,
selected-rate application onto the standard shipment shipping line item, and provider metadata persistence
(custom attributes on the shipment, custom objects, etc.).
Note: If the master dw.order.calculate hook (not the per-step
dw.order.calculateShipping) is overridden, the entire basket calculation is replaced and the
platform's automatic shipping hook selection is bypassed. You must manually invoke this hook from within your
custom dw.order.calculate implementation if you want to use Commerce App shipping providers.
Error Handling: Both returning a Status.ERROR and throwing an exception will
prevent the basket calculation from completing successfully. The platform logs the error and halts the current
basket operation. Since order creation requires a successful basket calculation, this also prevents orders from
being created with incorrect shipping amounts.
Sample Implementation:
1function calculate(lineItemCtnr) {
2 var ShippingMgr = require('dw/order/ShippingMgr');
3 var Status = require('dw/system/Status');
4 var Transaction = require('dw/system/Transaction');
5
6 // 1. Run native shipping defaults (product-level surcharges, tax classes)
7 ShippingMgr.applyShippingCost(lineItemCtnr);
8
9 // 2. Look up the provider rate that was selected on the shipment
10 var shipment = lineItemCtnr.getDefaultShipment();
11 var rateId = shipment.custom.providerRateId;
12 if (!rateId) {
13 return new Status(Status.OK);
14 }
15
16 // 3. Apply the provider rate to the shipping line item
17 Transaction.wrap(function () {
18 var sli = shipment.getStandardShippingLineItem();
19 sli.setPriceValue(lookupRate(rateId).price);
20 });
21
22 return new Status(Status.OK);
23}
24
25exports.calculate = calculate;Parameters:
Returns:
Status.OK or null for success; Status.ERROR to block the basket
calculation with details about the failure. Throwing an exception will also block the basket
calculation.The function is called by extension point extensionPointQuote on every invocation of
GET /baskets/{basket_id}/shipments/{shipment_id}/shipping_methods. ECOM pre-populates a
ShippingMethodResultWO with the applicable shipping methods, each carrying its native price. The
hook implementation may override prices and delivery information on any methods it can quote. Methods the hook
does not touch keep their native price.
Error Handling: To signal a failure, return new Status(Status.ERROR). The platform
logs that an error status was returned for this hook and the GET shipping-methods request fails.
Uncaught exceptions thrown from the hook are also treated as failures.
SCAPI Behavior: When ScapiHookExecutionEnabled is disabled, SCAPI requests bypass
this hook and use native shipping pricing.
Sample Implementation:
1function quote(shipment, result) {
2 var Status = require('dw/system/Status');
3
4 var methods = result.applicableShippingMethods;
5 for (var i = 0; i < methods.length; i++) {
6 var method = methods[i];
7 // ... call provider for this method, set price ...
8 method.setPrice(providerPrice);
9 }
10 return new Status(Status.OK);
11}
12
13exports.quote = quote;Parameters:
Returns:
Status.OK or null for success; Status.ERROR to block the request.