Cannot fetch Company Location catalog price via Storefront API

Short description of issue

I’m using Catalogs for a Company Location. The original product price is $250, and the catalog applies a -10% adjustment, resulting in a price of $225. I’m querying products using the Storefront API on the Online Store, but the adjusted price is not returned. How can I retrieve the correct catalog price ($225) via the Storefront API? This works as expected with Market-type catalogs, but doesn’t seem to work with Company Location catalogs on the Online Store.

Reproduction steps

query getProducts($country: CountryCode!, $language: LanguageCode!, $buyer: BuyerInput)
@inContext(country: $country, language: $language, buyer: $buyer) {
product(handle: “product-1”) {
variants(first: 250) {
nodes {
id
price {
amount
}
}
}
}
}

Additional info

What type of topic is this

Troubleshooting

Upload screenshot(s) of issue

Hi @Karl_RH,

In order to receive the product prices adjusted for the B2B Company location, you do need to pass a specific customer’s customerAccessToken and companyLocationId that the customer is associated with in the Buyer Identity input of the @inContext directive.

This is described in the Shopify.dev documentation here, with the following example:

This example shows how to return a product’s price amount contextualized for a business customer buyer @inContext(buyer: {customerAccessToken: 'token', companyLocationId: 'gid://shopify/CompanyLocation/1'}) .

More info on this workflow is also found here:

If you believe you are passing the @inContext directive correctly, per the documentation I linked above, please provide us with an x-request-id from the Response Headers of an API call not returning the adjusted pricing expected, and we can take a further look into the specific example.

I’ve been trying to use @inContext (Buyer Identity), but I’m stuck on obtaining the customerAccessToken. As mentioned, I’m on the Online Store. How can I retrieve the customerAccessToken if the customer is already logged in?

Hi @Karl_RH,

Thanks for that additional context. In this case since you’re developing for the Online Store, the Storefront API is not actually the way to go for this. The Storefront API is meant for Headless Storefronts using the Headless or Hydrogen Sales Channels, or 3rd party apps. If you’re developing the storefront using Themes on the Online Store channel, you should use Liquid Objects instead instead of Storefront API calls to display the product prices..

In this case, the Product and Product Variant’s price field in Liquid, will automatically return the market or catalog adjusted price based on the customer that is currently logged in to the storefront, by simply adding the liquid tag to your theme code.

For example: {{ product.price | money }}

If you were to continue using the Storefront API, or was developing for a headless storefront instead of an Online Store storefront, you’d need to get the customer access token via the Customer Account API, as described in the documentation I linked previously.

Thanks for your response.

I’ve updated the implementation to use the Product and Product Variant price fields in Liquid, and pricing is now resolved correctly.

However, I’m encountering an issue when working with markets of type COMPANY_LOCATION. Specifically, I’m unable to retrieve the correct market information (e.g., market ID or handle) for customers assigned to this type of market. For example, {{ location.market.id }} does not return the expected value in this context.

Could you clarify the correct approach to access market data for COMPANY_LOCATION-based customers?

Hi @Karl_RH,

So the {{ location }} object doesn’t actually have a market field, per the documentation.

I think in this case, you’ll want to use the {{ customer.current_location}} liquid object, to get information about the current company location the customer session is using.

Here’s some more documentation about working with B2B customers and company locations in Liquid. If this doesn’t help, can you share some more context on what you’re trying to do exactly and why it’s not working, what’s returning vs what you expect it to return?

Apologies for the typo, I meant {{ localization.market.id }}.

I’ve tried customer.current_company and customer.current_location, but this requires replicating Shopify’s market resolution logic and still doesn’t match Shopify’s behavior, especially when a company location belongs to multiple markets.

For example, a London company location is assigned to both London market and North London market (each with its own catalog). My logic resolves the London market, while Shopify resolves the North London market. As a result, the storefront context differs from the pricing context.

Could you clarify if there is a deterministic method or object in Liquid to reliably retrieve the current market used by Shopify for pricing and storefront rendering?

Hi @Karl_RH,

Great question, and the mismatch you’re seeing is actually expected behaviour in this case with B2B Buyers and B2B catalogs.

For B2B buyers, the pricing context and the localization context are resolved independently and can legitimately disagree. A Company Location can belong to several Markets at once (e.g. London and North London), and Catalogs can be attached either to a Market or directly to a Company Location. When a B2B Company Location has its own Catalog, that Catalog takes precedence over any Market-level Catalog for pricing, there isn’t a single “current Market” that drives the price in this scenario, so any logic that picks one Market and re-derives the price from it will diverge from what the storefront actually charges.

localization.market is intended for the localization experience (the country/language/currency selector, market-aware metafields, etc.) and resolves to a region-based Market for the buyer. It’s not guaranteed to be the same Market whose Catalog produced the displayed price, especially for B2B buyers whose pricing comes from a Company Location Catalog or from a more-specific Market with its own Catalog. There is no Liquid object that exposes “the Catalog used to price this variant”, which is deliberate, since the contextualized price is already exposed directly on the product and variant objects.

The pattern we recommend for B2B themes:

• Use {{ product.price | money }} and {{ variant.price | money }} (and compare_at_price, unit_price, quantity_price_breaks, etc.) — these are already adjusted for the logged-in customer’s Company Location and Catalog. You don’t need to resolve a Market or Catalog yourself to get the right number.
• Use {{ customer.current_location }} for the active Company Location (name, ID, address, metafields, tax registration). See company_location.
• Use {{ customer.current_company }} for the parent Company.
• Use {{ localization.market }}, {{ localization.country }}, and {{ localization.language }} for localization UI only — and treat the Market it returns as a localization signal, not as the source of pricing.

More background:

Support B2B customers in your theme
Liquid object: customer
Liquid object: company_location
Liquid object: localization
Liquid object: product / variant

If there’s a specific theme behavior you’re trying to drive off the Market (a market-specific banner, a metafield lookup, etc.), let us know what you’re trying to do exactly and we can suggest the closest stable signal, but for pricing, the variant and product price fields are the source of truth and you don’t need to derive a Market to use them.