Overview
The Shopping Cart API provides comprehensive cart management functionality for customers. Each customer can have multiple carts (one per store) with real-time synchronization across devices.
Add to Cart
Add a product to the customer’s shopping cart for a specific store.
Quantity to add (must be positive)
TypeScript
JavaScript
Python
await convex . mutation ( api . customers . cart . addToCart , {
customerId: "c123456789" ,
storeId: "j123456789" ,
productId: "p123456789" ,
quantity: 2
});
Update Cart Item Quantity
Update the quantity of a specific item in the cart. Set quantity to 0 to remove the item.
New quantity (0 to remove item)
await convex . mutation ( api . customers . cart . updateCartItemQuantity , {
customerId: "c123456789" ,
storeId: "j123456789" ,
productId: "p123456789" ,
quantity: 3
});
Remove from Cart
Remove a specific item from the cart completely.
await convex . mutation ( api . customers . cart . removeFromCart , {
customerId: "c123456789" ,
storeId: "j123456789" ,
productId: "p123456789"
});
Clear Cart
Clear all items from the cart for a specific store.
await convex . mutation ( api . customers . cart . clearCart , {
customerId: "c123456789" ,
storeId: "j123456789"
});
Get Cart
Retrieve the cart for a specific customer and store with current product information and pricing.
const cart = await convex . query ( api . customers . cart . getCart , {
customerId: "c123456789" ,
storeId: "j123456789"
});
{
"_id" : "cart123456789" ,
"customerId" : "c123456789" ,
"storeId" : "j123456789" ,
"items" : [
{
"productId" : "p123456789" ,
"productName" : "Pizza Margherita" ,
"productPrice" : 15.99 ,
"quantity" : 2 ,
"subtotal" : 31.98 ,
"productImage" : "https://storage.convex.dev/..." ,
"isAvailable" : true ,
"stockAvailable" : 100
},
{
"productId" : "p987654321" ,
"productName" : "Garlic Bread" ,
"productPrice" : 6.99 ,
"quantity" : 1 ,
"subtotal" : 6.99 ,
"productImage" : "https://storage.convex.dev/..." ,
"isAvailable" : true ,
"stockAvailable" : 50
}
],
"itemsCount" : 3 ,
"subtotal" : 38.97 ,
"store" : {
"id" : "j123456789" ,
"name" : "Mario's Pizza" ,
"logo" : "https://storage.convex.dev/..." ,
"isActive" : true
},
"_creationTime" : 1640995200000 ,
"lastUpdated" : 1640995800000
}
Get Customer Carts
Retrieve all carts for a customer across all stores.
const carts = await convex . query ( api . customers . cart . getCustomerCarts , {
customerId: "c123456789"
});
[
{
"_id" : "cart123456789" ,
"storeId" : "j123456789" ,
"storeName" : "Mario's Pizza" ,
"itemsCount" : 3 ,
"subtotal" : 38.97 ,
"lastUpdated" : 1640995800000
},
{
"_id" : "cart987654321" ,
"storeId" : "j987654321" ,
"storeName" : "Tech Store" ,
"itemsCount" : 1 ,
"subtotal" : 299.99 ,
"lastUpdated" : 1640995600000
}
]
Get Cart Summary
Get a summary of all cart activity for a customer.
const summary = await convex . query ( api . customers . cart . getCartSummary , {
customerId: "c123456789"
});
{
"totalItems" : 4 ,
"totalStores" : 2 ,
"totalAmount" : 338.96
}
Get Cart for Checkout
🆕 New Function - Get cart with checkout calculations and validation in one call.
Delivery method: delivery or pickup
Delivery fee (defaults to 5.99 for delivery, 0 for pickup)
const checkoutData = await convex . query ( api . customers . cart . getCartForCheckout , {
customerId: "c123456789" ,
storeId: "j123456789" ,
deliveryType: "delivery" ,
deliveryFee: 5.00
});
{
"cart" : {
"_id" : "cart123456789" ,
"items" : [ ... ],
"itemsCount" : 3 ,
"subtotal" : 38.97
},
"checkoutTotals" : {
"subtotal" : 38.97 ,
"deliveryFee" : 5.00 ,
"platformCommission" : 2.85 ,
"totalAmount" : 43.97 ,
"itemsCount" : 3
},
"isValidForCheckout" : true ,
"validationIssues" : []
}
Real-time Updates
The cart system supports real-time updates across all devices. Use the React hooks for automatic synchronization:
React Hook
Vue Composition API
import { useQuery , useMutation } from "convex/react" ;
import { api } from "./convex/_generated/api" ;
function CartComponent ({ customerId , storeId }) {
// Real-time cart data
const cart = useQuery ( api . customers . cart . getCart , {
customerId ,
storeId
});
// Mutation for adding items
const addToCart = useMutation ( api . customers . cart . addToCart );
const handleAddItem = async ( productId : string , quantity : number ) => {
await addToCart ({
customerId ,
storeId ,
productId ,
quantity
});
};
if ( cart === undefined ) return < div > Loading cart ...</ div > ;
if ( cart === null ) return < div > Cart is empty </ div > ;
return (
< div >
< h2 > Cart ({cart. itemsCount } items ) </ h2 >
< p > Subtotal : $ {cart. subtotal } </ p >
{ cart . items . map ( item => (
< div key = {item. productId } >
{ item . productName } x { item . quantity } = $ {item. subtotal }
</ div >
))}
</ div >
);
}
Error Handling
Error : Product is inactive or out of stock{
"error" : "Product is not available for purchase" ,
"code" : "PRODUCT_UNAVAILABLE" ,
"productId" : "p123456789"
}
Error : Not enough stock for requested quantity{
"error" : "Insufficient stock available" ,
"code" : "INSUFFICIENT_STOCK" ,
"available" : 5 ,
"requested" : 10
}
Error : Store is not accepting orders{
"error" : "Store is currently not accepting orders" ,
"code" : "STORE_INACTIVE" ,
"storeId" : "j123456789"
}
Best Practices
Real-time Sync Use React hooks for automatic cart synchronization across devices and tabs.
Validation Always validate cart contents before checkout to handle stock changes.
Performance Use getCartForCheckout for checkout flows to reduce API calls.
User Experience Show loading states and handle errors gracefully for better UX.
Cart items are automatically validated for availability and stock levels. Unavailable items are marked but not removed automatically.
Use the getCartForCheckout function for checkout flows as it provides cart data, validation, and totals calculation in a single optimized call.