# Shopify variant price to price

The Shopify variant price is the amount a customer pays in the store currency, and the feed price has to match what the shopper will see on the landing page. What makes this non-trivial is tax treatment, currency formatting, and every discount mechanism that never touches this field.

- **Canonical URL:** https://www.feedlab.io/knowledge/mappings/shopify-variant-price-to-price
- **Last reviewed:** 18 September 2026
- **Source:** feedlab knowledge base
- **Licence:** free to quote and cite with attribution to feedlab


## The Shopify side

| Property | Value |
| --- | --- |
| API field | `variant.price` |
| Called | Price |
| Found at | Product → Variants → edit variant → Pricing → Price |
| Feeds | `price` |


## Before and after

| In Shopify | In the feed | Note |
| --- | --- | --- |
| `49.00 (GBP store)` | `49.00 GBP` | Amount and ISO code, no symbol. |
| `1234.50` | `1234.50 GBP` | No thousands separator. A comma here is read as a decimal point by some parsers. |
| `49.00 (OpenAI feed)` | `"49.00 GBP"` | One string containing amount and currency for that channel. |
| `49.00 with DE market price 56.00` | `56.00 EUR in the German feed` | The market price, not the converted store price. |
| `49.00 with a 10% automatic discount` | `49.00 GBP` | The discount is applied at checkout and is invisible here, which is why the page and the feed disagree. |



## The transformation, step by step

1. **Read the price from the variant** — Price is per variant, so a large costing more than a small is normal and a product-level feed cannot express it. This is one of the clearest reasons a feed has to be variant level.
2. **Format the amount consistently** — Two decimal places, a full stop as the decimal separator, no thousands separator and no currency symbol in the number. A comma as a decimal separator is read as a thousands separator by some parsers, which turns 1.234,00 into a very different price.
3. **Attach the currency the way the channel expects** — Most channels take the amount with an ISO code alongside, as "49.00 GBP". OpenAI wants exactly one string containing both. Either way the currency must be the market's, not the store default.
4. **Decide the tax treatment per market** — EU markets expect the price to include VAT. The US expects tax excluded and handled separately. Shopify stores one number, so which one it is depends on the store's configuration, and the feed for each market has to state the right thing.
5. **Check it against the landing page** — Google compares the feed price with the price it finds on your product page. A correct value that the page contradicts, because of a discount app or a market-specific price, is a disapproval even though the feed is internally consistent.



## What goes wrong

### Checkout discounts never reach the feed

Automatic discounts, cart price rules, customer-specific pricing and app-driven promotions all apply after the product data. The feed shows the undiscounted price, the landing page may show less, and the channel treats the difference as a feed error.

### Tax treatment is a market decision, not a field

Shopify holds one number whose meaning depends on store configuration. Sending a tax-excluded price into an EU feed understates every price, and the mismatch is with the page rather than within the feed, so it is only caught by the channel.

### Currency conversion is not a market price

Converting the store price at today's rate produces a number that does not match what the storefront charges, because Shopify Markets applies its own rounding and price adjustments. The market price has to be read, not calculated.

### A zero price is not a free product

Zero usually means a placeholder, a configurable product or a data error. Channels reject a zero price, which is the right outcome, but it needs finding in the catalogue rather than in the error report.




## How feedlab maps it

feedlab formats price per channel from one internal amount and currency, reads market-specific prices rather than converting the store price, and applies the tax convention chosen for each market. Zero and missing prices are surfaced in the preview, since they are always data problems rather than values.






## Frequently asked questions

### Should the feed price include tax?

It depends on the market. EU markets expect VAT included; the US expects tax excluded and handled separately. Shopify stores one number, so the treatment has to be decided per feed.

### Why does the channel say my price does not match my page?

Most often a discount that applies at checkout rather than in the product data, or a market-specific price that the feed did not use. Both make the page and the feed disagree while the feed is internally correct.

### How should the price be formatted?

Two decimal places, a full stop as the decimal separator, no thousands separator, and the ISO currency code alongside the amount. OpenAI wants both in a single string.

### Can I convert my store price for another market?

No. Shopify Markets applies its own rounding and adjustments, so the converted figure will not match what the storefront charges. Read the market price instead.




## Primary sources

- [Google: price attribute specification](https://support.google.com/merchants/answer/6324371)
- [Shopify: ProductVariant API reference](https://shopify.dev/docs/api/admin-graphql/latest/objects/ProductVariant)



