← Blog

Updates,

Saleor 3.23: Explicit Delivery Options

Łukasz Ostrowski

Saleor 3.23 replaces implicit shipping webhook triggers with an explicit mutation — giving storefronts full control over when delivery options are fetched and validated.

Checkout is the most performance-sensitive part of any storefront. In Saleor 3.23, we're making a fundamental change to how delivery options work — moving from implicit, behind-the-scenes webhook calls to an explicit, storefront-driven model.

Delivery options should refresh when you decide — not as a side effect of reading checkout data.

The Problem

In previous versions, simply querying fields like shippingMethods or availableShippingMethods on a Checkout object would implicitly trigger synchronous webhooks (SHIPPING_LIST_METHODS_FOR_CHECKOUT, CHECKOUT_FILTER_SHIPPING_METHODS). On top of that, checkout mutations would silently invalidate the shipping cache, causing additional webhook calls.

This meant every checkout query could fire external HTTP requests without the storefront knowing — adding latency, increasing costs, and making performance unpredictable.

What's New

Saleor 3.23 introduces three related changes:

Before 3.23: implicit webhook triggers on every checkout operation After 3.23: explicit, storefront-driven delivery options
01

deliveryOptionsCalculate

This is the only place that triggers shipping webhooks. Call it when you decide it is time to refresh options — not on every checkout query.

GRAPHQL
1mutation DeliveryOptionsCalculate($id: ID!) {
2 deliveryOptionsCalculate(id: $id) {
3 deliveries {
4 id
5 shippingMethod {
6 name
7 active
8 price {
9 amount
10 }
11 }
12 }
13 errors {
14 field
15 message
16 code
17 }
18 }
19}
02

Checkout.delivery

Replaces the old deliveryMethod and shippingMethod fields with one structure that exposes the assigned delivery and its shipping method details.

GRAPHQL
1query Checkout($id: ID!) {
2 checkout(id: $id) {
3 delivery {
4 id
5 shippingMethod {
6 id
7 name
8 }
9 }
10 }
11}
03

New checkout problems

Instead of silently invalidating or removing delivery methods, Saleor surfaces explicit problem types so the storefront knows what changed and what to do next.

How It Works

The new flow puts the storefront in control:

  1. Set the shipping address on the checkout
  2. Call deliveryOptionsCalculate to fetch available shipping methods
  3. Use the id from the returned deliveries list as deliveryMethodId in checkoutDeliveryMethodUpdate
  4. Monitor checkout.problems for delivery state changes
  5. Re-call deliveryOptionsCalculate when problems indicate the delivery is stale

For click & collect, you still query checkout.availableCollectionPoints to get warehouse options, then pass the warehouse id to checkoutDeliveryMethodUpdate.

New Checkout Problems

Two new problem types replace the old implicit behavior:

CheckoutProblemDeliveryMethodStale

The assigned delivery method may be outdated — for example, after a voucher is applied, the shipping address changes, or line quantities are updated. The method is still assigned but hasn't been re-validated.

What to do: Call deliveryOptionsCalculate. If the method is still valid, the problem clears. If not, it becomes CheckoutProblemDeliveryMethodInvalid.

This problem does not block checkoutComplete — but if you proceed without resolving it, Saleor will implicitly validate the delivery during completion and return an error if it's no longer valid.

CheckoutProblemDeliveryMethodInvalid

The assigned delivery method is no longer applicable — it may have been deleted or no longer covers the checkout address.

What to do: Call deliveryOptionsCalculate to get valid options, then call checkoutDeliveryMethodUpdate with a new method. This problem blocks checkoutComplete.

Migration Guide

If you're upgrading from 3.22, here's what needs to change:

  • Replace checkout.shippingMethods and checkout.availableShippingMethods queries with calls to the deliveryOptionsCalculate mutation
  • Replace checkout.deliveryMethod and checkout.shippingMethod with checkout.delivery
  • Handle the new problems — watch for CheckoutProblemDeliveryMethodStale and CheckoutProblemDeliveryMethodInvalid in checkout.problems and respond accordingly
  • Update null checks — instead of checking checkout.deliveryMethod == null, use checkout.delivery == null for "not set" and check checkout.problems for "no longer valid"

The deprecated fields still work in 3.23 but will be removed in a future release. They continue to trigger implicit webhooks, so migrating early gives you the performance benefits immediately.

For the full upgrade guide, see the 3.22 to 3.23 migration docs.

    Get more useful guides, tech insights, and free learning materials by subscribing to our list.
    All human-written!

    By registering you agree to our Privacy Policy.
    The form is protected by reCAPTCHA - Privacy Policy and Terms of Service.