We need to add the same product variant (representing a Product Protection Plan, e.g., variantId=1234) to the Shopify POS cart multiple times, with each instance appearing as a separate line item. This is because each protection plan instance needs to be associated with a different primary product (e.g., Product A, Product B) using custom line item properties.
Example Scenario (Desired Cart State):
Imagine a customer adds Product A, its associated protection plan, then Product B, and its associated protection plan. The cart should ideally look like this:
Line Item 1: Product A (variantId=productA_variant)
Line Item 2: Product Protection Plan (variantId=1234, customProperties: { associatedProductId: ‘productA_id’ })
Line Item 3: Product B (variantId=productB_variant)
Line Item 4: Product Protection Plan (variantId=1234, customProperties: { associatedProductId: ‘productB_id’ })
Notice that Line Item 2 and Line Item 4 use the same variantId (1234) but are distinct entries, differentiated by their custom properties linking them to Product A and Product B, respectively.
Problem:
The standard cart.addLineItem(variantId, quantity) method seems designed to update the quantity if the variantId already exists in the cart, or potentially throws an error, rather than creating a new, separate line item like Line Item 4 in the example above.
Specific Query:
Is there an alternative method or workflow within the Shopify POS App SDK (specifically the Cart API or related features) that allows adding a variant as a new, distinct line item even if that variantId is already present in the cart? We need the ability to treat each addition as unique and attach separate custom properties to differentiate them.
Does this work in Admin API?
It seems a bit like abusing the cart as its designed to be one line item per variant.
Could you work the other way around, like so
Line Item 1: Product A (variantId=productA_variant, customProperties: PROTECTED + other info)
Line Item 2: Product B (variantId=productB_variant, customProperties: PROTECTED + other info)
Line Item 3: Some other product (variantId=variant_OTHER)
Line Item 4: Product Protection Plan (variantId=1234, quantity: 2)
So in this example the standard products on line 1 and 2 are protected by your cover. But line item 3 isn’t.
As then its working the way cart is expecting and you can still work back to which plan covers each item.
Alternatively there is a custom sale Cart API
But this wouldn’t tie back to your variant so might be a bit of a hack.
Yeah we are actively looking into alternative options but the way our BE is setup it would be ideal if we could add these Product Protection Plans as separate lines items.
But sounds like there isn’t a way to do this given that the CART was designed to be one line item per variant id?
Yeah the cart in Shopify is designed to have one line item per variant id. I know you can work around it via the Admin API but POS Cart won’t let you do this.
@JordanFinners Are you aware of any open issues/features that Shopify is looking into? The fact that this operates differently from the storefront poses some challenges, and we’re trying to evaluate how to proceed.
I don’t know of anything where this would change. TBH I would look at changing your data model around to marry up with one line item to one product variant as that how checkout is intended and you could do this relatively straightforwardly by using line item properties / custom properties on the line items you are protecting.
This is so very much needed. It works as expected in the online store, but the disparity in POS is causing major issues for us too. I’ve been talking with @JS_Goupil about this and sent in screen recordings, but I’m not sure if it’s been worked on or what the status is. There was some indication that a fix may be coming, but i’m not sure where it’s at. All I can say is that we desperately need this functionality also
Hey everyone – Thanks for sharing your feedback around supporting multiple cart line items with the same variant ID combined with unique customizations via line_item_properties (similar to how it’s available on the online store).
You’re right; this isn’t available right now in Shopify POS. Our engineering team knows this feature would boost the app experience significantly for merchants and developers alike. We appreciate hearing how important this update is to you and your projects – we’ll keep you updated on any developments here.
@Brian_Edwards just adding to the choir. Having the same issue with some of my clients. I understand you all are pushing POS hard but I have to halt my POS referral efforts until we can get this resolved. After uncovering this later in dev (while banking on a similar ecomm experience) I’m a little spooked to keep selling POS migrations to Shopify.
I’ve been experimenting with this and I believe splitting line items that have different properties is definitely possible in POS now.
Here is how I managed to get it working.
Method 1: Sequential Adding
You can combine addLineItem with addLineItemProperties to separate them right from the start.
// 1. Add the base variant (ID: 55443322) to the cart
// This generates a line item. Let's assume the UUID becomes 'uuid-original-A'
api.cart.addLineItem(55443322, 1);
// 2. Attach a specific property to that unique line item UUID
api.cart.addLineItemProperties('uuid-original-A', { Monogram: 'JS' });
// 3. Add the same variant again
// This generates a NEW line item. Let's assume UUID is 'uuid-new-B'
api.cart.addLineItem(55443322, 1);
// The cart now treats these as distinct entries because their properties differ.
// Resulting State:
| Line Item UUID | Variant ID | Qty | Properties |
| :--- | :--- | :--- | :--- |
| uuid-original-A | 55443322 | 1 | Monogram: JS |
| uuid-new-B | 55443322 | 1 | *None* |
// Note: If you were to add { Monogram: 'JS' } to 'uuid-new-B' later,
// POS would automatically merge them back into a single line item with Qty 2.
Method 2: Splitting Existing Items via bulkCartUpdate
If you have a line item with a quantity greater than 1 and need to split it programmatically, you can use a reducer to rebuild the line item array.
The Scenario: Imagine you have a cart where Item uuid-original-A has a Quantity of 3, and you want to separate one of them to add a property.
const currentCart = useCartSubscription();
// The UUID of the line item we want to target
const targetUuid = 'uuid-original-A';
// Build a new array of items
const newCartState = currentCart.lineItems.reduce((list, row) => {
if (row.uuid === targetUuid) {
// We found the target. Return an array injecting the split items.
return [
...list,
// 1. Keep the original item but decrement quantity by 1
{
...row,
quantity: row.quantity - 1
},
// 2. Create the split item with Quantity 1 and the new Property
{
...row,
uuid: "new-uuid-generated-explicitly", // It's best to supply a fresh UUID here
quantity: 1,
properties: { Monogram: 'JS' }
}
];
}
// If it's not the target, just push it to the list unchanged
return [...list, row];
}, []);
// Commit the changes to the cart
api.cart.bulkCartUpdate({
...currentCart,
lineItems: newCartState
});
// Final Cart Result:
| Line Item UUID | Variant ID | Qty | Properties |
| :--- | :--- | :--- | :--- |
| uuid-original-A | 55443322 | 2 | *None* |
| new-uuid-gener... | 55443322 | 1 | Monogram: JS |
| [other-items] | ... | ... | ... |