---
title: Cart Behaviour
date: 2026-06-13T16:09:00+01:00
author: John Henry Donovan
canonical_url: "https://johnhenry.ie/plugins/container-deposits/docs/guide/cart-behaviour"
section: Plugins
---
esc

↑↓ to navigate↵ to selectesc to close

Menu On this page 

- [Return to top](#)

Documentation

Documentation

# Cart Behaviour

## Where deposits appear

Deposit line items appear alongside their parent products in:

- The cart page
- The checkout review
- Order confirmation emails
- The CP order detail view

![](https://johnhenry.ie/images/plugins/docs/container-deposits/cart-example.png)They are stored as ordinary `LineItem` records with their `options` array marked `{ "_deposit": true, "_depositTypeId": <id> }`.

![](https://johnhenry.ie/images/plugins/docs/container-deposits/order-line-item.png)Twig templates can identify them with:

```twig
{% for item in cart.lineItems %}
  {% if item.options._deposit ?? false %}
    <tr class="deposit">…</tr>
  {% else %}
    <tr>…</tr>
  {% endif %}
{% endfor %}
```

## Showing cart totals excluding deposits

Deposit line items inflate the cart's raw item count and total. For UI that should reflect products only - nav badges, mini-cart, that sort of thing - use the plugin's Twig helpers instead of summing `cart.lineItems` yourself:

CallReturns`craft.containerDeposits.productQtyFor(cart)`Total qty across product line items only`craft.containerDeposits.productSubtotalFor(cart)`Sum of product line item subtotals, deposits excluded

```twig
{% set productQty = craft.containerDeposits.productQtyFor(cart) %}
{% set productTotal = craft.containerDeposits.productSubtotalFor(cart)|commerceCurrency(cart.currency) %}
```

![](https://johnhenry.ie/images/plugins/docs/container-deposits/cart-summary.png)This is exactly what the site's cart badge in `nav-main.twig` uses to keep the count product-only. See the [API overview](https://johnhenry.ie/plugins/container-deposits/docs/api/overview) for the full list of Twig helpers.

## Synchronisation rules

The sync runs on `Order::EVENT_BEFORE_SAVE` for any cart that has not been completed:

Cart eventEffect on deposit line itemsProduct with deposit addedNew deposit line item created (or qty incremented on an existing one).Qty of a deposit-bearing product changedMatching deposit line item qty updated to reflect the new total.Deposit-bearing product removedDeposit line item removed when no parent items remain for that type.Deposit field removed from a productSame as removal - deposit drops out on next save.Order completedAll further sync is skipped; deposits are preserved as-is on the completed order.

## Properties of deposit line items

PropertyValue`purchasable`A `DepositPurchasable` element`description`The deposit type's `name``sku``deposit-<handle></handle>``price`The deposit type's `amount``qty`Sum of the qty of every parent line item sharing the deposit type`taxCategoryId``containerDeposit` category - no VAT`shippingCategoryId`Free shipping (deposit doesn't add shipping cost)`options._deposit``true``options._depositTypeId`The deposit type ID

## Performance

The sync logic only calls `Order::setLineItems()` when a deposit was actually added, removed, or had its quantity changed. Idle saves are no-ops, so there's no recalculation cost for carts that already match the expected state.

On this page
