---
title: 'Live Commodity Pricing on Shopify with Sanity | Skai'
description: 'Keep Shopify metal prices tied to spot rates with Sanity pricing rules. Learn the Goldsource architecture, spike checks, lockdown and safe sync workflow.'
canonical_url: 'https://www.skaidigital.com/guides/shopify-live-commodity-pricing'
markdown_url: 'https://www.skaidigital.com/guides/shopify-live-commodity-pricing.md'
date_modified: '2026-10-28'
last_updated: '2026-10-28'
---

# Live commodity pricing on Shopify with Sanity

By [Ragnsan Finn Valla, Founder](https://www.skaidigital.com/about#ragnsan)

A standard Shopify product price is a stored amount. A precious metals store needs an amount that follows the market: the metal weight multiplied by the spot rate, with a commercial markup. Updating a number is the easy part. Preventing a customer from buying at a stale or broken price is the real integration problem.

This guide explains the setup Skai built for [Goldsource](/case-studies/goldsource): Sanity holds the pricing rules, a scheduled service reads market rates from XE, and Shopify receives the calculated prices. The useful lesson is the safety system around that calculation, not a promise of continuous quotes or a particular trading strategy.

## The architecture: rules, rates, prices and history

Keep responsibilities separate. Editors own the commercial rules. The rates provider supplies market data. The pricing service combines them. Shopify receives the sellable price, while the storefront reads a refreshed price cache.

```diagram
type: steps
title: From pricing rules to storefront prices
step: Read Sanity pricing rules
note: Metal, weight in troy ounces and markup mode define each product's calculation.
step: Fetch and validate rates
note: Goldsource uses XE; market-hours and spike checks decide whether the run can proceed.
step: Calculate and write prices
note: The service updates Shopify through productSet, processing several products in parallel.
step: Refresh the price cache
note: Replace the storefront price snapshot after the sync rather than publishing it piecemeal.
step: Store price history
note: A separate daily job records the history used by the storefront chart.
```

In Goldsource's setup, Sanity holds the metal, metal weight in troy ounces and markup mode for each product. The modes are a fixed amount over spot, a percentage over spot, or a flat price that ignores the market. The scheduled job runs on a short schedule and writes each calculated price through the [Shopify Admin GraphQL API's `productSet` mutation](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productSet), targeting the product's default variant.

A separate per-product endpoint prices a product when it is first published, rather than leaving it at zero until the scheduled run. Treat initial pricing as part of making a product sellable: if it cannot complete, do not make that product available for purchase. In your own implementation, apply the same validation and serialization to both entry paths.

After the sync, the price cache used by the storefront is refreshed in one write. That keeps the displayed snapshot aligned with the prices sent to Shopify. It is not a transaction across Shopify and the cache: your implementation still needs a policy for partial writes and a failed cache refresh. Do not claim the run completed while those disagree. The daily history job supplies the historical price chart, separately from the current sellable price.

## Model the calculation before the integration

For a spot-linked product, calculate the metal value as weight multiplied by the rate for that metal. Apply the selected markup to that value. A flat-price product bypasses the market calculation. Make those modes mutually exclusive so an editor cannot accidentally combine them.

Define the rate currency and weight unit explicitly. A troy-ounce weight cannot safely be multiplied by a rate quoted in another unit without conversion. Decide how purity, fabrication costs, tax treatment and rounding enter your own commercial model; do not assume a spot feed includes them. Reject missing, negative or non-finite inputs rather than coercing them into a price.

Use Sanity's [schema types](https://www.sanity.io/docs/studio/schema-types) and [validation documentation](https://www.sanity.io/docs/studio/validation) when designing the editorial contract. Validate again in the pricing service before writing money. Define a narrow query contract using the [GROQ documentation](https://www.sanity.io/docs/content-lake/groq-introduction). This is an application design, not a pricing engine supplied by Sanity.

For product identity, publication and sync ownership, start with our [Sanity-to-Shopify product sync guide](/guides/sanity-shopify-product-sync). The pricing worker should not compete with another worker that also writes prices: assign ownership explicitly and route competing updates through the same coordination boundary.

## Safety rails are the core of the system

### Lock the run and reject duplicate deliveries

Goldsource's scheduled workflow uses a lock to prevent overlapping runs and duplicate processing of the same scheduled run. These solve different problems. Mutual exclusion stops concurrent workers; a durable record of the scheduled execution stops a completed delivery from running again.

For a new build, acquire the lock before reading the working snapshot, retain ownership while writing and release it safely. Plan for a worker crash and an expired lease. A worker that has lost ownership must not keep writing. Coordinate first-publication pricing with scheduled pricing too, so an older calculation cannot overwrite a newer product rule.

### Respect market hours

Goldsource skips the run when the metals market is closed rather than writing prices. Make that an explicit skipped outcome, not an apparent success with no changes.

Choose a market calendar appropriate to the feed and instruments you sell. Market closure is not the same as a provider outage. Document what customers may buy while the market is closed, and separately define when the last accepted rate becomes too old to use. Do not let an intentional skip hide a broken feed when trading resumes.

### Detect spikes and enter lockdown

Goldsource compares incoming rates with the recent average. If a rate moves too far, the sync is skipped, the store enters lockdown and the team receives an email alert. The storefront shows a full-screen notice whose title and text the team can edit in Sanity.

The comparison is a guard against an unsafe input, not proof that the market is wrong. A genuine market move can trigger it too. Investigate the provider response and commercial exposure before accepting a new baseline. Do not automatically teach the detector that repeated rejected values are normal.

For your own store, a visible notice is only part of lockdown. Verify that purchase entry points, existing carts and checkout paths cannot bypass the protection. A page overlay alone is not evidence that checkout is blocked. The correct enforcement mechanism depends on your storefront and checkout design; this guide does not establish a universal Shopify checkout lock.

### Classify provider errors and log every outcome

Goldsource retries provider rate-limit errors, stops the run on authentication errors and records every run as completed, skipped with a reason, or failed. Keep the distinction visible to operators. Repeated skipped runs can be as important as a failed run if the store is relying on old prices.

For Shopify writes, use its [official API rate-limit guidance](https://shopify.dev/docs/api/usage/limits) to budget requests and handle throttling. Processing several products in parallel is not permission to send unbounded requests. Inspect mutation errors as well as transport errors, and reconcile an uncertain write before deciding it is safe to retry.

Record which input snapshot was accepted, which products were updated and whether cache refresh completed. Alert on stale accepted rates, incomplete writes and failed recovery. Set a purchase-blocking policy before the feed fails, not while deciding whether yesterday's price is still acceptable.

## Why put the rules in Sanity?

The useful distinction is editorial ownership. Markups, product attributes and lockdown copy belong in a workflow the commercial team can understand. With a deliberately designed Sanity schema, editors change those values without a code deploy; the pricing service remains responsible for accepting and applying them safely.

Our [Sanity implementation overview](/technology/sanity) explains the broader content layer. Keep it balanced: [Shopify metafields](https://shopify.dev/docs/apps/build/custom-data/metafields) may be enough for a handful of products, one metal and no custom editorial workflow. A spreadsheet can help establish a formula, but should not become an unvalidated, manually copied production feed.

Choose Sanity when the editorial workflow justifies another system, not because live pricing inherently needs a headless CMS. If that decision is still open, read our [Shopify CMS guide](/guides/shopify-cms).

## How to build it yourself

Use this as an implementation checklist, not a production-ready recipe:

- **Model the rules.** Define metal, troy-ounce weight, markup mode, required values and currency. Specify who can change them and validate the same contract in the worker.
- **Choose a rates provider.** Check metal coverage, quotation units, timestamps, licensing, outage behavior and authentication. Goldsource uses XE; assess suitability for your own market rather than assuming providers are interchangeable.
- **Write and test the calculation.** Cover each markup mode, invalid input, rounding and stale rates. Keep the accepted rate snapshot stable throughout a run.
- **Write to Shopify.** Resolve stored product and variant identities and inspect `productSet` errors. Its [list-field semantics](https://shopify.dev/docs/api/admin-graphql/latest/mutations/productSet) matter: omitted entries in a supplied list can be deleted. Do not send a default-variant-only list for a multi-variant product.
- **Add publication pricing.** Use the same calculation and safety policy before a newly published product becomes purchasable. Authentication and duplicate delivery handling belong on this path too.
- **Add the lock and market calendar.** Exercise overlapping deliveries, duplicate runs, worker crashes and lost lock ownership. Record intentional skips with their reasons.
- **Add spike detection and lockdown.** Test the notice, alert and actual purchase restrictions. Define a reviewed recovery procedure rather than automatically clearing an unsafe state.
- **Refresh caches after confirmed writes.** Publish the price snapshot in one write. On partial failure, reconcile Shopify and keep affected purchases blocked until the displayed and charged prices agree.
- **Store history and monitor.** Keep historical chart data distinct from current-price authority. Test provider throttling, revoked access, malformed responses, stale data and failed cache refreshes before launch.

## When to use this, and when not to

Use this pattern when commodity exposure is part of your product economics and manual repricing creates unacceptable operational risk. It fits a Shopify precious metals store with explicit weight-based rules and an operating team responsible for incidents.

Do not use it merely to imitate a live ticker. A business selling mostly fabrication, design or collectible value may need stable retail prices instead. Nor is this a trading platform or a guarantee that a displayed quote remains valid indefinitely. Define when a price is accepted and what happens when the market changes during a buying journey.

## Frequently asked questions

### Can Shopify update prices automatically from the gold price?

A custom integration can read a market feed, calculate product prices and write them to Shopify. The feed, calculation and safeguards are application responsibilities, not a built-in spot-price setting.

### How often should prices update?

Choose a cadence from your exposure, feed freshness and operating capacity. A short schedule still needs market-hours checks, overlap protection and a policy for stale rates; scheduling alone does not make a price safe.

### What happens if the price feed breaks?

Do not substitute a missing rate or silently keep selling indefinitely. Retry rate limits within a bounded policy, stop on authentication failures, alert the team and apply your stale-price purchase-blocking policy.

### Does this cover Shopify Markets and multiple currencies?

No. This guide covers calculating a base product price, not a complete international pricing implementation. Market-specific prices, conversion, rounding and taxes need a separate design and checkout verification.

For that separate design, start with Shopify's [contextual variant pricing reference](https://shopify.dev/docs/api/admin-graphql/latest/objects/ProductVariant#field-ProductVariant.fields.contextualPricing), rather than assuming a base-price update defines every market's customer price.

### Can I do this without a headless storefront?

The backend price-writing pattern does not require a headless storefront. A theme-based store still needs its own display-refresh and purchase-blocking design; the custom Goldsource storefront notice is not a drop-in theme feature.

## Plan the pricing workflow

Bring the pricing formula, rate-feed contract and failure policy to the architecture discussion. Our [headless Shopify agency service](/services/headless-shopify-agency) is the place to discuss how the storefront, rules and operations fit together.

[Book a discovery call](/book)


## About the author

[Ragnsan Finn Valla](https://www.skaidigital.com/about#ragnsan) — Founder, Skai Digital

Founder of Skai Digital. We build headless Shopify stores with Sanity as the brain: all five storefronts for Verandah Brands, a $45 million ecommerce company, on one platform, plus +102% sales for Goldsource, B2B portals, integrations and AI agents. I write about running Shopify catalogs from Sanity.

[LinkedIn](https://www.linkedin.com/in/ragnsan-finn-valla)

