Shopify is moving checkout validation off the client
January made blocking opt-in. July deprecated the API that did the blocking. Read together they are one decision, and the reason is express wallets.
UpdateJuly 10, 20264 min read
Two changelog entries six months apart look like housekeeping until you put them next to each other.
On 26 January 2026, checkout UI extensions began defaulting to non-blocking: an extension can no longer stop a buyer from progressing unless the merchant explicitly turns on "Allow app to block checkout". The entry also states Shopify's recommendation plainly — use Validation Functions rather than UI extensions for validation.
On 2 July 2026, useBuyerJourneyIntercept and the block_progress capability were deprecated in API version 2026-07, with removal announced for a future version. The migration path is Cart and Checkout Validation Functions; rejecting a discount code moves to the discount Function API.
That is not two adjustments. That is one decision, announced twice.
Why it had to happen
Scroll the figure sideways to see all of it
A checkout UI extension is client-side code that runs when the checkout renders. That is fine as long as every purchase goes through a rendered checkout — and increasingly they do not.
An express wallet button takes a buyer from a product page to a completed order without the extension ever executing. An agent completing a purchase on a buyer's behalf is not running your Preact component either. Any rule enforced only in a UI extension is therefore a rule with holes in it, and the holes are in the paths a buyer is most likely to take when they are in a hurry.
Validation Functions run inside Shopify, on the cart and the checkout, regardless of which surface the order came from. That is a far wider net than a UI extension casts — though not a complete one: the documented compatibility matrix still excludes POS, the Create Order API, Order Edit, pre-order and try-before-you-buy, and subscription renewals. Check the matrix for the surfaces your store actually sells through before treating a Function as total coverage.
What this means for extensions you have shipped
If an extension blocks progress today, three things are true. It only still blocks where a merchant has enabled the capability. The API it uses is deprecated. And the behaviour it was protecting has a gap on express and agentic paths that predates both announcements.
The migration splits validation into two pieces, which is a better shape anyway:
- The rule becomes a Validation Function. It runs server-side, returns errors against targets, and applies on every surface.
- The explanation stays in the UI extension. It renders the field, the help text, the reason the order cannot proceed — the part a Function cannot draw.
Shopify has been widening the Function side to support this. In April 2026, Cart and Checkout Validation gained billingAddress and poNumber along with new error targets, which covers a set of B2B and compliance rules that previously had no server-side expression.
The rules this affects, concretely
It is worth naming the rules that live in this pattern, because most of them were written years ago and nobody remembers where they run.
- Address rules. No PO boxes, no forwarding addresses, no delivery outside a service area, apartment number required for certain postcodes.
- Quantity rules. Minimums, maximums, multiples, per-customer limits on a launch product.
- Mixed-cart rules. Hazardous goods that cannot ship with anything else, refrigerated items that cannot ship with dry goods, fragile items that must ship alone.
- Account rules. Wholesale-only products, licence numbers, purchase orders that must be present before a B2B order can proceed.
Every one of those is a rule about whether an order is allowed to exist, and every one of them is wrong if it can be bypassed by tapping a wallet button on a product page.
What to do about it
Inventory what blocks. For each extension, write down the rule it enforces, then ask whether that rule is still enforced when the buyer uses an express wallet. Anything that answers no is already broken, deprecation aside.
Move the rule before the removal date arrives. "A future version" is not a date, but a deprecated API in a quarterly release cycle is a countdown regardless of whether the number is published yet.
And check the merchant-facing side: an extension that relied on blocking and is now non-blocking by default may be permitting orders it used to stop, and nothing about the storefront will look different. That is the failure worth finding this week rather than at quarter close.
This is the substance of checkout extensibility work now, and it is why Functions development has stopped being an advanced topic.