Product Structured Data
Merchant Listing Schema Markup
The one that gets you into Google Shopping. Direct merchant pages only — tells Google you're the seller, not just describing the product. Unlocks Popular Products, price drops, and shipping details in search.
Generate Merchant Listing Schema FreeMerchant Listing is a superset — adding these properties also qualifies the page for Product Snippet features. Selling products with variants? Layer ProductGroup schema on top for colour swatches in Shopping.
Merchant Listing in Google Shopping
What Merchant Listing schema unlocks
Required and recommended properties
Merchant Listing has stricter requirements than Product Snippet: price greater than zero and currency are required at the offer level.
| Property | Status | Notes |
|---|---|---|
| name | Required | Product name — must match the product name visible on the page. |
| offers.price | Required | Numeric price — must be greater than zero. Must match the price displayed and charged on the page. Free products (price = 0) are not eligible for Merchant Listing. |
| offers.priceCurrency | Required | Three-letter ISO 4217 code (GBP, USD, EUR…). One currency per URL — use separate URLs for different currencies. |
| offers.availability | Recommended | Full schema.org URI: https://schema.org/InStock, OutOfStock, PreOrder, BackOrder, Discontinued, LimitedAvailability. |
| image | Recommended | Product image URL. Must be crawlable and indexable. Required for Shopping panel eligibility in practice. |
| description | Recommended | Product description. Helps Google understand the product and improves Shopping matching accuracy. |
| gtin13 / gtin12 / gtin8 / gtin14 | Recommended | EAN-13, UPC, EAN-8, or ITF-14 barcode. Strong Shopping eligibility signal — Google uses it to match your product in its Shopping knowledge graph. Validate with GS1 checksum before including. |
| mpn | Recommended | Manufacturer Part Number. Use alongside brand as a fallback when no GTIN exists. |
| sku | Recommended | Your internal product identifier. If you don't have a GTIN, use this as the item ID in Merchant Center as well. |
| brand | Recommended | Brand as a nested Brand object: {"@type": "Brand", "name": "Acme"}. |
| offers.url | Recommended | Canonical URL of the product page. Should be the same as the page's canonical tag. |
| offers.shippingDetails | Recommended | OfferShippingDetails with shippingRate, shippingDestination, and deliveryTime. Include both handlingTime and transitTime within deliveryTime for full shipping annotations. Define at Organisation level if policy applies to all products. |
| hasMerchantReturnPolicy | Recommended | MerchantReturnPolicy. Required properties within it: returnPolicyCategory (e.g. MerchantReturnFiniteReturnWindow) and applicableCountry. Recommended: merchantReturnDays, returnMethod, returnFees. Define at Organisation level to avoid repeating on every product page. |
| inProductGroupWithID | Recommended | On variant pages — the productGroupID of the parent ProductGroup. Links this variant to the group for colour swatch eligibility in Shopping. |
| offers.priceSpecification | Optional | For sale / strikethrough pricing: array of UnitPriceSpecification objects. Use priceType: "https://schema.org/StrikethroughPrice" for the original price and "https://schema.org/SalePrice" for the discount. Member pricing uses validForMemberTier. |
| aggregateRating | Optional | Enables star ratings in search. Requires ratingValue and reviewCount. Works alongside Merchant Listing — adding reviews also qualifies the page for Product Snippet features. |
| offers.itemCondition | Optional | Full schema.org URI: https://schema.org/NewCondition, RefurbishedCondition, or UsedCondition. |
| offers.priceValidUntil | Optional | ISO 8601 date string. The offer may stop showing in search if this date has passed — keep it current or remove it. |
How to implement Merchant Listing schema
Google recommends putting Merchant Listing structured data in the initial HTML of your product pages, not injected by JavaScript after load. Shopping crawls JS-rendered schema less frequently, which means delayed or missed eligibility.
Mark up core product data
Start with the product name, image, description, and brand. Add identifiers — gtin13 (EAN barcode) or gtin12 (UPC) if you have them, validated with GS1 checksum. Use mpn + brand as fallback if no GTIN exists.
Add an Offer with price and currency
The Offer must include a price greater than zero and a priceCurrency (ISO 4217 code — GBP, USD, EUR). The price must exactly match what the customer sees on the page and at checkout. Use one URL per currency — do not put multiple currencies on the same page.
Add availability using the full schema.org URI (https://schema.org/InStock), priceValidUntil if the price is time-limited, and url pointing to the page's canonical URL.
Add shipping details
Use OfferShippingDetails with shippingRate, shippingDestination (destination country), and deliveryTime. Include both handlingTime (processing before dispatch) and transitTime (carrier transit days) for the best shipping annotation eligibility.
If the same shipping policy applies across all products, define it once at Organisation level using shippingDetails on your Organization schema — then reference it from each offer. This avoids repetition across thousands of pages.
Add a return policy
Use hasMerchantReturnPolicy with a MerchantReturnPolicy object. Required properties within it: returnPolicyCategory and applicableCountry. Recommended: merchantReturnDays, returnMethod, returnFees. Like shipping, define this at Organisation level if possible.
Validate and monitor
Test with Google's Rich Results Test and the Merchant Listings report in Search Console. Google will flag price mismatches between schema and page; resolve these immediately to avoid Shopping disapprovals.
JSON-LD examples
Basic Merchant Listing
Minimum required fields plus strong recommendations — name, offer with price/currency, availability, image, and GTIN.
{
"@context": "https://schema.org/",
"@type": "Product",
"name": "Classic Leather Trainer — White",
"image": "https://example.com/images/trainer-white.jpg",
"description": "Full-grain leather upper, rubber sole, available in sizes 4–13.",
"brand": { "@type": "Brand", "name": "Acme Footwear" },
"gtin13": "5901234123457",
"sku": "TRN-WHT-001",
"offers": {
"@type": "Offer",
"url": "https://example.com/trainers/classic-white/",
"price": 89.99,
"priceCurrency": "GBP",
"availability": "https://schema.org/InStock",
"itemCondition": "https://schema.org/NewCondition",
"priceValidUntil": "2026-12-31"
}
}
Full Merchant Listing with shipping and returns
Adds shipping details (handling + transit time) and a return policy — unlocks shipping annotations and return window in Shopping results.
{
"@context": "https://schema.org/",
"@type": "Product",
"name": "Classic Leather Trainer — White",
"image": "https://example.com/images/trainer-white.jpg",
"description": "Full-grain leather upper, rubber sole, available in sizes 4–13.",
"brand": { "@type": "Brand", "name": "Acme Footwear" },
"gtin13": "5901234123457",
"sku": "TRN-WHT-001",
"offers": {
"@type": "Offer",
"url": "https://example.com/trainers/classic-white/",
"price": 89.99,
"priceCurrency": "GBP",
"availability": "https://schema.org/InStock",
"itemCondition": "https://schema.org/NewCondition",
"priceValidUntil": "2026-12-31",
"shippingDetails": {
"@type": "OfferShippingDetails",
"shippingRate": {
"@type": "MonetaryAmount",
"value": 0,
"currency": "GBP"
},
"shippingDestination": {
"@type": "DefinedRegion",
"addressCountry": "GB"
},
"deliveryTime": {
"@type": "ShippingDeliveryTime",
"handlingTime": {
"@type": "QuantitativeValue",
"minValue": 0,
"maxValue": 1,
"unitCode": "DAY"
},
"transitTime": {
"@type": "QuantitativeValue",
"minValue": 1,
"maxValue": 3,
"unitCode": "DAY"
}
}
},
"hasMerchantReturnPolicy": {
"@type": "MerchantReturnPolicy",
"applicableCountry": "GB",
"returnPolicyCategory": "https://schema.org/MerchantReturnFiniteReturnWindow",
"merchantReturnDays": 30,
"returnMethod": "https://schema.org/ReturnByMail",
"returnFees": "https://schema.org/FreeReturn"
}
}
}
Sale / strikethrough pricing
Shows a crossed-out original price alongside the discounted sale price in Shopping results.
{
"@context": "https://schema.org/",
"@type": "Product",
"name": "Classic Leather Trainer — White",
"image": "https://example.com/images/trainer-white.jpg",
"brand": { "@type": "Brand", "name": "Acme Footwear" },
"gtin13": "5901234123457",
"offers": {
"@type": "Offer",
"url": "https://example.com/trainers/classic-white/",
"price": 59.99,
"priceCurrency": "GBP",
"availability": "https://schema.org/InStock",
"priceSpecification": [
{
"@type": "UnitPriceSpecification",
"price": 59.99,
"priceCurrency": "GBP",
"priceType": "https://schema.org/SalePrice"
},
{
"@type": "UnitPriceSpecification",
"price": 89.99,
"priceCurrency": "GBP",
"priceType": "https://schema.org/StrikethroughPrice"
}
]
}
}
price on the Offer must equal the active sale price and must match exactly what the customer sees. Google verifies both — a mismatch causes disapproval.Common implementation pitfalls
Merchant Listing is actively verified by Google, and these are the issues that most frequently cause Shopping disapprovals or lost eligibility.
<script type="application/ld+json"> block in the page's initial HTML response — not injected after load.priceValidUntil has passed, the offer may stop appearing in search. Either remove it (price stands indefinitely) or update it with each price change.MerchantReturnPolicy requires both returnPolicyCategory and applicableCountry. Omitting either causes validation errors. Define it once at Organisation level rather than repeating it on every product page.Frequently asked questions
priceSpecification array to the Offer with two UnitPriceSpecification objects: one with priceType: "https://schema.org/SalePrice" (the active discounted price) and one with priceType: "https://schema.org/StrikethroughPrice" (the original price). The main price field must equal the active sale price. Both must match what the customer sees on the page.inProductGroupWithID to link each variant back to the parent ProductGroup, which enables colour swatch eligibility in Shopping results. See the Product Variants schema guide for full implementation detail.Also in this series
Generate valid Merchant Listing schema
Add pricing, shipping, returns, and identifiers — get clean JSON-LD in seconds. No account needed.