Clearing Hybris Orders
Context
We are going to deploy the new Checkout project iteratively by market or groups of markets, starting with Ireland. Users will shop and add to their basket using the Hybris storefront. When a user in Ireland moves from their basket to the checkout we will redirect them to the new Commerce Layer checkout. All other users will remain on the Hybris checkout. At the point at which the user is redirected, a cart (a draft order) will be created for the user in Commerce Layer. When the user completes the checkout in Commerce Layer and their order status is updated to "placed" we need to delete the cart in Hybris.
Decision
We will do this using Commerce Layer Webhooks and AWS middleware. The Commerce Layer webhooks allow us to react to specific events in real-time. We can set up a webhook in Commerce Layer to make a request to an API Gateway each time an order status changes to "placed" using the orders.placed topic.
The Commerce Layer documentation recommends verifying the webhook callback authenticity by signing the payload with the shared secret (SHA256 HMAC) that is automatically generated when the webhook is created, and comparing the result with the X-CommerceLayer-Signature callback header. To do this we have created a private package, allowing the authorization code to be shared with other services that will send or receive data from Commerce Layer in future. See the consequences and limitations section for more information on different options that were considered.
- An
orders.placedevent occurs in Commerce Layer - A POST request is sent to the /order/notifications endpoint in the Hybris API Gateway
- The request is integrated with the Hybris Order Delete Lambda, which is then executed
- The Lambda uses the common Commerce Layer Authorizer package to verify the authenticity of the request
- The Lambda makes a request to Hybris to delete the cart
Consequences and limitations
- For this solution to work we need to save the Hybris cart number in the order metadata in Commerce Layer when we create the cart. We will save this to
hybris_cart_id.
For the authorization of the webhook callbacks we considered a number of different options but found challenges with each:
- Lambda authorizer on API Gateway - this prevents the order-delete Lambda from being executed if the callback cannot be verified. We couldn't use this option because the request body is not passed into the Lambda authorizer, and there is no way to customise this to pass it in. We need both the headers and the body of the original request in order to complete the validation of the request.
- Lambda@edge on API Gateway - this allows you to pass in the request body, but Lambda@edge are intended for slightly different usecases. You cannot pass environment variables to Lambda@edge, which does not work for us since we need to save and use the shared secret to sign the request body with.
- Implement authorization code directly in the order-delete Lambda - this code is going to be reused any time we set up a new webhook with Commerce Layer, so we needed a solution that was going to allow this code to be shared.