Skip to main content

Where products come from

  • getStore() returns every listable product in store.products - use it for grids, search, categories and the cart. See Store Information.
  • getProduct(idOrSlug) fetches one product, by ID or slug - use it for a product page.
  • getProductReviews(productId, page) fetches a product’s reviews, a page at a time.

Get one product

Each call is a fresh request, and a successful one records a product view in the store’s analytics. That’s what you want on a product page, and not in a cart or a grid - look those products up in store.products instead.

The product object

Every product has at least one variant, and the price lives on the variant, not the product.
The full definitions are on the TypeScript page.

Prices

Sort variants by order and format cost with the store’s formatter:
Always pass cost to the formatter exactly as it arrives. On a store with adaptive currency the formatter converts it into the shopper’s currency - see Currency formatting.

Stock

Three fields decide what to show:
When a merchant hides stock levels, every variant is sent with stock: 0. Treating stock === 0 as “sold out” makes those products impossible to buy. isOutOfStock already accounts for hidden and untracked stock.

Quantity limits

A variant can set a minimum and a maximum quantity per order (maximumQuantity is -1 when there’s none). The cart doesn’t enforce them - checkout does, and refuses an order outside them - so clamp your quantity input:

Subscriptions

A subscription variant has type: 1 and a billingInterval:
Checkout refuses a cart that mixes subscriptions with one-time products. Give subscriptions a “Subscribe” button that uses buyNow(), which empties the cart first, or tell the buyer before they add one.

Volume pricing

volumeDiscounts holds quantity tiers. The highest tier the quantity reaches applies to every unit:
Use it to show the buyer what they’ll save. The order is still priced on the server: when a coupon is used and disableVolumeDiscountOnCoupon is true, the tiers stop applying.

Custom fields and Discord

customFields are the questions a merchant asks at checkout, and requireDiscordAuthorization means the buyer has to link their Discord account. Komerza’s hosted checkout handles both, so there’s nothing for your storefront to collect. Read them only if you want to tell the buyer what’s coming.

Badges

badges are the labels a merchant pins on a product, such as “New” or “Sale”, each with an optional hex color. isBestSeller marks the product the merchant chose as their best seller.

Images

imageNames holds file names, not URLs. A variant with no images of its own uses the product’s:
More on the Images page.

Reviews

Reviews carry no reviewer name.
Review text is written by customers. Render it with textContent or your framework’s normal text binding - never innerHTML. A review containing HTML would otherwise run as part of your page. See Security.

Complete example

A product page at product.html?slug=...:

Next

Currency Formatting

Prices in the store’s currency, or the shopper’s

Basket

Adding to the cart, and rendering it
Last modified on October 15, 2026