payload icon indicating copy to clipboard operation
payload copied to clipboard

Ecommerce Plugin - Expose manual refreshCart and updateCart in useCart

Open teastudiopl opened this issue 3 months ago • 2 comments

Describe the Bug

I’m currently adding products to the cart by fetch request because the standard addItem method has built-in validation for product uniqueness conflicts with my use case: the same product as new line in cart.

To make this workflow smoother, could you:

Expose a way to manually refresh the cart state, so I can re-sync the UI whenever I modify cart items directly. Provide access to updateCart from useCart - this would allow updating the cart programmatically while keeping the state consistent. This would allow more flexibility for custom cart logic without being blocked by addItem’s uniqueness validation.

Current addItem method:

`const addItem: EcommerceContextType['addItem'] = useCallback( async (item, quantity = 1) => { if (cartID) { const existingCart = await getCart(cartID)

    if (!existingCart) {
      // console.error(`Cart with ID "${cartID}" not found`)

      setCartID(undefined)
      setCart(undefined)
      return
    }

    // Check if the item already exists in the cart
    const existingItemIndex =
      existingCart.items?.findIndex((cartItem: CartItem) => {
        const productID =
          typeof cartItem.product === 'object' ? cartItem.product.id : item.product
        const variantID =
          cartItem.variant && typeof cartItem.variant === 'object'
            ? cartItem.variant.id
            : item.variant

        return (
          productID === item.product &&
          (item.variant && variantID ? variantID === item.variant : true)
        )
      }) ?? -1

    let updatedItems = existingCart.items ? [...existingCart.items] : []

    if (existingItemIndex !== -1) {
      // If the item exists, update its quantity
      updatedItems[existingItemIndex].quantity =
        updatedItems[existingItemIndex].quantity + quantity

      // Update the cart with the new items
      await updateCart(cartID, {
        items: updatedItems,
      })
    } else {
      // If the item does not exist, add it to the cart
      updatedItems = [...(existingCart.items ?? []), { ...item, quantity }]
    }

    // Update the cart with the new items
    await updateCart(cartID, {
      items: updatedItems,
    })
  } else {
    // If no cartID exists, create a new cart
    const newCart = await createCart({ items: [{ ...item, quantity }] })

    setCartID(newCart.id)
    setCart(newCart)
  }
},
[cartID, createCart, getCart, updateCart],

) `

I’ve created a discussion for this here: https://github.com/payloadcms/payload/discussions/14764

Do you know of any alternative approaches so I don’t have to struggle with this workaround?

Link to the code that reproduces this issue

.

Reproduction Steps

Set up a PayloadCMS project with the E-commerce plugin enabled.

Create a product in the Payload admin (or via API) that you want to add multiple times.

Use the standard addItem method from useCart in a React component to add the same product twice:

const { addItem } = useCart(); addItem({ product: 'PRODUCT_ID' }); addItem({ product: 'PRODUCT_ID' }); // Will increment quantity

Observe the behavior:

addItem merges the product quantity instead of adding a new line for the same product.

There is no built-in way to bypass the uniqueness check.

Which area(s) are affected? (Select all that apply)

plugin: ecommerce

Environment Info

.

teastudiopl avatar Nov 29 '25 21:11 teastudiopl

Please add a reproduction in order for us to be able to investigate.

Depending on the quality of reproduction steps, this issue may be closed if no reproduction is provided.

Why was this issue marked with the invalid-reproduction label?

To be able to investigate, we need access to a reproduction to identify what triggered the issue. We prefer a link to a public GitHub repository created with create-payload-app@latest -t blank or a forked/branched version of this repository with tests added (more info in the reproduction-guide).

To make sure the issue is resolved as quickly as possible, please make sure that the reproduction is as minimal as possible. This means that you should remove unnecessary code, files, and dependencies that do not contribute to the issue. Ensure your reproduction does not depend on secrets, 3rd party registries, private dependencies, or any other data that cannot be made public. Avoid a reproduction including a whole monorepo (unless relevant to the issue). The easier it is to reproduce the issue, the quicker we can help.

Please test your reproduction against the latest version of Payload to make sure your issue has not already been fixed.

I added a link, why was it still marked?

Ensure the link is pointing to a codebase that is accessible (e.g. not a private repository). "example.com", "n/a", "will add later", etc. are not acceptable links -- we need to see a public codebase. See the above section for accepted links.

Useful Resources

github-actions[bot] avatar Nov 29 '25 21:11 github-actions[bot]

ok, I’ve already created a fix and opened a PR: https://github.com/payloadcms/payload/pull/14767

teastudiopl avatar Nov 30 '25 18:11 teastudiopl