Product Schema for Indian Ecommerce: Price, Availability and GST

Indian product markup breaks in predictable ways: MRP against selling price, tax-inclusive display, variants sharing one URL and availability that lies. A field by field guide to getting it right.

Product markup is the one piece of structured data with a direct commercial consequence. Get it right and your listing can carry price, availability and ratings. Get it wrong and Google drops the enhancement, or worse, shows a price you are not selling at.

Indian stores break it in a handful of specific ways, almost all of them traceable to how prices are displayed here. This post is about those specific failures rather than a general tour of schema.org. For the wider page structure question, ecommerce SEO for Indian D2C brands covers the ground above this one.

The fields that carry weight

A product page needs a Product object with an offers block. Everything else is optional in the sense that the markup validates without it, and important in the sense that omitting it costs you.

name Exactly the product name shown on the page. Not the page title with your brand appended.
sku Your internal code. Use it. It is how your own data joins up later.
gtin The barcode number if the product has one. Strongly worth including for anything manufactured rather than made by you.
brand An object with a name, not a bare string buried elsewhere.
image Several images, absolute URLs, the same ones a shopper sees.
offers.price The number a buyer pays today. Not the MRP. More on this below.
offers.priceCurrency INR. Obvious, and still wrong on a surprising number of sites running a theme built for another market.
offers.availability One of the schema.org values such as InStock or OutOfStock, and it must be true right now.
offers.priceValidUntil When the current price expires. Useful during sale periods, misleading if you set it and forget it.
offers.itemCondition New, refurbished or used. Matters for anyone selling renewed stock.
shippingDetails Delivery cost and timing. Shoppers compare on landed cost, not product price.
hasMerchantReturnPolicy Return window and who pays. The single most asked question before a first purchase from an unknown brand.

MRP is not your price, and marking it up as one is the common error

Indian product pages almost always show two numbers, the maximum retail price struck through and the selling price beside it. Plenty of templates put the first one into the markup because it is the field the theme calls the price.

The price in your offer is what a buyer pays at checkout today. If your page shows a selling price of one figure and your markup declares the MRP, you have published a price mismatch. Google’s product documentation is explicit that structured data must match the page, and the usual outcome is the enhancement being dropped quietly. Nobody tells you. You simply stop getting the rich result and assume the feature was removed.

If you want to express the MRP as well, it belongs in a price specification as a list price rather than replacing the real one. If your templating cannot do that cleanly, publish only the selling price. One correct number beats two numbers in the wrong fields.

Tax inclusive pricing needs to be stated, not assumed

Under India’s packaged commodity rules, the retail price shown to a consumer is inclusive of all taxes. Everyone in the Indian market reads a displayed price that way without thinking about it. Structured data does not.

Schema.org has a price specification that carries a flag for whether value added tax is included. Setting it removes the ambiguity for any consumer of your markup, including assistants and shopping surfaces built for multiple markets which may not assume Indian conventions.

Where this actually bites is business to business selling. If you quote exclusive of GST to trade buyers and inclusive to consumers, and both run through the same template, you will eventually publish one as the other. Decide which audience the page is for, state the tax treatment explicitly in the markup, and make the visible page say the same thing in words.

Availability that lies is worse than availability you omit

Availability is the field most likely to be stale, because it is the only one that changes without anybody editing the page. A product marked in stock that is not will produce a click, a disappointed buyer and, if it persists, a loss of the enhancement.

Drive it from live inventory or do not publish it. Marking everything as in stock because that is the template default is a decision, even when nobody made it deliberately.

For products that are genuinely coming back, the vocabulary has values for pre-order and back-order that are more useful than a binary. For something discontinued, say so and keep the page alive with a link to the replacement, which also protects the links the page has earned. Deciding whether to update, merge or delete a page applies to retired products as much as to articles.

Variants are where Indian stores lose the most

Size, colour, capacity, pack count. A single URL showing ten variants with a price range is comfortable for shoppers and hostile to structured data, because there is no single price to declare.

You have two honest options. Give each variant its own indexable URL with its own markup and its own price. Or keep one URL and declare an aggregate offer with a low and high price, which is accurate but produces a weaker result than a specific price.

Choose based on whether people search for the variant. Nobody searches for a t-shirt in medium, so one URL with an aggregate offer is right. People absolutely search for a specific capacity of an appliance or a specific pack size, and those deserve their own URLs. Getting this wrong in the other direction creates hundreds of near-identical pages, which is the problem faceted navigation and pagination deals with.

Ratings you did not earn

Aggregate rating markup is the most abused field in ecommerce. Two rules, both of which Google enforces.

The rating must come from reviews of that product, collected from real buyers, and those reviews must be visible on the page. A site-wide rating applied to every product is invalid. A rating from a third-party platform that does not appear on the page is invalid. Inventing them is the kind of thing that attracts a manual action rather than a quiet downgrade.

If you do not yet have product reviews, ship without the field. It is not worth the risk, and the honest route to getting them is covered in getting genuine customer reviews.

What assistants do with this

When someone asks an assistant to compare two products or find something under a budget, clean product markup makes your page usable rather than merely readable. Price, currency, availability and return terms expressed as data are far easier to extract than the same facts scattered across a page in images and styled spans.

Be realistic about the ceiling. Markup makes a page machine readable, it does not make an unknown brand authoritative, and marketplaces still dominate most shopping answers. We argued the general case in does schema markup help you get cited, and the ecommerce specific version is in AI product search for ecommerce.

What is a waste of effort

Marking up fields you cannot keep accurate. Every field is a promise, and a stale promise is worse than a missing one.

Hand-writing markup per product. At any real catalogue size this drifts within a month. Generate it from the same data the page renders from, and validate it automatically, which is the approach in automating structured data from your CMS.

Chasing every optional property. A correct, complete offer block beats a sprawling object with twenty half-filled fields.

When you also sell on marketplaces

Most Indian brands sell on their own store and on one or two marketplaces at the same time, and that creates a specific problem for product markup.

The marketplace listing will usually outrank your own page, because marketplace domains are stronger and their catalogues are enormous. That is not something you fix with better markup. What you can do is make sure the comparison favours you where a buyer does reach your site.

Price is the awkward part. If your own store is more expensive than your marketplace listing, a shopper who compares will notice, and no structured data strategy repairs that. Decide your pricing policy across channels deliberately, because it is a commercial decision that shows up as a conversion problem.

Where your own page can win is on everything a marketplace listing cannot carry: full specifications, genuine usage guidance, care instructions, warranty terms handled by you directly, and bundles or variants the marketplace does not stock. Mark those up accurately and the page becomes the authoritative description of the product rather than a weaker copy of a listing. The marketplace side of this is in Amazon and Flipkart listing optimisation.

Use the same identifiers everywhere. The same SKU and the same barcode on your site, your marketplace listings and any shopping feed. Inconsistent identifiers are why the same product is sometimes treated as several different products.

Images and feeds, which share the same data

Two things depend on the fields discussed above and are worth connecting to them.

Image markup should point at the same images the page displays, at a usable resolution, on absolute URLs. Several images beat one. Avoid images with price or offer text burned into them, because the picture becomes wrong the moment the price changes and you will not remember to regenerate it.

If you run a shopping feed, treat it and your structured data as two outputs of one source. When the feed says one price and the page markup says another, you have a mismatch that is both a data integrity problem and a visible inconsistency.

The practical rule is that price, availability, title, identifiers and images should be generated from the same place for the page, the markup and the feed. Teams that maintain them separately end up with three slightly different versions of the catalogue and no way to tell which is right. Shopify SEO covers the platform-specific version of this problem.

A sensible order of work

  1. Audit what you currently publish against what the page shows. Price mismatch first, availability second.
  2. Fix the price field so it carries the selling price, and express MRP as a list price or not at all.
  3. State the tax treatment explicitly, and make the visible page agree with it.
  4. Wire availability to live inventory, or remove the field.
  5. Decide your variant strategy deliberately and apply it consistently.
  6. Add shipping and return policy, which affect conversion more than most markup.
  7. Add a validation step to your deployment so a template change cannot silently break the catalogue.

If you want an audit of what your store is currently publishing against what it actually sells, get in touch.