Merchant settings
Apply the public shop contract consistently in SSR, checkout and customer accounts
Read getShopInfo() before rendering the storefront. Settings belong to the
merchant and override template defaults. New fields in SDK 1.20 are optional for
compatibility with older servers; absence is different from an explicit false.
Use the public contract instead of exposing or reading arbitrary administrative
settings or inventory data groups.
Appearance and money
appearance.primaryColor, secondaryColor and fontFamily override the theme
when non-null. Validate colors and calculate readable button text; retain a
fallback when a font cannot load. customCss is trusted merchant styling, but
must still be serialized safely inside a style element so </style> cannot
escape into HTML. showPoweredBy controls platform attribution independently of
other footer content. Merchant descriptions and other rich text still require
HTML sanitization; script settings are a separate trusted channel.
Pass currencyDisplayFormat as the fourth argument of formatPrice(amount, currency, locale, displayFormat). Apply it to initial HTML and client updates,
including variant prices, cards, cart, checkout, receipts and account pages.
This changes presentation only. Currency selection must update the actual cart;
never relabel an amount from another currency.
Checkout
Render checkout.checkoutLayout as SINGLE_PAGE or STEP_BY_STEP. In a stepped
checkout, preserve entered addresses and choices when moving back or reloading,
and recalculate the review after changing them. Do not persist consent as an
automatically accepted checkbox or reuse an expired shipping quote.
showCartPriceBreakdown controls detailed totals and showEstimatedDelivery
controls delivery estimates. orderConfirmationText is plain text, escaped on
the receipt. Receipt amounts come from the order snapshot, including payment
fees, gift cards, loyalty and rounding; later administrative changes must not
rewrite historical totals.
Honor required phone and tax identifiers, terms/privacy consent, guest and
account requirements, order-note visibility, newsletter defaults and optional
SMS consent. requireRegistrationApproval is independent of email verification.
Only the merchant's required consents block submission. A price preview does
not record consent or create an order.
Use cart.checkoutLimits for minimum/maximum order amounts in the cart's
currency, compared with cart.subtotal before codes or gift redemption. The
server also validates per-product and whole-cart quantity limits. Submit a
current signed checkout.preview() result with the order, and display an
explicit error when a review is stale or cannot be loaded.
Physical and online delivery
The product admin has Requires shipping, enabled by default. Disable it only
for a product delivered entirely online. Product variants have their own setting.
An attached paid PDF may be a bonus for physical goods, so isDigital describes
available digital content and does not determine the need for shipping. Product
duplication preserves the explicit setting.
cart.requiresShipping is true if any product requires physical delivery,
including any component of any bundle. An omitted field from an older server
must be treated as true. In a purely online cart, collect the real billing
address, omit the delivery address, courier and pickup selector, and hide COD.
Keep payment-country, currency and tax checks based on the billing destination.
Do not restrict online billing countries to the courier's delivery countries.
CheckoutInput.shippingAddress is optional only for carts without physical
delivery. The API rechecks the current products, ignores obsolete shipping
selections on an online order and charges no shipping. It stores no fictional
delivery address. On a receipt, hide delivery details when
OrderDetail.requiresShipping === false. Downloads and course enrollments are
granted after payment is confirmed, including full gift-card payment, not when
a price preview or unpaid order is created.
Time zone
timezone is the site's IANA time zone (for example Europe/Prague). Format
every date and time with it, new Intl.DateTimeFormat(locale, {timeZone: shop.timezone}), both on the server and in the browser. Without it the server
(UTC) and the visitor's browser format the same instant as different days, React
reports a hydration mismatch and a sale ending at midnight shows the wrong date.
Fall back to Europe/Prague only when the field is missing (older cached payload).
Accounts, maintenance and outages
Apply account.passwordMinLength to registration, reset and password-change
forms, with a maximum length of 128. Show approval and email-verification states
separately; pending accounts receive no login tokens.
maintenance.enabled and maintenance.message control the maintenance page.
The checkout API also blocks ordering during maintenance. A sandbox may preview
an inactive shop, but that does not bypass an explicit maintenance setting.
commerce.state says whether the site sells right now. LIVE sells, ADDED
means the merchant is still setting the shop up (orders are accepted), NONE
is a website without a shop, and PAUSED means the shop is not accepting
orders at the moment, for example after the trial ended without a plan. While
paused, cart writes, checkout and gift card purchases answer 403
be.storefront.shopPaused. Keep the catalog and product pages visible, replace
the buy buttons with a short notice and do not send visitors into a checkout
that cannot finish. Gate on commerce.acceptsOrders; treat a missing
commerce (older cached payload) as accepting orders.
A network or server error is not a logout and is not an empty cart. Keep stored session cookies, present an unavailable state and let the visitor retry. Session renewal must remain usable even while catalog and cart reads fail. See authentication for read-only rendering, refresh-token rotation and cookie persistence.