Extensibility via Hooks

Many Shopper API resources are extensible through hooks. With hooks, you can augment server-side logic with your own eCom-based script code. Hooks are available on any resources that perform a modification on the server-side, such as the Customer and Basket resources.

For more information on eCom-based script code, refer to the following B2C Commerce documentation:

Hooks are used by developers to enrich the server-side system logic with their custom B2C Commerce script code. Each customizable resource provides before, after, and modifyResponse extension points. Use the before and after extension points to execute custom code before or after the server performs its processing, respectively. Use the modifyResponse extension point to apply final changes to the response document. In addition, some special convenience hooks allow you to perform actions like basket calculations or special checkout steps. These convenience hooks let you place your basket-calculation code in a single place, instead of including duplicate code in multiple after extension points.

  • before<HTTP_Method>
  • after<HTTP_Method>
  • modify<HTTP_Method>Response

Available Hooks

GET Requests support before-Hooks and modifyResponse-Hooks. POST, PATCH, PUT, and DELETE Hooks additionally support after-Hooks. The latter also writes transactions to the database accordingly.

Typical use cases are:

  • before-Hooks: define additional filter criteria for the API execution, and perform certain status checks before a PATCH request.
  • after-Hooks: add information after the service logic to indicate how to finalize the step (such as, setting status for a payment method), integrate with third-party systems (such as, order placements).
  • modifyResponse-Hooks: extend result sets with additional information to an object (for example, additional product detail information), and cleanup result sets of unwanted properties.

Hooks are available for all commerce areas such as Basket, Order, Product, Catalog, Customer, Pricing & Promotion, and Search.

As new SCAPI endpoints are created, we provide hooks to allow customization (for example, hooks for merge and transfer basket endpoints).

See the applicable Hooks-to-SCAPI-endpoints in the Hook List.

To use hooks for Commerce API you must enable the feature in Business Manager for every eCom instance you want to use it with. Navigate to Administration > Global Preferences > Feature Switches and check the Enable Salesforce Commerce Cloud API hook execution feature switch.

In order to set the feature switch, you must have the Account Manager role of “Business Manager Administrator” configured for the instance assigned to your Account Manager user profile.

Feature Switches

  1. Place a package.json file in the top-level directory of your script cartridge.
  2. In the package.json file, define the hooks property to the path of the hooks.json configuration file. This path is relative to the directory containing the package.json file.
  3. In the hooks.json file, configure an array with the mappings of hooks to their script files.

    The paths are relative to the directory where the hooks.json file is located.

  4. For site-specific use, register your cartridge to each appropriate site in Business Manager. To customize organization-level resources across all sites, such as libraries, you must register the cartridge to the Business Manager site at the organizational level.

A hook script is loaded as a CommonJS module. All hook functions must be exported. The exported name must match the name of the extension point function, without the package qualification. For example, the dw.ocapi.shop.basket.billing_address.beforePUT extension point is exported as beforePUT:

Using hooks with the Salesforce Commerce API is similar to using hooks with OCAPI, but there are differences developers must be aware of. When you enable and maintain hooks, you must be aware that the same hooks are called for both SCAPI and the related OCAPI endpoints. This is important if you use both API frameworks for your client applications.

Hooks enabled for SCAPI still run under the timeout definition of the SCAPI endpoint. The amount of time that your hook takes to run adds to the overall processing time and the entire response, with the hook execution, and must still complete within the timeout period.

All Shopper APIs have a timeout of 10 seconds, except the Shopper-Products endpoint that has a timeout of 30 seconds.

One of the benefits of SCAPI is its contract-based API definition. It makes responses from SCAPI predictable, able to be documented, and the ability to put an SDK in use for them. (Yes... the SDKs still work with hooks!)

modifyResponse hooks are a powerful way to create a response that best fits the needs of the application. You can add additional information to objects, or provide a more UI-friendly property set to improve the consumption on the client application. However, any changes to the response must fit in the API contract that has been established.

Keep the following in mind when dealing with modifyResponse hooks:

  • Additional properties must be added only as custom properties (c_ properties).
  • Other modifications (deletion or changing of a property) must only occur within the boundaries of the API contract.

With the hooks enabled for SCAPI, the basket calculations built into the B2C Commerce backend are now in play for determining the basket information. There are endpoints created specifically for SCAPI (without hooks) that allowed the manipulation of tax information on the basket.

  • /checkout/baskets/{}/taxes
  • /checkout/orders/{}/taxes
  • /checkout/baskets/{}/items/{}/taxes
  • /checkout/baskets/{basketId}/price-books

These endpoints no longer work with the hooks enabled. Calling these endpoints result in a 409 error response from the request.

When writing your hook logic, it’s important to keep in mind the context of the API that is calling the hook. Both OCAPI and SCAPI share the same hooks, so it’s possible to write a hook that is used for both. Use request.isSCAPI() to determine SCAPI or OCAPI usage, especially if you’re already using the calculate hook in the context of controllers and use transactions in that hook, as that breaks SCAPI. Direct access to the _sfdc_mercury HTTP header is deprecated.

As SCAPI is governed by its API contract, sending a custom query string in the URL causes SCAPI to reject the request. In a similar fashion, any HTTP header values that are sent that SCAPI is not expecting are not forwarded to the B2C Commerce backend, and they aren’t available in the hook code.

In the past, developers have often used custom headers or query strings to control the behavior in their hook code. With these restrictions, we recommend using other mechanisms of control, such as custom properties.

If a hook errors during processing, the request will fail. You can track hook errors with Log Center. Configure a search using the LCQL query category: ( com.demandware.wapi.servlet.ShopRestServlet ) AND stackTrace: ( HookInvocationException ).

As a result of many projects with customers, our community is maintaining a hook collection with many useful implementations to extend functionality or even provide new functionality. The hooks in the community collection cover a wide range of practical use cases. SCAPI supported hooks in the collection are:

  • Order-Hooks
  • OrderPaymentInstruments-Hooks
  • Search-Hooks
  • Basket-Hooks
  • BasketPayments-Hooks

For more information, check out the OCAPI Hooks Collection on the Salesforce Commerce Cloud GitHub repository.

The OCAPI Hooks Collection GitHub repository isn’t open source. It’s part of a private collection of repositories for Salesforce Commerce Cloud customers. If you’re unable to access the repository, refer to the Salesforce Commerce Cloud GitHub Repositories and Access documentation in the Salesforce B2C Commerce Infocenter.