Reserve stock on Cart

Learn how to prevent overselling and improve the checkout experience by automatically reserving items in a Cart.

Ask about this Page
Copy for LLM
View as Markdown
This tutorial uses Inventory reservations functionality that is in public beta.

In this tutorial, you will learn how to temporarily reserve products for a customer, giving them time to complete their checkout. By the end, you will have created a Cart with reserved Line Items and will understand how to manage these reservations.

You will learn to:

  • Create a Cart that automatically reserves items.
  • Extend the duration of a reservation.
  • Understand and handle different reservation-related warnings.

Prerequisites

Before you begin, you should be familiar with:

You should also have a commercetools Project with the following:
  • A Product: Create a Product with at least one Product Variant. Note the SKU of the variant.
  • API Client: An API Client with the following scopes:
    • manage_orders:{projectKey} to create and update Carts and Orders.
    • manage_project_settings:{projectKey} to update reservation-related Project settings.
    • manage_products:{projectKey} to create and update Inventory Entries.

Instructions

The following instructions walk through creating and managing stock reservations. The scenario follows a customer who adds a popular, limited-stock item to their cart. To ensure they have a chance to purchase it, the item is reserved for them for a limited time.

Set the Project-level expiration

Before you can use reservations, you must set the Project-level reservation expiration time. After you set this default, you'll be able to use the ReserveOnCart InventoryMode, which automatically reserves Line Items when they are added to the Cart.

This is a mandatory step to ensure that stock is not held indefinitely, which could lead to it being unavailable for other customers. You only have to set this once per Project.

To do this, use the Set Reservation Expiration in Minutes update action on the Project and specify a value between 1 and 44640 minutes (31 days).

This value will be the fallback for any inventory entry that doesn't have a specific expiration set.

The next section covers how to create a reservation and override the Project-level reservation expiration time for individual SKUs.

Create a reservation

First, create a Cart with a product to be reserved.

Create an Inventory Entry

Ensure you have an Inventory Entry for your Product Variant (SKU-1 in this example) with stock available. In this example, reservationExpirationInMinutes is set to 30 minutes. If you omit this value, the Project-level default will be used.
Both the Project-level and InventoryEntry-level reservationExpirationInMinutes values must be at least 1 minute and at most 44640 minutes (31 days).
Create an Inventory Entry for SKU-1bash
curl -X POST "https://api.europe-west1.gcp.commercetools.com/{{project-key}}/inventory" \
-H "Authorization: Bearer {{auth-token}}" \
-H "Content-Type: application/json" \
-d '{
    "sku": "SKU-1",
    "quantityOnStock": 10,
    "reservationExpirationInMinutes": 30
}'

Create a Cart

Now, create a Cart that supports reservations, and add the Product. By setting the Cart inventoryMode to ReserveOnCart, you instruct commercetools to create a reservation for all the Line Items in the Cart.
You can specify a different inventoryMode for each Line Item, allowing for mixed reservation behaviors within a single Cart.
Create a Cart with ReserveOnCart inventory modebash
curl -X POST "https://api.europe-west1.gcp.commercetools.com/{{project-key}}/carts" \
-H "Authorization: Bearer {{auth-token}}" \
-H "Content-Type: application/json" \
-d '{
    "currency": "USD",
    "inventoryMode": "ReserveOnCart",
    "lineItems": [
        {
            "sku": "SKU-1",
            "quantity": 1
        }
    ]
}'
After this call, a Cart is created, and a Reservation is automatically created for SKU-1. The reservation expiration time is the same one that was set in the associated Inventory Entry. In this case, the reservation is valid for 30 minutes.
The availableQuantity for this SKU is reduced by 1, while quantityOnStock remains unchanged until the Order is placed. This change is eventually consistent and may take up to 10 seconds to appear. For more details, see Inventory checks and consistency.

Verify the reservation

You can verify that the reservation was successful by checking the response. You will see a reservation field on the Line Item, containing a reference to the created Reservation object. The absence of any warnings is also a good indicator that everything worked as expected.
{
    "lineItems": [
        {
            "id": "...",
            "productId": "...",
            "name": { "...": "..." },
            "variant": { "...": "..." },
            "quantity": 1,
            "reservation": {
                "typeId": "reservation",
                "id": "..."
            }
        }
    ],
    "inventoryMode": "ReserveOnCart",
    "warnings": []
}
As with any reference in the commercetools Platform, you can expand it to get more details about the reservation.

Extend a reservation

Cart interactions can be complex. Payments might fail or additional validation steps can delay checkout. To prevent a reservation from expiring while the customer is completing their purchase, you can extend its duration.

Extend the reservation

Before the reservation expires, you can extend it by sending the Set Reservation Expiration in Minutes update action to the Cart. You will need to provide a new expiration duration in minutes.
Extend the reservation for the Cartbash
curl -X POST "https://api.europe-west1.gcp.commercetools.com/{{project-key}}/carts/{{cart-id}}" \
-H "Authorization: Bearer {{auth-token}}" \
-H "Content-Type: application/json" \
-d '{
    "version": 1,
    "actions": [
        {
            "action": "setReservationExpirationInMinutes",
            "reservationExpirationInMinutes": 30
        }
    ]
}'
This will update the underlying Reservation object, setting its expiration time to 30 minutes from now.
The Set Reservation Expiration in Minutes Cart update action extends all existing reservations for the Cart, meaning all Line Items in the Cart will now expire at the same time.

Verify the extension

From the response, you should see no warnings, indicating the extension was successful. The reservation field remains present. To see the details, you can expand the reservation reference.

Handle reservation warnings

When creating or updating a Cart, a reservation can potentially fail. When this happens, commercetools ensures that the Cart remains orderable by adjusting its contents and provides a warning for each failure.

The behavior depends on whether you are creating or updating a Cart:

  • When creating a Cart, if all Line Items with inventoryMode: "ReserveOnCart" fail to be reserved, the entire operation fails with a 400 Bad Request (InvalidOperation) error. If only some items fail, the Cart is created, but the failed Line Items are removed from it and mentioned in a warning (see Scenario 1).
  • When updating a Cart, if a reservation update for a Line Item cannot be fulfilled (for example, when increasing its quantity), a warning is added to the response (see Scenario 2) and the quantity is not updated.

In all cases of partial success or adjustment, a warning is added to the response. This gives you the information needed to create the experience you want for your customers, like notifying them about the changes in their Cart.

The following diagram summarizes the different reservation scenarios:

Scenario 1: CannotCreateReservation

This warning is returned when a Line Item with InventoryMode ReserveOnCart is added to a Cart, but the reservation fails due to lack of stock. When this happens, the Line Item is not added to the Cart, ensuring the Cart remains orderable.
To trigger this warning:

Create a Cart with two Line Items. One with a quantity that can be fulfilled, and another with a quantity greater than its availability.

The Cart is created, but only with the Line Items that were successfully reserved. The Cart response will contain a CannotCreateReservationWarning for the failed Line Item.
{
    "warnings": [
        {
            "code": "CannotCreateReservation",
            "message": "Failed to create a reservation for product 987fcdeb-51a2-43d1-9c4f-123456789abc (SKU: SAMPLE-SKU-001, Supply Channel: channel-123) with quantity 5.",
            "productId": "987fcdeb-51a2-43d1-9c4f-123456789abc",
            "sku": "SAMPLE-SKU-001",
            "supplyChannel": "channel-123",
            "quantity": 5
        }
    ]
}
Resolution: The Line Item was not added to the Cart. You should inform the customer that the item could not be added due to insufficient stock and was not reserved for them.

Scenario 2: CannotUpdateReservation

This warning is returned when you update a Line Item's quantity, but the reservation cannot be updated to match the new quantity. This is usually due to insufficient stock. The quantity of the Line Item remains the same.

To trigger this warning:
  1. Ensure SKU-1 has a stock of 5.
  2. Create a Cart with SKU-1, quantity: 2, and inventoryMode: "ReserveOnCart". A reservation for 2 items is created.
    • Available quantity: 5 (initial) - 2 (reserved) = 3
  3. Update the Cart to change the quantity of the Line Item to 6 (that is, adding 4 more items). This requires 4 additional items to be reserved, but only 3 are available. The reservation update fails, and the Line Item quantity in the Cart remains at 2 (the original quantity).
    • Available quantity: 3. Additional items requested: 4. Reservation update fails.
The Cart response will contain a CannotUpdateReservationWarning warning.
{
    "warnings": [
        {
            "code": "CannotUpdateReservation",
            "message": "Failed to update the reservation for line item 123e4567-e89b-12d3-a456-426614174000 (Product ID: 987fcdeb-51a2-43d1-9c4f-123456789abc, SKU: SAMPLE-SKU-001, Supply Channel: channel-123) to a quantity of 6. The reserved amount is still 2.",
            "lineItemId": "123e4567-e89b-12d3-a456-426614174000",
            "requestedQuantity": 6,
            "reservedQuantity": 2,
            "productId": "987fcdeb-51a2-43d1-9c4f-123456789abc",
            "sku": "SAMPLE-SKU-001",
            "supplyChannel": "channel-123"
        }
    ]
}
Resolution: The line item quantity was not updated. You should inform the customer that only part of their desired quantity is reserved.

Scenario 3: CannotChangeReservationExpiry

This warning appears if you try to extend a reservation that has already expired or is in a state that doesn't allow extension.

To trigger this warning:
  1. Use the Set Reservation Expiration In Minutes update action on the Inventory Entry and specify a short duration, for example, 1 minute.
  2. Create a Cart with SKU-1 and inventoryMode: "ReserveOnCart".
  3. Wait for the reservation to expire.
  4. Try to extend the Cart's reservations using the Set Reservation Expiration in Minutes update action on the Cart.
The action succeeds, but the response includes a CannotChangeReservationExpiryWarning warning because the underlying reservation could not be extended.
{
    "warnings": [
        {
            "code": "CannotChangeReservationExpiry",
            "message": "The reservation expiration for line item 448085fc-fe34-484a-8d77-ad6b9148ef59 cannot be changed.",
            "lineItemId": "448085fc-fe34-484a-8d77-ad6b9148ef59"
        }
    ]
}
Resolution: The reservation has expired, and the stock has been released. You should inform the customer that the item is no longer reserved for them. They might need to add it to the Cart again to create a new reservation, provided stock is still available.

Summary

You have learned how to:

  • Use the ReserveOnCart inventory mode to create temporary stock reservations.
  • Extend reservations to give customers more time to check out.
  • Understand and handle warnings related to reservation mismatches and expirations.

This feature helps improve the customer experience for high-demand products by providing a fair window for purchase. When implementing this in a real project, remember to build user-facing notifications for the various warning scenarios to keep your customers informed.

Further reading

To learn more about implementing reservations, see the following resources: