Skip to navigation

The changelog now publishes a weekly roll-up

Starting with this post, the changelog publishes one roll-up every Thursday instead of a separate post for each change.

  • Highlights first. Each roll-up opens with the week’s most significant launches.
  • New, Improvements, and Fixes. Every other change is a collapsible item in one of these sections, labeled with the product area it affects. Open an item for the details.
  • Breaking changes don’t wait for Thursday. Breaking changes, deprecations, scheduled maintenance, and other time-sensitive announcements still publish as their own posts on the day they’re announced, often well before the change takes effect. Each roll-up links that week’s standalone posts under Also this week.

B2B GraphQL quoteCreate can calculate quote prices

The B2B Edition GraphQL quoteCreate mutation can now calculate quote prices: a request can omit every price field, and B2B Edition calculates and saves the quote prices from BigCommerce catalog pricing.

  • Optional price fields: subtotal, discount, and grandTotal on quoteData, and basePrice, discount, and offeredPrice on each productList item, are no longer required by the schema.
  • Server-calculated prices: when a request sends no price fields, each product’s price comes from BigCommerce pricing for the shopper’s customer group, channel, and currency, including bulk pricing and tax. The response returns the saved prices.
  • Requests that send prices: behave as before, including any price validation configured for the store.
  • Validation: a request with no price fields is rejected when the product list is empty or a product or variant is not in the catalog.

For details, see the quoteCreate mutation in the B2B GraphQL API reference.

Promotions on Storefront GraphQL orders

Storefront GraphQL orders now report the promotions, coupons and manual discounts applied to them, in the same shape as checkout promotions.

  • Order promotions: the BaseOrder interface adds a promotions field, so it is available on both Order and OrderWithPayments. Each OrderPromotion gives the promotion’s entityId, displayName, priority and the couponCode that applied it, if any.
  • Discount breakdown: each promotion lists its discounts, with the amount, the type (AUTOMATIC, COUPON or MANUAL) and the target (ORDER, PRODUCT or SHIPPING).
  • Allocations: each discount lists the line items or shipping consignments it was applied to, and the amount discounted from each.

Orders placed before discount details were recorded return an empty list.

For schema details, see the Storefront GraphQL API reference:

New

Catalyst 1.14.0 shows pick list items in the cart, sends OpenTelemetry spans to Cloudflare Workers tracing on Workers, and fixes analytics, faceted search, and session handling in server actions.

  • Pick list items in the cart: products that a pick list option adds to the cart now show under their parent line item, with the option’s label and their own selected options. Their quantity shows only when it differs from the parent’s.
  • OpenTelemetry on Cloudflare Workers: instrumentation.ts detects the Workers runtime and hands spans from Next.js and ~/lib/otel/tracer to Workers tracing, instead of loading @vercel/otel, which fails on Workers.
  • Analytics initialization: analytics providers initialize before the first event, so Google Analytics no longer calls gtag before it is defined.
  • Category facet includes sub-categories: on brand and search pages, filtering by a parent category returns products assigned only to its sub-categories.
  • Session redirects in server actions: when a session is invalidated, actions such as add to cart now follow the sign-out redirect instead of showing it as a form error.
  • Product list and cart layout: product list pages hide the empty filters column when there are no filters, and the cart quantity column keeps a fixed width.
  • Next.js 16.4.3: moves off the versions affected by the next/og vulnerability (CVE-2026-94545).
  • verify-catalyst agent skill: drives the storefront in a real browser to prove UI changes and attaches screenshot, video, and trace evidence to pull requests.

See the full 1.14.0 release notes for migration details and release tags.

The Catalyst CLI (@bigcommerce/catalyst) 1.6.0 deploys proxy.ts as-is on Storefront Hosting, makes --env-path the only env source for build and deploy, and makes catalyst deploy reconnect when the status stream drops.

  • proxy.ts on Storefront Hosting: setup no longer renames proxy.ts to middleware.ts. It pins @opennextjs/cloudflare 1.20.15, which bundles proxy.ts directly, and catalyst build defaults to Wrangler 4.156.0. Projects set up by an older CLI keep their middleware.ts and continue to work. If catalyst upgrade brings proxy.ts back beside it, the CLI offers to delete middleware.ts; move any changes you made in it into proxy.ts first.
  • catalyst upgrade stages removed files: middleware.ts and instrumentation.ts are staged when the upgrade removes them.
  • --env-path is the only env source: catalyst build and catalyst deploy --env-path <file> use only that file, and deploy sends its variables to the deployment, overriding values saved with catalyst env add. --secret still wins over both.
  • catalyst deploy reconnects: no longer crashes with TypeError: terminated when the deployment status stream disconnects, and no longer reports success when the stream closes before the deployment finishes.
  • OpenTelemetry on Workers: Storefront Hosting setup keeps instrumentation.ts and @vercel/otel when the hook already sends spans to Workers tracing, instead of prompting to remove them.
  • Custom checkout URLs: catalyst channels update keeps a channel’s custom checkout URL when the new storefront URL shares its main domain, instead of falling back to the default channel’s domain.

For details, see the Catalyst CLI reference.

BigCommerce now supports Wero for stores that use Stripe, so shoppers in Belgium, France, Germany, Luxembourg and the Netherlands can pay in euros with their Wero app.

  • Where Wero appears: Stripe offers Wero on EUR checkouts when the shopper’s billing country is Belgium, France, Germany, Luxembourg or the Netherlands.
  • How a shopper pays: the shopper is redirected to Wero, approves the payment in their banking app, and returns to the store. BigCommerce treats the payment as pending until Stripe confirms it, then completes the order.
  • Refunds: Wero payments can be refunded, in full or in part.
  • Turn it on in Stripe: store owners enable Wero in their Stripe Dashboard payment method settings. Stripe currently offers Wero as a public preview. No BigCommerce control panel setting, API field, value, or endpoint changes.

For payment method details, see Stripe’s Wero documentation.

A new REST endpoint reports whether Makeswift is enabled for a storefront channel, so your app can detect Makeswift storefronts without reading storefront response headers.

  • New endpoint: GET /stores/{store_hash}/v3/makeswift/channels/{channel_id}/enabled returns {"data": {"enabled": true}, "meta": {}} when Makeswift is enabled for the channel, and "enabled": false when it is not.
  • Per channel: Makeswift is enabled channel by channel, so check each storefront channel your app works with.
  • Authentication: requests use the existing store_v2_content_read_only or store_v2_content OAuth scope.

For details, see the Get Makeswift Status for a Channel reference.

Since November 9, 2026, the Avalara integration submits order transaction dates in the store’s timezone instead of UTC, so tax calculations reflect the merchant’s primary timezone of business.

  • Transaction dates — tax requests to Avalara carry the timezone from the store’s timezone setting. They are no longer sent in UTC.
  • Rule effective dates — a tax rule can take effect at a specific date and time, so the timezone decides which transactions it applies to. An order placed late in the evening before a rate change can fall on the next day in UTC. With the store timezone, the rule starts when the store owner and their shoppers expect it to.
  • Impact — most store owners see no functional change.
  • Other tax providers — this change applies to the Avalara integration only. There are no plans to enable it for other tax providers at this time, but requests are welcome.

Improvements

Company addresses in the Storefront GraphQL API now return a companyName, which is the company name saved on the address record. It can differ from the name of the company that owns the address.

  • New field: CompanyAddress.companyName is a nullable string. It is available on the addresses and address fields of customer.activeCompany.
  • Value: the company name saved on the address, or null or empty when the address has no company name.
  • Mutations: the addAddress and updateAddress mutations do not accept a company name yet, so addresses created or edited through them return an empty companyName.
  • No change for existing queries: the field is additive, and queries that do not request it behave as before.

For schema details, see the Storefront GraphQL API reference:

The B2B Edition GraphQL quoteCreate mutation now accepts an optional notes field on each item in productList, so you can save a note with each quote line.

  • Optional field: notes is a string on ProductInputType. Requests that do not send it behave as before.
  • Saved with the line: the note is stored on the quote product and returned with it. When you omit notes, the saved note is empty.

For details, see the quoteCreate mutation in the B2B GraphQL API reference.

We are rolling out structured errors for the shopping list queries and mutations in the B2B Edition GraphQL API. Over the coming weeks, you will see an error code on the errors these operations return, so your integration can tell invalid input apart from permission, not-found, and server errors.

  • Error codes. Errors include an extensions object with a code: 400 for invalid input, 403 when the user lacks permission or isn’t assigned to a company, 404 when the shopping list, item, or company doesn’t exist, 429 when requests are throttled, and 500 for unexpected server errors. The object repeats the error message in message and data.errMsg.
  • Messages name the field. Validation messages start with the input field that failed, for example items.0.quantity: Invalid product quantity. Errors that previously returned a serialized object, such as a blank shopping list name, use the same field: message form.
  • Nested fields and pagination are covered. Errors from nested fields such as products and customerInfo carry the same extensions code. A nested field whose record doesn’t exist returns 404. On shoppingLists, customerShoppingLists, and their products fields, these pagination arguments return 400 with a message naming the argument: first or last below 0 or above 50, a negative offset, offset together with before, and an after cursor that is negative, or that can’t be decoded when offset is also sent.
  • Quantity errors no longer fail the whole request. An item quantity outside 0 to 1,000,000 is reported on the mutation with HTTP 200 and a path, instead of an HTTP 400 response with no data.
  • Unexpected errors use a generic message. Server errors return An unexpected error occurred. instead of internal exception text.
  • Unchanged. Authentication errors and malformed input, such as a non-numeric quantity, keep their current responses. A shoppingList or customerShoppingList query for a list that doesn’t exist still returns null.
  • Affected operations. shoppingLists, shoppingList, shoppingListsIdName, shoppingListsCreate, shoppingListsUpdate, shoppingListsDelete, shoppingListsDuplicate, shoppingListsItemsCreate, shoppingListsItemsUpdate, shoppingListsItemsDelete, and the customer version of each, such as customerShoppingListsCreate.

We are rolling out a change to the customerShoppingListsCreate mutation in the B2B Edition GraphQL API. Over the coming weeks, you will see new shopping lists saved on the store’s default channel when the request doesn’t name a channel, instead of being saved with no channel.

  • Missing channel. When channelId is omitted, null, or 0, the shopping list is saved on the default channel. This applies to single-channel and multi-storefront stores.
  • Multi-storefront stores. A channelId that matches an enabled channel is used as before. An unknown or disabled channelId still creates the shopping list without a channel and doesn’t return an error.
  • Single-channel stores. Every new shopping list is saved on the default channel, including when channelId names another enabled channel.
  • Unchanged. Validation errors, such as a blank shopping list name, keep their current responses.

Thanks to user feedback, the Update Cart Line Item reference now documents every field you can update on a cart line item, and its request body uses the keys the API accepts.

  • Updatable fields. A line_item update can change quantity, list_price, name, weight, dimensions, gift_wrapping, and product_options. The reference previously said only list_price and quantity could be updated.
  • Gift wrapping. Send gift_wrapping to add or replace an item’s gift wrapping, or set it to null to remove it. Cart responses return gift wrapping in the giftWrapping field, not gift_wrapping.
  • Variant and modifier changes. Send the new selections in product_options, along with product_id. The line item keeps its ID, so you don’t need to remove and re-add the item. Sending a different variant_id, or sending option_selections, doesn’t change the item’s options.
  • Custom items and gift certificates. Update them with a singular custom_item or gift_certificate object. The reference previously showed custom_items and gift_certificates arrays, which return a 422 error, and said custom items couldn’t be updated.

The cart troubleshooting example in the REST APIs: Cart and Checkout Overview guide and the Checkout and Orders API course lessons are updated to match.

For details, see Update Cart Line Item.

Thanks to user feedback, the List States reference now explains that it returns the states and provinces of every country, sorted by ID, 50 per page by default. Because United States states have the lowest IDs, the first page of default results contains only United States states. Use page and limit to retrieve the rest.

  • Page size. List States, List Countries, and List Countryʼs States return 50 results per page by default. The maximum limit is 250, and a higher value returns a 413 error.
  • Response example. The List States example now shows the first results a default request returns.

For details, see List States.

The combo condition in the Promotions API now accepts an optional exclude_items_on_sale boolean.

  • Opt in per promotion: set exclude_items_on_sale to true to prevent items already on sale from being considered for the combo.
  • Default unchanged: the field defaults to false, so existing combo promotions continue to include items on sale.
  • No eligible items: when excluding items on sale leaves a branch without enough items, the combo doesn’t apply.
  • Featured promotions: featured promotions can’t set exclude_items_on_sale to true on a combo condition.
  • Returned in responses: exclude_items_on_sale is included in the combo condition when you retrieve a promotion.

For details, see Create a promotion.

The V2 Orders API now returns a new original_price field on order products. It gives the price of each line item when the order was placed, including picklist items, whose base_price is 0.

  • New original_price field: the original price of one unit of the line item, as a decimal string such as "89.0000". For an order placed at checkout, it is the cart line item’s original_price. For a product that a merchant adds while editing an order, it is the catalog price (or price-list price if one applies) at the time of the edit. Later order edits don’t change the value.
  • Where it appears: in the responses of GET /v2/orders/{order_id}/products and GET /v2/orders/{order_id}/products/{product_id}, and in consignment line items when you request include=consignments.line_items on GET /v2/orders or GET /v2/orders/{order_id}.
  • null when not recorded: the value is null for orders placed before this change, for custom products and gift certificates, and for orders created with POST /v2/orders.
  • Read-only: POST /v2/orders and PUT /v2/orders/{order_id} don’t accept the field.

For details, see Get order products.

The new manual order experience in the control panel now offers a None shipping method. This brings the new experience in line with the legacy manual order experience, which already offered None.

  • How it works: selecting None adds a custom shipping method named No Shipping Method with a price of $0.00 to the order.
  • Draft orders: the shopper sees No Shipping Method on the checkout and on the resulting order.
  • Still required: a shipping address, as with other shipping methods in the new experience.

Combo deals in the Promotions API and the control panel now support individual variants, so a combo can require specific variants of a product. You will see individual variants in combo deals over the coming weeks.

  • New variants branch: each branch of a combo condition can now target variants, a list of variant IDs, in addition to products, categories, or brands. Each branch still targets exactly one of them.
  • Control panel: in the Buys a combo of products condition, each combo item now offers Individual variants, so you can pick specific variants of a product.
  • Returned in responses: variants is included in the combo condition when you retrieve a promotion.

For details, see Create a promotion.

Apple Pay is now available for stores that use Worldpay Access, so shoppers can pay with Apple Pay through your existing Worldpay Access account.

  • Merchant setup: you can configure Apple Pay for a Worldpay Access profile in the control panel.
  • Shopper payments: shoppers can pay with Apple Pay on the cart, quick cart, and checkout pages.
  • Disconnecting Worldpay Access: Apple Pay switches off automatically when you disconnect your Worldpay Access account.

The Widgets REST API course is now Widgets in Stencil, reworked to cover both Page Builder and Makeswift and to introduce Widget Builder for local template development.

  • Both visual editors — the course introduces Page Builder and Makeswift, with new orientation labs for each, and explains which parts of the Widgets API each editor uses.
  • Widget Builder — a new setup lab introduces Widget Builder for creating, previewing, and publishing widget templates locally. It’s used in the schema array and GraphQL labs.
  • Reorganized modules — GraphQL is now Module 5. A new Module 6, Widgets and Page Builder, combines the widgets and placements lessons and clarifies that programmatic placement is specific to Page Builder.
  • Trimmed content — the Widget Versioning lesson, the Third-Party Widgets lesson, and its lab are removed, and the Placements lesson is condensed.
  • Updated links — the course has a new lesson count and duration, and old lesson URLs redirect to their new locations.

For details, see the Widgets in Stencil course overview.

The Developer Portal guide now includes steps for rotating your app’s client secret if it is exposed or you need to replace it for any other reason. The app guides also explain the states an app can be in.

  • App states. Types of apps now explains the draft, under review, published, and unlisted states, including who can install an app in each one and how to request unlisted status.
  • Rotate the secret. In the app editor, open the App information tab, find the Client credentials section, and click the refresh icon on the Client Secret row. The old secret stops working immediately.
  • Update your app right away. Copy the new secret into your app’s code and environment variables. New installs and signed payload verification fail until your app uses the new secret.
  • Existing installs are unaffected. Rotating the secret doesn’t change existing installs or the access tokens already issued to them.

For details, see Rotate the client secret.

Tax Provider API requests now include the date each operation was triggered, which tax providers can use to assign tax documents to the correct filing period.

  • operation_date on quote requests: an ISO 8601 formatted field available on the QuoteRequest sent with estimate, commit, and adjust operations. It does not affect tax calculation.
  • operation_date on void requests: void operations now send a VoidRequest body with the same operation_date field available.
  • Timezone: operation_date and transaction_date are provided in UTC or the store’s timezone settings, depending on provider preference.

For details, see Adjust tax quote and Void tax quote.

Fixes

We are rolling out a fix so that variants in the Product List appear in the same order as on the Add/Edit Product page. Over the coming weeks you will see this order when you expand a product.

  • Option order: variants sort by the order of the product’s options, then by the order of each option’s values.
  • Removed options or values: variants that no longer match an option or value on the product sort as if their value were first in order.
  • Simple products: products without variants are unchanged.

When you search or filter the product list, select all products, and then choose Edit inventory, the inventory editor will open with only the matching products instead of every product in your catalog. We are rolling this out gradually, and you will see the change in the control panel over the coming weeks.

  • Search and filters apply: the editor uses your search term and filters such as Brand, Category, Channel, and Out of stock.
  • Results still load page by page: you review and save changes one page of products at a time.

Adding a free theme from the control panel now returns the actual error from the theme registry instead of an “Invalid CSRF token” message.

  • Registry errors keep their own status and message. Before this fix, every error from the theme registry, such as adding a theme the store already owns, was reported as 403 “Invalid CSRF token”.
  • Real CSRF failures are unchanged. A request with an invalid CSRF token still returns 403 “Invalid CSRF token”.

BigCommerce has fixed an issue where some requests to the login flow failed with an error instead of loading the login page or completing sign-in.

  • Login requests complete as expected. Requests that pass through certain proxies no longer fail, so affected store owners and developers will see the login page and sign-in complete normally.

No action is needed.

When you edit an order in the control panel and change the quantity of a product that has a pick list option, the picked product now gets the new quantity. Before this fix, the change was applied to the picked product twice.

  • Quantity increase: changing the product from 1 to 2 gives the picked product a quantity of 2. Before, it got 4.
  • Quantity decrease: changing the product from 2 to 1 gives the picked product a quantity of 1. Before, it got 0.
  • Orders API: the picked product’s line in GET /v2/orders/{order_id}/products returns the corrected quantity.
  • Orders edited earlier: orders edited before this fix keep the quantities they were saved with.

The UPS reauthorization and tax provider unauthorized notifications on the control panel dashboard are now translated for the language of the user viewing them. Before this fix, both messages were stored and always displayed in English.

  • UPS reauthorization: the message asking you to reauthorize your UPS account is translated, including the link to your shipping settings.
  • Tax provider unauthorized: the message about your tax provider rejecting requests is translated, including the link to your tax settings.
  • No action needed: the English wording is unchanged, and no API behavior is affected.

Fixed a bug where the filter sidebar was missing from a storefront search results page when the request included category ID 0.

  • Affected requests: search pages opened with category=0, for example /search.php?search_query=shirt&category=0. The page loaded, but the filters were missing because the request for them failed.
  • Filters now load: the request completes and the sidebar shows the same filters as for any other category.
  • No changes needed: you don’t need to change your theme or your links.

We are beginning to roll out a fix so the Shopping Agent no longer covers the product Quick view popup on Stencil storefronts. You will see this take effect over the coming weeks.

  • Quick view popup: shows in full and stays usable while the Shopping Agent panel or button is on the page, instead of being partly hidden behind it.
  • Other theme popups: the same applies to other popups that use the theme’s modal, such as the add-to-cart confirmation.
  • Agent panel: when the popup closes, the Shopping Agent returns to where it was, with its conversation intact.

We are beginning to roll out a fix so that Stencil category pages keep rendering when product search, or another service the page depends on, fails or responds slowly. You will see these changes on category pages over the coming weeks.

Before this fix, a failure in one of these services returned a 500 error page or showed the category as empty, and a slow response held the page until the request timed out.

  • Filters unavailable: the page shows the category’s products and pagination without the filter sidebar. Filters already in the URL, such as brand, still narrow the products.
  • Prices or measurement units unavailable: the page still renders its products. Prices that fail to load are left out, and the store’s length and weight units from its display settings are used.
  • Product search unavailable: the page returns 503 Service Unavailable with a Retry-After header instead of an empty category, and is not cached. The theme receives category.search_error set to true; Cornerstone uses it to show a search error message in place of the product grid.
  • Filter settings unavailable or slow: loading the store’s filter settings now stops waiting after 5 seconds. If they can’t be loaded, the page renders without filters instead of timing out.

For details, see the category object in the Stencil object reference.

BigCommerce has fixed a bug where shoppers occasionally saw “An internal error occurred while trying to create your account” when submitting the storefront account creation form, most often on stores with high signup traffic.

  • Account creation is more resilient. The form no longer depends on two separate, independently failing lookups to resolve a shopper’s submitted country, removing an intermittent cause of failed signups.

You may notice fewer account creation errors on affected stores moving forward.

For details, see the Storefront Customers API overview.

Validating promotions with very large sets of rules is now faster, so large promotion requests are less likely to return a 502 Bad Gateway error.

Create a promotion and Update a promotion now return a 422 error when start_date is 2038-01-19T03:14:07+00:00 or later. Before this fix, such a request could save a promotion that the API could not load again, and every request that listed the store’s promotions then failed with a 500 error.

  • Start date. A start_date at or after 2038-01-19T03:14:07+00:00 returns a 422 error on start_date. Before, a request with such a start date and no end date returned 201 and saved the start date as 2038-01-19T03:14:07+00:00.
  • End date. An end_date after 2038-01-19T03:14:07+00:00 still works. The API saves it as 2038-01-19T03:14:07+00:00, as before.

For details, see Create a promotion.

We’re beginning to roll out a fix so cancelling an order no longer adds stock to a product or variant that is set to not track inventory. You will see the change in this area over the coming weeks.

  • No more unexpected inventory_level increases: when an order contained both a product that tracks inventory and a product that does not, cancelling the order added one unit per cancelled order to the untracked product’s inventory_level. The inventory_level of untracked products now stays unchanged after a cancellation.

Fixed a bug in the Developer Portal’s app scope editor where turning off Metafields Access (leaving it at its default, “Standard”) added the literal text Standard to the app’s OAuth scope list instead of omitting a scope entirely.

  • Invalid scope removed — apps that left Metafields Access at “Standard” generated an OAuth authorization URL with an invalid Standard scope value, causing BigCommerce to reject the request with an Invalid scope(s) error during installation or reauthorization.
  • Correct behavior — “Standard” is the off state for Metafields Access and grants no metafield scope. Only selecting “Full” adds the store_metafield_write_all scope.

If your app was affected, reinstall or reauthorize it after this fix to pick up a valid scope list.

For details, see Store Resource Scopes.

We are beginning to roll out a fix for Clover payments with American Express cards declined with the error “Destination postal code is required for AMEX”. You will see fewer of these declines over the coming weeks.

  • Destination postal code: BigCommerce sends the shipping postal code to Clover with the payment. For orders without a shipping address, such as digital goods, it sends the billing postal code.
  • No setup changes: you don’t need to change your Clover settings.

We are beginning to roll out a fix for storing an instrument with a type that the payment method doesn’t support. You will see a descriptive error instead of a generic one over the coming weeks.

  • Descriptive error: when you store an instrument with a type the payment method can’t vault, such as a tokenized_card for a payment method that only accepts a raw_card, the 422 response now returns the unsupported_instrument_type code. The message names the payment method, the type you sent, and the supported types.
  • No more generic message: these requests no longer return “Please, check your payload and try again.”
  • No setup changes: you don’t need to change your payment method settings. Requests that use a supported instrument type behave as before.

For the instrument types each payment method supports, see the stored instruments guide.

We are beginning to roll out a fix for a bug in the Storefront GraphQL API where an order’s status.label returned the default status name in English on stores without a multi-language storefront. You will see translated labels over the coming weeks.

  • Affected labels: the default order status names. For example, on a store whose storefront language is German, a completed order returned Completed instead of Abgeschlossen, while the Stencil order status page on the same store showed Abgeschlossen.
  • Translated labels: status.label now returns the default status name in the storefront language, the same label a Stencil storefront shows.
  • Custom labels: order status names you have customized return unchanged.
  • Status value: status.value, for example COMPLETED, doesn’t change. Base any logic on the order status on value, not label.
  • No request changes: you don’t need to change your queries. Storefronts that display status.label, such as the Catalyst account order pages, show the translated label automatically.

For details, see the orders field on the customer query.

We are beginning to roll out a fix for a bug in the Storefront GraphQL API where the displayCurrencyCode argument of the @shopperPreferences directive didn’t change the currency of a POST /graphql request. You will see this take effect over the coming weeks.

  • Affected requests: queries and mutations that pass @shopperPreferences(displayCurrencyCode:). Prices returned in the currency from the shopper’s cookie or country instead of the requested currency. For example, a product priced at 49.00 USD returned 49.0 USD instead of 24.5 EUR when the request asked for EUR.
  • Requested currency applies to the whole request: prices now return in the currency that displayCurrencyCode names, and the cart and shopper session receive the same canonical currency code.
  • No request changes: you don’t need to change your queries.
Request prices in euros
query @shopperPreferences(displayCurrencyCode: "EUR") {
site {
product(entityId: 77) {
prices {
price {
value
currencyCode
}
}
}
}
}

We are beginning to roll out a fix so that paging through relevance-sorted product search results in the Storefront GraphQL API stays consistent from one page to the next. Over the coming weeks, every store will get the fix.

  • Affected requests: searchProducts queries sorted by RELEVANCE that you page through with after. Previously, a product near the boundary between two pages could appear on both pages, or on neither.
  • What changes: each page of one search is now answered consistently with the pages before it, so a product appears once across the full set of results.
  • What stays the same: other sort options, such as A_TO_Z, LOWEST_PRICE and HIGHEST_PRICE, were not affected. No fields, arguments or response shapes change.

We are rolling out a fix for BigCommerce staff who open B2B Edition from a store’s control panel. Over the coming weeks, a staff member who opens the app to help with your store will no longer be added to your B2B Edition System Users list.

  • Hidden from your lists. The staff member gets a support role that doesn’t appear in your System Users or Roles lists and doesn’t count toward your system user limit.
  • Independent of your default role. The staff member no longer receives the role you set as the Default Role for New System Users, so support access doesn’t depend on that setting.
  • Existing users unchanged. Staff system users created before this fix are not affected by it.

No action is needed.

When you open a company address to edit in B2B Edition in the control panel, any field that does not meet the form’s requirements now shows its error straight away, so you can see why Save is unavailable.

  • Edit address - after you open an address from B2B > Companies > a company > Addresses, each field that already fails validation shows its error, for example a missing zip code or a phone number in a format the form does not accept. Before, Save was disabled with no error shown. This mostly affects addresses created through the API.
  • Unchanged - the validation rules are the same, and adding a new address behaves as before.

When you pass --env-path, the Catalyst CLI now uses that file for both the build and the deployed storefront, so a deploy can no longer build with one set of values and run with another.

  • Only that file is read: .env.local and .env on disk are no longer read by the build or included in the deployed worker as runtime fallbacks.
  • deploy sends the file to the deployment: its variables reach the deployed storefront, including with --prebuilt.
  • New precedence: --secret overrides the --env-path file, which overrides values saved with catalyst env add. The CLI lists the saved keys the file overrides.

If you rely on saved values overriding the file: when you deploy with --env-path, the file’s values now win over values saved with catalyst env add. Move those values into the file or pass them with --secret.

For details, see the Catalyst CLI reference.

The Storefront GraphQL API no longer returns Google Pay and Amazon Pay wallets from the paymentWallets query for Catalyst storefronts, so headless checkouts no longer render wallet buttons that Catalyst does not support yet.

  • What changes: For requests from Catalyst storefronts, paymentWallets omits Google Pay and Amazon Pay wallets. Other wallets, such as PayPal, are still returned.
  • Who is affected: Catalyst storefronts that render wallet buttons from paymentWallets. Stencil storefronts and other consumers of the query are not affected.

Sales channels in the Requires Action status can now open their sales channel app, and are now disconnected when that app is uninstalled.

  • Opening the app — a channel in the requires_action status could not open its sales channel app, for example the Feedonomics app. The app now opens for these channels the same way it does for connected channels.
  • Uninstalling the app — uninstalling an app did not disconnect its channels in the requires_action status, because only connected channels were disconnected. These channels now move to disconnected on uninstall, the same as connected channels. Channels in other statuses are unchanged.

Universal Commerce Protocol (UCP) orders now report the discounts applied to them, so an order’s totals add up to its total. Previously, a discounted order’s totals left the discount out, and completing a checkout session dropped the discounts the session had shown. We’re beginning to roll this out, and you will see discount details on UCP orders over the coming weeks.

  • Order discount totals: the order resource and order webhooks include discount and items_discount totals for order-level and item-level discounts, using the same types and negative amounts as checkout sessions.
  • Fulfillment before shipping discounts: the order’s fulfillment total is reported before shipping discounts, as checkout sessions report it, and shipping discounts are counted in the discount totals instead.
  • Discounts on completed checkout sessions: completing a checkout session returns the same discounts and line item items_discount totals the session showed before completion.

Orders placed before discount details were recorded don’t include discount totals.

Also this week