Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,16 @@ export type LineItemDiscountType = 'Percentage' | 'FixedAmount';
export interface ReadonlyCartApiContent {
/**
* Provides read-only access to the current cart state and allows subscribing to cart changes. The `value` property provides the current cart state, and `subscribe` allows listening to changes with improved performance and memory management.
*
* While POS is in a return, exchange, or refund flow, this signal exposes an empty, non-editable cart (`editable: false`). The lines being returned or exchanged aren't exposed through this signal.
*/
current: ReadonlySignalLike<Cart>;
}

/**
* Cart and line item write operations.
*
* Each mutation returns a promise that resolves once POS has processed the operation. On API version 2026-10 and later, most mutations reject the promise when POS refuses the write or can't confirm that it succeeded. On earlier API versions, the promise can resolve even when POS refuses or fails the write. Some methods resolve without confirming the write on every API version: `removeCartDiscount`, `clearCart`, `addCartProperties`, `removeCartProperties`, `setAttributedStaff`, and `setAttributedStaffToLineItem`. After a mutation, read `shopify.cart.current` to confirm the cart state changed.
* @publicDocs
*/
export interface MutableCartApiContent {
Expand All @@ -65,11 +69,13 @@ export interface MutableCartApiContent {
bulkCartUpdate(cartState: CartUpdateInput): Promise<Cart>;

/**
* Apply a cart-level discount with the specified type (`'Percentage'`, `'FixedAmount'`, or `'Code'`), title, and optional amount. For discount codes, omit the `amount` parameter. Enhanced validation ensures proper discount application.
* Apply a cart-level discount with the specified type (`'Percentage'`, `'FixedAmount'`, or `'Code'`), title, and optional amount.
*
* For type `'Code'`, pass the discount code itself as `title` (it must be non-empty) and omit `amount`. For validated code redemption with availability checks, use `addCartCodeDiscount` instead. For `'Percentage'` and `'FixedAmount'`, `amount` is required; omitting it submits a zero-value discount that POS doesn't apply.
*
* @param type the type of discount applied (example: 'Percentage')
* @param title the title attributed with the discount
* @param amount the percentage or fixed monetary amount deducted with the discount. Pass in `undefined` if using discount codes.
* @param title the title attributed with the discount. For type `'Code'`, the discount code to redeem
* @param amount the percentage or fixed monetary amount deducted with the discount. Required for `'Percentage'` and `'FixedAmount'`; pass `undefined` for discount codes
*/
applyCartDiscount(
type: CartDiscountType,
Expand All @@ -78,7 +84,9 @@ export interface MutableCartApiContent {
): Promise<void>;

/**
* Apply a discount code to the cart. The system will validate the code and apply the appropriate discount if the code is valid and applicable to the current cart contents with improved error messaging.
* Apply a discount code to the cart. POS validates the code against the shop's discount rules and applies the appropriate discount if the code is valid and applicable to the current cart contents.
*
* On API version 2026-10 and later, the returned promise rejects if the code is invalid or can't be applied. On earlier API versions, an invalid or inapplicable code can fail without rejecting the promise; check `shopify.cart.current` to confirm the discount was applied.
*
* @param code the code for the discount to add to the cart
*/
Expand Down Expand Up @@ -122,14 +130,14 @@ export interface MutableCartApiContent {
addCustomSale(customSale: CustomSale): Promise<string>;

/**
* Add a product variant to the cart by its numeric `ID` with the specified quantity. Returns the `UUID` of the newly added line item, or an empty string if the user dismissed an oversell guard modal. Throws an error if POS fails to add the line item due to validation or system errors.
* Add a product variant to the cart by its numeric `ID` with the specified quantity. Returns the `UUID` of the new line item, or the `UUID` of the existing line item if POS merged the quantity into a matching line. Throws an error if the variant can't be found or POS fails to add the line item.
*
* Pass `options` to attach line-item properties in the same operation, instead of following up with a separate `addLineItemProperties` call.
* Pass `options` to attach line-item properties in the same operation, instead of following up with a separate `addLineItemProperties` call. The `'RFID Tag'` property key is reserved and isn't applied to the line item.
*
* @param variantId the product variant's numeric ID to add to the cart
* @param quantity the number of this variant to add to the cart
* @param quantity the number of this variant to add to the cart; must be a positive integer
* @param options optional line-item properties to apply to the new line item in the same operation
* @returns {string} the UUID of the line item added, or the empty string if the user dismissed an oversell guard modal
* @returns {string} the UUID of the line item added or merged into
* @throws {Error} if POS fails to add the line item
*/
addLineItem(
Expand Down Expand Up @@ -176,7 +184,7 @@ export interface MutableCartApiContent {
/**
* Add custom properties to a specific line item using its `UUID`. Properties are merged with existing line item properties for metadata storage and tracking with enhanced validation.
*
* @param uuid the uuid of the line item to which the properties should be stringd
* @param uuid the uuid of the line item to which the properties should be added
* @param properties the custom key to value object to attribute to the line item
*/
addLineItemProperties(
Expand Down Expand Up @@ -204,10 +212,12 @@ export interface MutableCartApiContent {
/**
* Apply a discount to a specific line item using its `UUID`. Specify the discount type (`'Percentage'` or `'FixedAmount'`), title, and amount value with improved discount allocation tracking. `FixedAmount` discounts use per-unit amounts. For example, passing `'5.00'` on a line item with quantity 2 results in a $10.00 total discount.
*
* On API versions earlier than 2026-07, `FixedAmount` amounts apply to the whole line instead: POS divides the total across the line's quantity, which can introduce a one-cent rounding difference (for example, `'2.00'` on a quantity of 3 becomes `'0.67'` per unit).
*
* @param uuid the uuid of the line item that should receive a discount
* @param type the type of discount applied (example: 'Percentage')
* @param title the title attributed with the discount
* @param amount the percentage or fixed monetary amount deducted with the discout
* @param amount the percentage or fixed monetary amount deducted with the discount
*/
setLineItemDiscount(
uuid: string,
Expand All @@ -219,14 +229,16 @@ export interface MutableCartApiContent {
/**
* Apply discounts to multiple line items simultaneously. Each input specifies the line item `UUID` and discount details for efficient bulk discount operations with enhanced validation and allocation tracking. `FixedAmount` discounts use per-unit amounts. For example, passing `'5.00'` on a line item with quantity 2 results in a $10.00 total discount.
*
* @param lineItemDiscounts a map of discounts to add. They key is the uuid of the line item you want to add the discount to. The value is the discount input.
* On API versions earlier than 2026-07, `FixedAmount` amounts apply to the whole line instead: POS divides the total across the line's quantity, which can introduce a one-cent rounding difference (for example, `'2.00'` on a quantity of 3 becomes `'0.67'` per unit).
*
* @param lineItemDiscounts an array of discount inputs to apply. Each entry pairs the target line item's `UUID` (`lineItemUuid`) with the discount to apply to it (`lineItemDiscount`).
*/
bulkSetLineItemDiscounts(
lineItemDiscounts: SetLineItemDiscountInput[],
): Promise<void>;

/**
* Set the attributed staff member for all line items in the cart using the staff `ID`. Pass `undefined` to clear staff attribution from all line items with enhanced staff validation and tracking.
* Set the attributed staff member for all line items in the cart using the staff `ID`. Gift card line items are excluded from staff attribution and keep their current attribution. Pass `undefined` to clear staff attribution from all line items.
*
* @param staffId the ID of the staff. Providing undefined will clear the attributed staff from all line items.
*/
Expand Down Expand Up @@ -272,10 +284,9 @@ export interface MutableCartApiContent {
updateDefaultAddress(addressId: number): Promise<void>;

/**
* Add a selling plan to a line item in the cart using the line item `UUID`, selling plan `ID`, and selling plan name. Optionally provide delivery interval and interval count for improved performance, otherwise POS will fetch them after syncing the cart.
* Add a selling plan to a line item in the cart.
*
* @param uuid the uuid of the line item that should receive the selling plan
* @param sellingPlanId the ID of the selling plan to add to the line item
* @param input the selling plan assignment, containing the target line item's `UUID` (`lineItemUuid`), the selling plan `ID` (`sellingPlanId`), and an optional display name (`sellingPlanName`)
*/
addLineItemSellingPlan(input: SetLineItemSellingPlanInput): Promise<void>;

Expand Down
48 changes: 25 additions & 23 deletions packages/ui-extensions/src/surfaces/point-of-sale/types/cart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {DiscountAllocation} from './discount-allocation';
export interface Cart {
/**
* Indicates whether the cart is currently editable. An `undefined` value should be treated as `true` for backward compatibility. Use this to determine if cart modification operations are allowed.
*
* `editable` is `false` while POS is in a return, exchange, or refund flow. In those flows the cart signal exposes an empty cart, not the lines being returned or exchanged. `editable` remains `true` during the payment flow, where POS refuses cart mutations.
*/
editable?: boolean;
/**
Expand All @@ -28,27 +30,27 @@ export interface Cart {
*/
currency: string;
/**
* The cart note to set during bulk update. Replaces existing note or sets new note if none exists. Set to `undefined` to remove current note.
* The current cart note, or `undefined` if no note is set.
*/
note?: string;
/**
* The cart-level discount to apply during bulk update. Replaces existing cart discount. Set to `undefined` to remove current discount.
* The cart-level discount currently applied to the cart: the first manual (percentage or fixed amount) discount, or the first discount code if no manual discount exists. `undefined` if the cart has no discount.
*/
cartDiscount?: Discount;
/**
* An array of cart-level discounts to apply during bulk update. Replaces all existing cart discounts with the provided array.
* The discounts currently applied to the cart. Empty array if the cart has no discounts.
*/
cartDiscounts: Discount[];
/**
* The customer to associate with the cart during bulk update. Replaces existing customer or converts guest cart to customer cart.
* The customer currently associated with the cart, or `undefined` for a guest cart.
*/
customer?: Customer;
/**
* An array of line items to set during bulk update. Completely replaces existing cart contents—removes all current items and adds the provided ones.
* The line items currently in the cart.
*/
lineItems: LineItem[];
/**
* The custom key-value properties to apply to the line item. Merged with existing properties—duplicate keys overwrite existing values.
* The custom key-value properties currently set on the cart. Empty object if no properties are set.
*/
properties: Record<string, string>;
}
Expand Down Expand Up @@ -79,7 +81,7 @@ export interface CartUpdateInput {
*/
lineItems: LineItem[];
/**
* The custom key-value properties to apply to the line item. Merged with existing properties—duplicate keys overwrite existing values.
* The custom key-value properties to apply to the cart. Merged with existing properties—duplicate keys overwrite existing values.
*/
properties: Record<string, string>;
}
Expand Down Expand Up @@ -113,7 +115,7 @@ export interface LineItem {
*/
quantity: number;
/**
* The display title of the line item. Returns 'undefined' for items without titles. Use for customer-facing displays and cart item identification.
* The display title of the line item. For catalog products, this is the product title; the variant title isn't included, so use `sku` or `variantId` to distinguish between variants of the same product. Returns 'undefined' for items without titles. Use for customer-facing displays and cart item identification.
*/
title?: string;
/**
Expand Down Expand Up @@ -161,11 +163,11 @@ export interface LineItem {
*/
attributedUserId?: number;
/**
* Determines whether this line item requires a selling plan (subscription) to be purchased. Returns 'undefined' if selling plan information is unavailable. Use for implementing subscription-based product handling.
* Determines whether this line item requires a selling plan (subscription) to be purchased. Always present as a boolean on POS cart state. Use for implementing subscription-based product handling.
*/
requiresSellingPlan?: boolean;
/**
* Determines whether this line item has selling plan groups (subscription options) available. Returns 'undefined' if selling plan information is unavailable. Use for displaying subscription options.
* Determines whether this line item has selling plan groups (subscription options) available. Always present as a boolean on POS cart state. Use for displaying subscription options.
*/
hasSellingPlanGroups?: boolean;
/**
Expand All @@ -184,27 +186,27 @@ export interface LineItem {
*/
export interface LineItemComponent {
/**
* The display name for the custom sale item. Appears on receipts and in cart displays. Should be descriptive and customer-friendly.
* The display title of this bundle component.
*/
title?: string;
/**
* The quantity of the custom sale item. Must be a positive integer. Use for quantity-based pricing and inventory management.
* The quantity of this component in each bundle line item.
*/
quantity: number;
/**
* The price for the custom sale item as currency string. Must be a valid positive amount. Use for non-catalog items and custom pricing.
* The total price of this component within the bundle line, as a number.
*/
price?: number;
/**
* Determines whether the custom sale item is taxable. Set to `true` to apply tax calculations, `false` to exempt from taxes.
* Determines whether this component is subject to tax calculations.
*/
taxable: boolean;
/**
* An array of tax lines applied to this component.
*/
taxLines: TaxLine[];
/**
* An array of discount allocations applied to this component, providing a detailed breakdown of how discounts are distributed across bundle components. Returns `undefined` if no allocations exist.
* An array of discount allocations applied to this component, providing a detailed breakdown of how discounts are distributed across bundle components. Empty array if no allocations exist.
*/
discountAllocations?: DiscountAllocation[];
/**
Expand All @@ -227,15 +229,15 @@ export interface SellingPlan {
*/
id: number;
/**
* The name of the POS device.
* The display name of the selling plan.
*/
name: string;
/**
* The fingerprint of the applied selling plan within this cart session. Provided by POS. Not available during refund / exchanges.
* The fingerprint of the applied selling plan within this cart session. Not currently populated by POS on cart state; always `undefined`.
*/
digest?: string;
/**
* The interval of the selling plan. (DAY, WEEK, MONTH, YEAR).
* The delivery interval of the selling plan: `'Day'`, `'Week'`, `'Month'`, or `'Year'`. `undefined` if POS can't map the plan's interval.
*/
deliveryInterval?: string;
/**
Expand All @@ -254,7 +256,7 @@ export interface Discount {
*/
amount: number;
/**
* The [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code associated with the location currently active on POS.
* The [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code for the discount. Not currently populated on POS cart state; always `undefined`. Use `Cart.currency` for the cart's currency code.
*/
currency?: string;
/**
Expand All @@ -273,7 +275,7 @@ export interface Discount {
*/
export interface AddLineItemOptions {
/**
* Custom key-value properties to attach to the newly created line item. Equivalent to calling `addLineItemProperties` with the returned `UUID`, but applied in the same operation.
* Custom key-value properties to attach to the newly created line item. Equivalent to calling `addLineItemProperties` with the returned `UUID`, but applied in the same operation. The `'RFID Tag'` property key is reserved and isn't applied to the line item.
*/
properties?: Record<string, string>;
}
Expand All @@ -284,7 +286,7 @@ export interface AddLineItemOptions {
*/
export interface SetLineItemPropertiesInput {
/**
* The target line item `UUID` for selling plan assignment. Must match an existing line item in the cart.
* The `UUID` of the line item to update. Must match an existing line item in the cart.
*/
lineItemUuid: string;
/**
Expand All @@ -299,7 +301,7 @@ export interface SetLineItemPropertiesInput {
*/
export interface SetLineItemDiscountInput {
/**
* The target line item `UUID` for selling plan assignment. Must match an existing line item in the cart.
* The `UUID` of the line item to discount. Must match an existing line item in the cart.
*/
lineItemUuid: string;
/**
Expand All @@ -314,7 +316,7 @@ export interface SetLineItemDiscountInput {
*/
export interface LineItemDiscount {
/**
* The display name for the custom sale item. Appears on receipts and in cart displays. Should be descriptive and customer-friendly.
* The display title of the discount. Appears on receipts and in cart displays.
*/
title: string;
/**
Expand Down
Loading