GigaCommerce

When AI Shopping Quotes the Wrong Price

AI shopping quotes the wrong price when schema, Shopify discounts, and Amazon coupons disagree. Align the offer before peak, then run a free readiness score.

Sujan BhuiyanFounder, GigaCommerce12 min read
AGENTIC COMMERCEGigaCommerce · Insights

AI shopping quotes the wrong price when the amount on the product page, the amount in structured data, the amount at checkout, and the amount on Amazon are four different numbers. The quote an assistant should give is the price a shopper pays right now: the live selling price, in the currency shown on the page, with any public sale already applied. A compare-at figure, a coupon that still needs a clip, or a “was” line in a bullet is context. It is a second fact, and it has to be labeled as one.

This briefing is for Shopify and Amazon operators in the $100K–$10M range heading into peak. It names the four prices that drift apart, walks a worked offer, and gives a same-week drill so assistants stop citing a number your checkout will not charge.

Why assistants cite a single number

A shopper can see $64 crossed out, $48 in bold, and a 15% banner, and still do the math. An assistant recommending the product has to say one number. If your data offers four candidates, it picks the first figure in the description, the schema price, or a cached sale from last month. The shopper arrives expecting that figure. Checkout shows another.

The gap shows up where you already spend money. A Brand Agent that states compare-at as the current price creates a ticket the moment the cart loads. The first 30 days after launch are the cheapest window to catch that. On Amazon, a detail page can show a current price, a list price, a coupon, and a Subscribe & Save price together, and a bullet that says “was $64” hands any reader a second number with no label. On Google, Merchant Center’s “Mismatched product price” article says a disagreement between the price in your product data and the price on the landing page can disapprove the item. Structured data has to match the price the user sees, and a sale the user would actually pay belongs in that markup.

A check that only asks whether Product schema exists will miss this. The agentic commerce readiness checklist already flags live price and availability. This post is the price half of that check, written so a team can run it.

The four prices that usually disagree

Pick one hero SKU and write down every price a machine could read. Mid-market brands usually find four.

Shopify selling price versus compare-at

Shopify stores a variant’s selling price in cents. Themes that follow the Dawn pattern emit Offer.price as that value divided by 100, along with priceCurrency from the shop currency and an availability URL such as https://schema.org/InStock. That selling price is the number the assistant should quote for a one-time purchase at the price currently on the variant.

Compare-at (compare_at_price) is the crossed-out reference. It belongs beside the selling price, labeled as a reference, when you have a real prior price to show. It does not belong in Offer.price.

Google’s product-snippet documentation states a tie-break you can test: if you put an active price in both offers.price and offers.priceSpecification, Google uses offers.price and ignores the specification. So the safe pattern is:

  • Offer.price and Offer.priceCurrency = the live selling price.
  • A UnitPriceSpecification with priceType set to https://schema.org/StrikethroughPrice = the compare-at amount, and only when that amount is a real reference price you are allowed to show.

highPrice and lowPrice describe an AggregateOffer range across variants. They do not encode “was $64, now $48” on one variant. priceValidUntil belongs only on a price that actually ends. A fake expiry makes assistants drop a live price, or keep a promotional price after the promotion ended.

Checkout discounts the schema never sees

Automatic discounts and some discount codes apply in the cart, after the product JSON-LD has already been rendered. The PDP can say $48 in HTML and in schema while checkout charges $40.80 because a 15% automatic discount fired.

Google’s price rules require the submitted amount and currency to match the landing page and checkout. For an advertised sale, show both the non-sale price and the sale price on the landing page, charge the sale price at checkout, and keep it consistent through checkout. An advertised coupon has to be available to users generally, with both prices visible once it is applied.

Two practical rules keep the Brand Agent and the feed honest:

  1. 1If every shopper gets the discount with no code, the price on the PDP, in Offer.price, and in the feed should already be the discounted amount — or the PDP must show both numbers with the sale as the current price.
  2. 2If the discount is a code for a segment (welcome, SMS, VIP), the public price stays the variant price. The agent may mention the code only when your policy says that code is public. A code buried in a popup is a poor fact for an assistant to promise to a stranger.

Copilot Checkout and any other agent-mediated purchase will charge whatever Shopify calculates. If you have not tested the discounted path, read the edge-case section of the Copilot Checkout configuration guide before you let an assistant promise a price.

Amazon price, coupon, and Subscribe & Save

Amazon’s detail page is allowed to show more than one figure. The current price is what a one-time buyer pays before a coupon. A list price, when Amazon displays it, is a reference and has to meet Amazon’s list-price rules — a recent price you charged or another substantiated reference, not a number invented for a strikethrough. A coupon changes the price only after the shopper clips it. Subscribe & Save shows a lower recurring price that a one-time buyer does not pay.

Quote the current price for “what does it cost?”, the clipped amount only when the shopper asks about the coupon, and Subscribe & Save only for a subscription. A bullet that says “was $64” with no date gets repeated as the offer. Coupon depth also changes weekly in peak. The person who owns the Amazon offer for a SKU should be able to see the Shopify price the same day, so a marketplace promo does not become the number your site agent cites for the DTC SKU. Amazon marketplace operations is where listing price, coupons, and list-price compliance get fixed. The Shopify agent still needs an explicit line when the channels differ: “DTC price is $48. The Amazon offer is priced separately and may include a coupon.”

Feed price versus the page a crawler actually receives

Merchant Center can update price from your landing-page markup when automatic item updates are on, and it can disapprove the item when the feed and the page disagree. For the match to work, Google’s structured-data setup for Merchant Center requires the markup in the HTML returned by the server. Markup injected only after JavaScript runs is invisible to that crawl. The price in that HTML must use a period as the decimal separator (48.00, not 48,00).

Merchant Center’s setup notes also say landing-page price must not change based on user information such as IP address if you want markup to match product data. A theme that swaps currency in the browser after load, while the first HTML response contains a different amount, breaks that match. Several currencies means several Offer objects, each with its own priceCurrency. On a URL with multiple variants, each offer needs a SKU or GTIN that matches the feed, or neither Google nor an assistant can tell which price belongs to which unit.

$40.80

Checkout price in the worked example after a public 15% discount on a $48 Shopify variant. Compare-at still reads $64. Schema that only emits the variant price still reads $48. Amazon at $49.99 with a 20% clip lands at $39.99.

Illustrative offer for an audit drill. Arithmetic you can reproduce. Not a client result.

What a mismatched quote does to the sale

Take that hero SKU and put the four numbers in one row. The product is a mid-weight hoodie, one colorway, sold on Shopify and on Amazon.

| Surface | Amount | What it actually is | |---|---|---| | Shopify compare-at | $64.00 | Reference price, crossed out on the PDP | | Shopify variant price | $48.00 | Live one-time price before the automatic discount | | Checkout after 15% automatic | $40.80 | Amount charged if the discount applies to everyone | | Offer.price in the theme JSON-LD | $48.00 | What many themes emit from variant.price | | Amazon current price | $49.99 | One-time marketplace price | | Amazon after a 20% coupon clip | $39.99 | Conditional price, only after clip |

Asked “how much is this hoodie?”, an assistant can answer any of those six figures. For a shopper who lands on the DTC page and gets the public 15% discount, the citable price is $40.80. Label $48 as the pre-discount variant price and $64 as the older reference, or leave them out of the quote. A cart that disagrees with the cited price bounces or refunds, and Merchant Center can drop the Shopping row for the same mismatch.

Track it beside agent-referred revenue. The agentic commerce ROI piece already separates those sessions. Add PDPs whose schema price differs from the cart by more than a rounding cent. That backlog does not show up inside ACoS.

A “was” price with no history

Compare-at on Shopify and list price on Amazon both claim a real higher price. If you cannot point at that prior price, remove the strikethrough.

A same-week price-truth drill

Run this on the 25 SKUs with the most revenue in the last 90 days, plus any SKU in a live promotion. The same Liquid runs on every product, so this sample exposes a theme-level schema bug.

  1. 1

    Export the live selling price

    From Shopify, export variant price, compare-at price, and SKU for the 25. Note which discounts are automatic and which need a code. Calculate the checkout amount for the automatic case (a 15% discount on $48.00 is $40.80, not “about $41”).

  2. 2

    Read the HTML, not the app preview

    View source on the PDP, or use Google’s Rich Results Test, and find Offer.price, priceCurrency, and any priceSpecification. Confirm the markup is in the server HTML. Confirm Offer.price equals the amount you want quoted, using a period as the decimal separator.

  3. 3

    Add the reference price only as strikethrough

    If compare-at is real, encode it as a strikethrough price specification. Leave Offer.price on the live amount. Delete priceValidUntil unless the sale has a calendar end.

  4. 4

    Place the same order the assistant would

    Add the variant to cart in a clean browser. Confirm the charged price matches the number you decided is public. If a code is required, confirm the PDP does not promise that code in schema or in the first paragraph.

  5. 5

    Reconcile Amazon on the same row

    For each SKU with an ASIN, record current price, list price, coupon, and Subscribe & Save. Write one sentence your Brand Agent is allowed to say about the Amazon price. If the channels differ on purpose, that sentence should say they differ.

  6. 6

    Fix the feed the same day

    Update Merchant Center price and, when you are in a real sale, sale_price plus the effective dates, so the feed matches the landing page and checkout. Recheck the variant identifier (SKU or GTIN) on multi-variant URLs.

The output is a sheet with one public price per SKU, the schema snippet that states it, and a yes/no on whether checkout matches. Keep conflicting SKUs out of peak creative. If every row shows the theme emitting variant price and never a strikethrough specification, fix that once in Liquid. Check compare-at values per SKU, because a vanity anchor is a content error, not a theme error.

Publish one price an assistant may cite

Put the decided price in the five places that get quoted.

  • Product page. The current price is the primary figure. Compare-at is secondary and crossed out. A public automatic discount is already inside the current price, or both numbers are on the page with the lower one marked as the price now.
  • JSON-LD. Offer.price is that current amount. priceCurrency is the ISO code (USD). Strikethrough lives in priceSpecification. One offer per variant when prices differ, each with a SKU or GTIN.
  • Agent source. Paste a short rule: “Quote Offer.price for the selected variant. Mention compare-at only as a reference price. Mention a code only if it is in the public offers metafield. Say that Amazon is priced separately when the SKU has an ASIN.” That rule is part of Agentic Commerce Setup: the agent stays as current as the offer data you maintain.
  • Amazon. Update the current price, the coupon, and any list price together with the bullets. Remove “was” claims that do not match the list price on the detail page.
  • Feed. For a timed sale, price is the non-sale amount, sale_price is the current amount, and the landing page shows both. With no separate sale, price matches the page and the checkout.

Recheck a SKU the day its price, discount, coupon, or end date changes, and pass the full 25 weekly through peak. A priceValidUntil of 30 November that nobody extends makes a careful agent drop a price that is still correct. A missing end date leaves November’s deal quotable in January. Attribute work answers “what is it?” This drill answers “what do I pay?”

Get a free Agentic Commerce Readiness Score

Ten minutes. See whether price, availability, and catalog facts are strong enough for an assistant to quote you without guessing.

Frequently asked questions

Should Offer.price be the amount before or after an automatic discount?

Use the amount the shopper pays when the discount applies to everyone and needs no private code. A 15% automatic discount that takes $48.00 to $40.80 means $40.80 is the price the landing page, schema, and feed should share, with $48.00 labeled as the pre-discount figure if you show both. When the lower price needs a code that is not offered to all users, keep `Offer.price` at $48.00 and keep $40.80 out of the agent’s promise.

Can I put compare-at price in Offer.price to show a bigger discount?

Keep compare-at out of `Offer.price`. That field is the current offer. Google’s product-snippet docs use `offers.price` as the active price when both `offers.price` and `priceSpecification` are present. Put the live amount in `Offer.price` and a genuine compare-at in a strikethrough price specification. Inflated compare-at values also conflict with platform rules on reference prices.

What if my Shopify price and my Amazon price are supposed to be different?

Keep them different, and label them. The DTC agent quotes the Shopify public price. It describes Amazon as a separate offer — current price, coupon, Subscribe & Save — only from source content your team updates with the listing. One unlabeled number in a bullet gets quoted for both channels.

How often should we recheck price truth during peak?

Recheck a SKU the day its price, compare-at, automatic discount, coupon, or sale end date changes, and pass the top 25 weekly through peak. A Sunday end date still sits in schema on Monday if nobody owns `priceValidUntil` and the feed’s sale window. A weekly pass is a few hours. A week of expired quotes costs more in refunds and disapprovals.

Will correct schema stop an assistant from quoting an old price?

Current schema fixes what a fresh fetch can see. Assistants and search systems also cache, so an updated page, a real `priceValidUntil`, an updated feed, and copy that has dropped the old amount give the next fetch one consistent story. Align the page, the markup, the checkout, and the Amazon offer so that next citation has a single defensible number.
SB

Sujan Bhuiyan

Founder, GigaCommerce

Founder of GigaCommerce, part of Gigaverse. Works with mid-market Shopify and Amazon merchants on agentic commerce installs, AI-ready catalogs, and Commerce GEO.

The weekly brief

Get the weekly DTC + Agentic Commerce brief.

One email a week on what shipped in agentic commerce and the move to make. No fluff.