Intercept API
This feature is available only to approved apps and is subject to change.
This feature is available only to approved apps and is subject to change.
The Intercept API registers a callback that checks the cart before checkout or a cash payment before Shopify Point of Sale (POS) adds it. Your callback returns validation findings, which Shopify POS displays as required or recommended actions. Staff address the findings in a resolution target. For complete examples, follow Build a cart validation UI extension and Build a payment validation UI extension. Before registering an interceptor, declare its event and matching resolution target. See Configuration rules.
Anchor to Example use casesExample use cases
- Cart checks (
cartvalidations): Apply a rule to the whole cart before checkout, such as requiring a note when the cart has a discount. - Product checks (
cartvalidations): Collect staff input for a specific cart line before checkout. - Cash review (
paymentvalidations): Recommend that staff review the cash count before accepting payment.
Anchor to Supported targetsSupported targets
Register interceptors at this target for the following events:
| Target | Events |
|---|---|
pos.app.ready.data | cartvalidations, paymentvalidations |
Anchor to MethodsMethods
Use shopify.intercept() in the default entry function of pos.app.ready.data to register a callback for a declared event. This method is available only on the app background target. The method returns a function that unregisters the callback. You can register one callback per event in each extension instance, and the callback must return its result synchronously. Returning a Promise isn't supported.
A valid empty operations array adds no findings.
The app background target adds shopify.intercept() for registering validation callbacks.
- Anchor to interceptinterceptintercept<K extends keyof ShopifyInterceptMap>(type: K, interceptor: ShopifyInterceptor<K>) => () => void<K extends keyof ShopifyInterceptMap>(type: K, interceptor: ShopifyInterceptor<K>) => () => voidrequiredrequired
Register an interceptor for a POS host workflow that can be blocked. Returns a function that unregisters the interceptor.
ShopifyInterceptMap
Maps POS interceptable workflow names to their corresponding `Event` types. Used as the generic type parameter for `shopify.intercept`.
- cartvalidations
The event a `cartvalidations` interceptor receives. Carries a snapshot of the POS cart taken when the event was produced.
CartValidationsEvent - paymentvalidations
The event a `paymentvalidations` interceptor receives. Carries the tender attempt's payment method and amount; split payments produce one event per tender, each with its own amount.
PaymentValidationsEvent
CartValidationsEvent
The event a `cartvalidations` interceptor receives. Carries a snapshot of the POS cart taken when the event was produced.
- cart
A snapshot of the POS cart taken when the event was produced.
Cart - type
The event name, always `'cartvalidations'`.
'cartvalidations'
Cart
Represents the shopping cart state, including line items, pricing, customer information, and applied discounts. Provides comprehensive access to all cart data and operations.
- cartDiscount
The cart-level discount to apply during bulk update. Replaces existing cart discount. Set to `undefined` to remove current discount.
Discount - cartDiscounts
An array of cart-level discounts to apply during bulk update. Replaces all existing cart discounts with the provided array.
Discount[] - currency
The ISO 4217 currency code for this cart.
string - customer
The customer to associate with the cart during bulk update. Replaces existing customer or converts guest cart to customer cart.
Customer - editable
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.
boolean - grandTotal
The final total amount including all items, taxes, and discounts, formatted as a currency string.
string - lineItems
An array of line items to set during bulk update. Completely replaces existing cart contents—removes all current items and adds the provided ones.
LineItem[] - note
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.
string - properties
The custom key-value properties to apply to the line item. Merged with existing properties—duplicate keys overwrite existing values.
Record<string, string> - subtotal
The subtotal amount of the cart before taxes and discounts, formatted as a currency string.
string - taxTotal
The total tax amount for the cart, formatted as a currency string.
string
Discount
Represents a discount applied to a cart or transaction, including amount and description.
- amount
The discount value to apply. For `'Percentage'` type, this represents the percentage value (For example, "10" for 10% off). For `'FixedAmount'` type, this represents the fixed monetary amount to deduct from the line item price. Commonly used for discount calculations and displaying the discount value to merchants.
number - currency
The [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code associated with the location currently active on POS.
string - discountDescription
A human-readable description of the discount shown to merchants and customers. This typically includes the discount name, promotion details, or discount code (for example, "SUMMER2024", "10% off entire order", "Buy 2 Get 1 Free"). Returns `undefined` when no description is provided.
string - type
The [discount type](https://help.shopify.com/en/manual/discounts/discount-types) applied to this line item. Can be either `'Percentage'` for percentage-based discounts or `'FixedAmount'` for fixed monetary amount discounts. This determines how the discount amount is calculated and displayed.
string
Customer
Represents basic customer identification information. Contains the customer ID for linking to detailed customer data and enabling customer-specific features.
- id
The unique numeric identifier for the customer in Shopify's system. This ID is consistent across all Shopify systems and APIs. Used to link this customer reference to the full customer record with complete profile information. Commonly used for customer lookups, applying customer-specific pricing or discounts, linking orders to customer accounts, or integrating with customer management systems.
number
LineItem
Represents an individual item in the shopping cart. Contains product information, pricing, quantity, discounts, and customization details for a single cart entry.
- attributedUserId
The staff member 'ID' attributed to this line item. Returns 'undefined' if no staff attribution is set. Use for commission tracking and performance analytics.
number - components
Bundle components for this line item. Only present for [product bundles](/docs/apps/build/product-merchandising/bundles). Each component represents an individual item within the bundle with its own tax information.
LineItemComponent[] - discountAllocations
An array of discount allocations applied to this line item, providing detailed breakdown of how discounts are distributed. Returns 'undefined' if no allocations exist. Use for enhanced discount tracking and reporting.
DiscountAllocation[] - discounts
An array of discounts applied to this line item. Empty array if no discounts are active. Use for displaying line item savings and discount details.
Discount[] - hasSellingPlanGroups
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.
boolean - isGiftCard
Determines whether this line item is a gift card. Gift cards have special handling requirements and business logic. Use for implementing gift card-specific workflows.
boolean - price
The unit price of the line item. Returns 'undefined' for custom sales without set prices. Use for pricing calculations and displays.
number - productId
The product 'ID' this line item represents. Returns 'undefined' for custom sales or non-product items. Use for product-specific operations and linking to product details.
number - properties
The custom key-value properties attached to this line item. Empty object if no properties are set. Use for metadata, customization options, or integration data.
{ [key: string]: string; } - quantity
The quantity of this item in the cart. Always a positive integer. Use for quantity displays, calculations, and inventory management.
number - requiresSellingPlan
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.
boolean - sellingPlan
The currently selected selling plan for this line item. Returns 'undefined' if no selling plan is applied. Contains selling plan details including 'ID', name, and delivery intervals. Use for subscription management and recurring purchase functionality.
SellingPlan - sku
The Stock Keeping Unit (SKU) identifier for this line item. Returns 'undefined' if no SKU is configured. Use for inventory tracking and product identification.
string - taxable
Determines whether this line item is subject to tax calculations. Use for tax computation, compliance, and pricing displays.
boolean - taxLines
An array of tax lines applied to this line item, containing tax amounts and rates. Use for detailed tax reporting and compliance.
TaxLine[] - title
The display title of the line item. Returns 'undefined' for items without titles. Use for customer-facing displays and cart item identification.
string - uuid
The unique identifier for this line item within the cart. Use for line item-specific operations like updates, removals, or property modifications.
string - variantId
The product variant 'ID' this line item represents. Returns 'undefined' for custom sales or non-variant items. Use for variant-specific operations and product details.
number - vendor
The vendor or brand name for this line item. Returns 'undefined' if no vendor is set. Use for vendor-specific displays and organization.
string
LineItemComponent
Represents a component of a [product bundle](/docs/apps/build/product-merchandising/bundles) line item. Bundle components contain the individual items that make up a bundle, each with their own pricing and tax information.
- discountAllocations
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.
DiscountAllocation[] - price
The price for the custom sale item as currency string. Must be a valid positive amount. Use for non-catalog items and custom pricing.
number - productId
The unique numeric identifier for the product this component represents, if applicable.
number - quantity
The quantity of the custom sale item. Must be a positive integer. Use for quantity-based pricing and inventory management.
number - taxable
Determines whether the custom sale item is taxable. Set to `true` to apply tax calculations, `false` to exempt from taxes.
boolean - taxLines
An array of tax lines applied to this component.
TaxLine[] - title
The display name for the custom sale item. Appears on receipts and in cart displays. Should be descriptive and customer-friendly.
string - variantId
The unique numeric identifier for the product variant this component represents, if applicable.
number
DiscountAllocation
Represents the allocation of a discount to a specific line item.
- allocatedAmount
The amount of discount allocated.
MoneyV2
MoneyV2
Represents a monetary amount as a string with explicit currency code.
- amount
The monetary amount as a string.
string - currencyCode
The ISO currency code (for example, USD, CAD).
string
TaxLine
Represents a tax line applied to an item or transaction.
- enabled
Whether this tax is currently enabled.
boolean - price
The tax amount as a Money object.
Money - rate
The tax rate as a decimal number.
number - rateRange
The range of tax rates if applicable.
{ min: number; max: number; } - title
The title or name of the tax.
string - uuid
The unique identifier for this tax line.
string
Money
Represents a monetary amount with currency information.
- amount
The monetary amount as a number.
number - currency
The [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code associated with the location currently active on POS.
string
SellingPlan
Represents a selling plan (subscription) associated with a line item, containing delivery schedule and plan identification details.
- deliveryInterval
The interval of the selling plan. (DAY, WEEK, MONTH, YEAR).
string - deliveryIntervalCount
The number of intervals between deliveries.
number - digest
The fingerprint of the applied selling plan within this cart session. Provided by POS. Not available during refund / exchanges.
string - id
The unique identifier of the selling plan.
number - name
The name of the POS device.
string
PaymentValidationsEvent
The event a `paymentvalidations` interceptor receives. Carries the tender attempt's payment method and amount; split payments produce one event per tender, each with its own amount.
- amount
The cash amount received for this tender, in presentment currency.
MoneyV2 - paymentMethod
The payment method staff selected.
InterceptedPaymentMethod - type
The event name, always `'paymentvalidations'`.
'paymentvalidations'
InterceptedPaymentMethod
Identifies the payment method being attempted. `type` alone identifies singleton methods (for example `cash`). `identifier` disambiguates method types a shop can have several of (for example custom payment methods) as they become interceptable.
- identifier
Present when `type` alone is ambiguous. Matching is exact on the pair.
string - type
The kind of payment method being attempted.
InterceptedPaymentMethodType
InterceptedPaymentMethodType
The kind of payment method being attempted.
'cash'ShopifyInterceptor
The interceptor callback for a POS interceptable workflow, keyed by the workflow name so the event and its valid validation targets stay paired.
- event
ShopifyInterceptMap[K]
InterceptResult<ValidationTargetMap[K]>InterceptResult
The result an interceptor returns. An empty `operations` list adds no findings from this interceptor and doesn't remove or override findings from other interceptors.
- operations
The operations to apply. Each operation can add one validation finding.
Operation<TTarget>[]
Operation
A single host operation produced by an interceptor.
- validationAdd
ValidationAdd<TTarget>
ValidationAdd
Adds a validation to the workflow being intercepted.
- handle
Stable identifier for this validation, namespaced per extension. Each handle must be unique within one `operations` array, even across different targets. A result that repeats a handle is rejected. To flag several line items, include the line item `uuid` in each handle.
string - level
`ERROR` creates a finding labeled `Required` only when blocking is declared and allowed by the store. Otherwise, it creates a finding labeled `Recommended`. `WARNING` always creates a finding labeled `Recommended`.
ValidationLevel - target
Locates the data the validation applies to; the host decides where it renders. Omitted or unrecognized targets fall back to the event's root scope (`$.cart` / `$.payment`). The validation still applies, rendered less specifically. Line item uuids are only valid within the event that delivered them: use `lineItems[n].uuid` from this event's cart snapshot, don't cache uuids across events. Bundle components are not addressable; target their parent line.
TTarget
ValidationLevel
The severity of a validation. `ERROR` can block the workflow when blocking is declared and allowed by the store. `WARNING` never blocks.
'WARNING' | 'ERROR'ValidationTargetMap
Maps POS interceptable workflow names to their valid validation targets.
- cartvalidations
The targets that a `cartvalidations` interceptor can return.
CartValidationTarget - paymentvalidations
The targets that a `paymentvalidations` interceptor can return.
PaymentValidationTarget
CartValidationTarget
A target that a `cartvalidations` interceptor can use: the whole cart or one cart line item.
CartTarget | CartLineItemTargetCartTarget
Targets the whole cart rather than a specific line item.
'$.cart'CartLineItemTarget
Targets one cart line item by its `uuid` from this event's `cart` snapshot, for example `$.cart.lineItems['adfd6b06-4a24-4f5f-9f4b-ea21f4432dd4']`.
`$.cart.lineItems['${string}']`PaymentValidationTarget
A target that a `paymentvalidations` interceptor can use. The only supported target is the payment attempt.
"$.payment"Anchor to Intercept typesIntercept types
Event names accepted by shopify.intercept() and the event each callback receives.
- Anchor to cartvalidationscartvalidationscartvalidationsCartValidationsEventCartValidationsEventrequiredrequired
The event a
cartvalidationsinterceptor receives. Carries a snapshot of the POS cart taken when the event was produced.- Anchor to paymentvalidationspaymentvalidationspaymentvalidationsPaymentValidationsEventPaymentValidationsEventrequiredrequired
The event a
paymentvalidationsinterceptor receives. Carries the tender attempt's payment method and amount; split payments produce one event per tender, each with its own amount.
Anchor to Validation operationsValidation operations
Return this object synchronously from an interceptor. Each operation can add one validation finding.
- Anchor to operationsoperationsoperationsOperation<TTarget>[]Operation<TTarget>[]requiredrequired
The operations to apply. Each operation can add one validation finding.
Each handle must be unique within one result, even when operations target different line items. Shopify POS rejects a result that repeats a handle.
Use one of these exact target tokens to identify where a validation applies.
CartValidationTarget
A target that a
cartvalidationsinterceptor can use: the whole cart or one cart line item.
PaymentValidationTarget
A target that a
paymentvalidationsinterceptor can use. The only supported target is the payment attempt.
jsx
Examples
Require a note for discounted carts
Description
Require staff to record why a cart is discounted before checkout. This example shows how to use `shopify.intercept('cartvalidations', …)` to return an `ERROR` finding on `$.cart` when the cart has a cart-level discount but no note, and no findings otherwise.
jsx
export default function extension() { shopify.intercept('cartvalidations', ({cart}) => { if (cart.cartDiscounts.length === 0 || cart.note) return {operations: []}; return { operations: [ { validationAdd: { level: 'ERROR', handle: 'discount-note-required', target: '$.cart', }, }, ], }; }); }Limit line item quantity
Description
Limit how many units of an item staff can sell in one cart. This example shows how to use `shopify.intercept('cartvalidations', …)` to return an `ERROR` finding on each cart line with a quantity over 5, with the line's `uuid` in each handle.
jsx
const MAX_QUANTITY = 5; export default function extension() { shopify.intercept('cartvalidations', ({cart}) => ({ operations: cart.lineItems .filter((line) => line.quantity > MAX_QUANTITY) .map((line) => ({ validationAdd: { level: 'ERROR', handle: `quantity-limit-${line.uuid}`, target: `$.cart.lineItems['${line.uuid}']`, }, })), })); }Recommend a cash count review
Description
Recommend that staff count large cash payments. This example shows how to use `shopify.intercept('paymentvalidations', …)` to return a `WARNING` finding on `$.payment` when the cash amount received is 100 or more, and no findings for smaller amounts.
jsx
export default function extension() { shopify.intercept('paymentvalidations', ({amount}) => { if (Number(amount.amount) < 100) return {operations: []}; return { operations: [ { validationAdd: { level: 'WARNING', handle: 'cash-count-recommended', target: '$.payment', }, }, ], }; }); }
Anchor to Finding severityFinding severity
The callback's result and the store's settings determine how Shopify POS displays a finding:
| Callback result | Store configuration | POS label |
|---|---|---|
ERROR | blocking = true and the store has turned on Allow app to block checkout | Required |
ERROR | Blocking isn't declared or the store hasn't allowed it | Recommended |
WARNING | Any | Recommended |
| Fails: isn't registered, rejects, times out, or returns an invalid or missing result | blocking = true, and the store has turned on both Allow app to block checkout and Block checkout if app experiences a problem | Required |
| Fails | Any other configuration | Recommended |
Setting blocking = true declares that your interceptor can block checkout (cartvalidations) or a payment (paymentvalidations). It doesn't grant the store's permission. Required findings stop checkout or the payment until staff resolve or skip them through the Shopify POS flow. Recommended findings don't require resolution.
Merchants turn on both settings in the POS editor, in your extension's configuration. For the steps, see Activate a POS app extension. Allow app to block checkout lets your ERROR findings block the workflow. Block checkout if app experiences a problem makes the finding that Shopify POS creates for a failed interceptor Required, but only for an intercept that sets blocking = true. Despite their labels, both settings apply to cart validations and payment validations.
Anchor to Execution orderExecution order
Shopify POS runs your interceptor callback at specific points in each flow, and the order differs by event. The following sections give the sequence for each event: cart validation (cartvalidations) and payment validation (paymentvalidations).
Anchor to Cart validation (cartvalidations)Cart validation (cartvalidations)
cartvalidations)The following steps describe the order in which Shopify POS runs cart validation, from the first cart change through checkout to the resolution target:
- Changes to the cart run cart validation. Shopify POS clears findings when the cart has no items and no customer. A cart with only a customer still runs validation.
- Starting checkout runs cart validation again rather than reusing an earlier result. Blocking findings prevent checkout.
- Staff can tap the cart validation banner to open the cart resolution target. For what happens when staff proceed, see Revalidation.
Anchor to Payment validation (paymentvalidations)Payment validation (paymentvalidations)
paymentvalidations)The following steps describe the order in which Shopify POS runs payment validation, from a cash payment attempt to the resolution target:
- Selecting or confirming cash runs payment validation before Shopify POS adds the payment. For split payments, each cash payment attempt runs validation. Retrying a failed payment submission doesn't run validation again.
- After staff select the cash tendered amount, Shopify POS automatically opens the payment resolution target if your callback returns findings, including Recommended findings. For what happens when staff proceed, see Revalidation.
Anchor to Configuration rulesConfiguration rules
Configure intercepts in shopify.extension.toml. The following sections cover the properties you set on each intercept and the requirements your configuration must meet. For complete examples, see Configure intercepts in the cart validation tutorial and the payment validation tutorial.
Anchor to Intercept propertiesIntercept properties
Each intercept declaration accepts the following properties:
| Property | Required? | Value | Description |
|---|---|---|---|
event | Yes | string matching cartvalidations or paymentvalidations | The Shopify POS workflow to intercept. Declare each event at most once. |
blocking | No | boolean | Set to true if the callback can return ERROR findings. Defaults to false. Required findings also need the store's blocking permission. |
applies_to | Yes if event is paymentvalidations | array of unique string values | The payment methods that trigger the interceptor. Currently supports only ["cash"]. Don't set this property when event is cartvalidations, even to an empty array. |
Anchor to Configuration requirementsConfiguration requirements
A valid intercept configuration must meet these requirements:
- Use an app whose API client is approved for the POS intercept developer preview. Shopify checks this access when you run
shopify app dev. - Add
[[extensions.targeting.capabilities.intercepts]]to the[[extensions.targeting]]entry wheretarget = "pos.app.ready.data". Don't add it under extension-level capabilities. - Set
runs_offline = trueunder[extensions.supported_features]. - Set
api_versionto2026-10or a later stable version. - Declare the matching resolution target for each event, even if it returns only warnings:
pos.cart.validations.resolution.renderforcartvalidations, andpos.payment.validations.resolution.renderforpaymentvalidations. Each resolution target also requires its matching event declaration in the same extension. - Shopify rejects unknown fields or events, duplicate events, invalid types or payment method values, and events or resolution targets without a matching declaration.
Anchor to Best practicesBest practices
- Prepare asynchronous data before the callback runs: The callback must return synchronously, so fetch or subscribe to any data it needs during target setup, cache the result, and read the cached value inside the callback.