Shopify

Shopify cart and checkout validation in 2026

Shopify

Shopify cart and checkout validation is how I enforce business rules on the server instead of hoping a theme script or a checkout UI extension catches every edge case. I am Alan Vo, a Gold Coast web developer with 18 years in production. When a Plus store needs to block oversize carts, cap first-time buyers, or require a PO number on B2B checkout, Cart and Checkout Validation Functions belong in the same migration bucket as Shopify checkout extensibility deadlines in 2026.

This note is for merchants and developers who already accept that checkout.liquid and Shopify Scripts are sunset paths. It covers the cart.validations.generate.run target, how Shopify surfaces errors to buyers, what changed in 2026 for billing address and PO fields, and how I test before a peak season.

Why Shopify cart and checkout validation matters in 2026

Shopify cart and checkout validation matters because client-side checks are easy to bypass and expensive Scripts are going away. A JavaScript guard on the cart page does not run inside Shop Pay, does not protect the Storefront API cart mutations, and disappears when a buyer uses an accelerated wallet. Validation Functions run in Shopify's checkout pipeline after pricing and discount Functions, which is the order Shopify documents in its Function APIs overview.

The platform treats a validation error as a hard stop. When your function returns a validationAdd operation with errors, checkout cannot advance until the cart state changes or the rule no longer fires. That is stronger than a UI extension banner that a theme update can hide. It is also different from a discount Function: you are not changing line prices, you are declaring that the order is not allowed to proceed.

Merchants activate validations under Settings > Checkout > Checkout rules (wording may vary slightly by admin version). Each rule points at one deployed Function. Multiple rules can stack, but I prefer one well-tested function per concern so rollback is obvious.

2026 added server-side hooks for billing address fields and purchase order numbers on the validation input graph, with matching checkout field targets for error messages. Shopify's April 2026 changelog entry describes billingAddress and poNumber on the cart input and targets such as $.cart.billingAddress.countryCode and $.cart.poNumber. That closes a gap where teams used fragile UI extensions to block prohibited billing countries or B2B orders without a PO.

If you still rely on a Ruby Script to reject carts, the Scripts sunset timeline in my checkout extensibility note applies. Validation Functions are the supported replacement surface for "should this cart be allowed to check out?"

Shopify cart and checkout validation on a laptop showing a Shopify storefront layout

How Cart and Checkout Validation Functions run

Cart and Checkout Validation Functions use the target cart.validations.generate.run. Your app ships a Function extension. Shopify invokes it with a GraphQL input query you define (for example cart subtotal, buyer order count, line attributes, delivery address, and as of 2026-04 billing address and PO number where applicable). The Function returns a CartValidationsGenerateRunResult with an ordered list of operations, typically validationAdd blocks that contain one or more errors.

Each error has a message string shown to the buyer and a target string that tells Shopify where to attach the error in checkout. The Cart and Checkout Validation Function API reference documents global cart targeting with $.cart and field-level targets that mirror checkout field paths. Field-level targeting is how you put a postal code error on the postal code field instead of flashing a generic banner at the top of the step.

Functions execute in WebAssembly with strict time and memory limits. Shopify's overview stresses performance because validations sit on the purchase path. I keep input queries minimal: fetch only fields the rule reads, avoid unbounded line loops when a cart attribute or subtotal check is enough, and never assume you can call the Admin API from inside the Function runtime unless you use the documented fetch pattern for external validation providers (and account for latency).

The execution order relative to other Functions is fixed. Cart line transforms and discount Functions run first. Validations run last among the standard checkout Function family. That means your validation sees discounted totals, not pre-discount fiction. It also means you cannot validate your way out of a bad discount Function; fix the discount layer first.

Checkout UI extensions can still complement validations. I use UI extensions for helpful copy and validations for rules that must hold on every surface. Duplicating the same rule in JavaScript and in a Function is a maintenance trap. Pick one source of truth for enforcement.

Production checklist for Shopify cart and checkout validation

The production checklist starts with a written rule spec, then scaffold, then activation on a duplicate store before touching production checkout rules.

  1. Write the rule in merchant language first: "First-time customers cannot checkout over $1,000 AUD" or "Billing country must not be on our restricted list." Include what should happen on Shop Pay and on headless carts.
  2. Scaffold a Function app with Shopify CLI using the cart and checkout validation template. Shopify's tutorial Create checkout validation walks through GraphQL input, Rust or JavaScript handler, and deploy.
  3. Shape the input query to match the rule. The tutorial example reads buyerIdentity.customer.numberOfOrders and cart.cost.subtotalAmount.amount. Extend only when you need line attributes, delivery groups, or the 2026 billing and PO fields.
  4. Return validationAdd with a clear buyer-facing message. Avoid internal codes in the string merchants see.
  5. Set target deliberately. Use $.cart for order-level blocks. Use field paths when the buyer can fix a specific input.
  6. Deploy the app to a development store and enable the validation under checkout rules. Confirm the rule name matches what support will search for in admin.
  7. Test happy path checkout end to end: standard shipping, discount codes, and at least one wallet if the merchant uses Shop Pay.
  8. Test failure path: attempt checkout with a cart that should fail. Verify the buyer cannot reach shipping or payment until the cart changes.
  9. Test Storefront API behavior. Shopify documents that cartLinesAdd and related mutations surface function validation messages in userErrors. Headless storefronts must render those errors instead of swallowing them.
  10. Test B2B PO rules on a store with B2B features if applicable. Confirm poNumber is present in input when you expect it and that errors land on the PO field target.
  11. Test billing country restrictions with the new address subfield targets. A message on countryCode is easier to act on than a generic cart error.
  12. Document rollback: which checkout rule to disable and which app version to pin if a deploy misbehaves during a sale.
  13. Align analytics. A blocked checkout is not a conversion. If you map checkout steps in GTM via a Shopify custom pixel for Google Tag Manager, decide whether validation failures get an event or stay out of the funnel noise.
  14. After Scripts sunset, remove duplicate Ruby checks so buyers do not see two conflicting messages.
Clothing rails in a shop used as a live catalogue for Shopify cart and checkout validation

What breaks when validation Functions go live

The most common break is an over-broad input query that pushes the Function over resource limits on large carts. Symptoms are intermittent checkout failures or rules that never seem to run. Shrink the query and simplify logic before you ask Shopify to raise limits (which is not guaranteed).

Theme code on a monitor during Shopify cart and checkout validation work

The second break is wrong targets. A typo in target still returns an error, but Shopify may show it as a global checkout message. Buyers do not know which field to fix. Copy targets from the API reference, do not guess path strings from checkout DOM ids.

The third break is stale buyer identity assumptions. numberOfOrders and customer fields depend on login state and checkout identity. Guest checkout with an email that matches a returning customer behaves differently than a logged-in account. Test guests, logged-in customers, and B2B company locations if the store uses them.

The fourth break is fighting discount Functions. If a validation reads pre-discount subtotal in your head but the input exposes post-discount amounts, thresholds feel "wrong" to merchandisers. Read the actual input schema fields and name the rule after post-discount totals in the spec.

The fifth break is headless carts that ignore userErrors. Hydrogen and custom apps must bubble validation failures to the UI. Otherwise support hears "Shopify blocked me" while the storefront shows a generic failure.

The sixth break is double enforcement. A UI extension that disables the Pay button plus a Function that blocks checkout can produce duplicate messaging. Pick server-side enforcement and use UI for education only.

How I measure Shopify cart and checkout validation

Measurement starts with structured logs on the app side, not only Shopify admin. I log function version, rule id, and a hash of cart line count when a validation returns errors in staging. In production I avoid logging PII; I log rule name and outcome counts.

In checkout analytics, compare step drop-off before and after enabling a rule. A spike on the information step after turning on billing country validation usually means the message or target is unclear, not that buyers hate the policy.

Support ticket tags help. If agents start pasting the exact validation message daily, the copy is either working (buyers quote it) or the rule is too aggressive for the catalog mix.

For B2B PO requirements, measure orders that complete after PO entry versus abandoned checkouts where PO was empty. If abandonment rises with no lift in compliant orders, the rule timing may be wrong (require PO before payment, not after).

Storefront API teams should track mutation userErrors rates in their own telemetry. Silent failures there are conversion leaks.

Validation Functions sit beside checkout extensibility work I have shipped on Plus stores. Their Nibs is a Shopify build where checkout trust, tags, and conversion hygiene had to stay aligned through platform migrations. Offporter is another Shopify storefront where checkout-side behavior and merchandising rules cannot drift from what the theme promises. Tamannaah Fine Jewellery is the kind of high-SKU catalogue where cart limits and regional rules show up in support if enforcement is only client-side.

Phone showing a product page in Shopify cart and checkout validation testing

If you are still mapping the extensibility surface area, read Shopify checkout extensibility deadlines in 2026 before you schedule Function work behind a hard launch date.

FAQ

What is Shopify cart and checkout validation?

Shopify cart and checkout validation is a Checkout Extensibility feature that runs Cart and Checkout Validation Functions on Shopify's servers during checkout. The function evaluates cart and buyer data, then returns validation errors that block progress until the buyer fixes the cart or the rule no longer applies. It replaces many legacy Script-based guards for order eligibility.

How do I activate a cart and checkout validation function?

You deploy a Function app extension, install the app on the store, then enable the validation under checkout rules in admin (Settings > Checkout). Shopify's create checkout validation tutorial covers scaffolding, deploy, and verifying that checkout stops when the rule fires. Test on a development store before enabling on production.

Can Shopify cart and checkout validation block Storefront API carts?

Yes. When a validation function returns errors, Storefront API cart mutations can include those messages in userErrors, and checkout cannot complete while the validation fails. Custom storefronts must display userErrors to buyers. Relying only on Online Store checkout without testing API paths leaves a hole in enforcement.

What changed for billing address and PO validation in 2026?

As of API version 2026-04, Cart and Checkout Validation Function input includes billingAddress and poNumber on the cart object, with checkout field targets for billing address subfields and $.cart.poNumber. That lets functions enforce billing country restrictions and B2B PO requirements without client-only UI extensions, as described in Shopify's changelog post.

Card payment at a counter after a Shopify cart and checkout validation release

Keep reading

Contact if you want this kind of work on a live store.