Describe the Bug
In the ecommerce template, products can display a stale priceInUSD even after USD pricing has been disabled. When a product previously had a USD price set, disabling priceInUSDEnabled does not clear or invalidate the stored value, allowing outdated pricing data to persist and be used by the frontend.
The issue originates in shop/page.tsx, where priceInUSD is selected and passed into the product grid without checking whether it is enabled:
select: {
title: true,
slug: true,
gallery: true,
categories: true,
priceInUSD: true,
},
This allows previously saved prices to flow through the storefront even when they are no longer active. This is especially problematic for products that rely on variant-level pricing, where disabling the base product price is expected behavior.
ProductGridItem then simply renders any numeric price:
{typeof price === 'number' && (
<Price amount={price} />
)}
This check is faulty, as it only verifies that the value is numeric, not whether the price is actually enabled. As a result, stale prices continue to be displayed.
A simple fix at the template level would be to also select priceInUSDEnabled and only pass or render priceInUSD when it is true, preventing disabled prices from reaching the UI.
Suggested fix:
In shop/page.tsx, also select priceInUSDEnabled:
select: {
title: true,
slug: true,
gallery: true,
categories: true,
priceInUSD: true,
priceInUSDEnabled: true,
},
Then normalize the results before rendering so disabled prices are not passed into ProductGridItem:
const cleanProducts = products.docs.map((product) => ({
...product,
priceInUSD: product.priceInUSDEnabled ? product.priceInUSD : undefined,
}))
Render cleanProducts instead of products.docs to prevent stale prices from being displayed.
Link to the code that reproduces this issue
https://github.com/payloadcms/payload/tree/main/templates/ecommerce
Reproduction Steps
-
Create a new Payload app using the ecommerce template (I used PostgreSQL):
npx create-payload-app@latest my-app -t ecommerce
-
Start the app:
-
Open http://localhost:3000, click Seed on the homepage, and create an admin account
-
Go to the admin panel at /admin and open an existing product (or create a new one)
-
Enable USD pricing and set a value for priceInUSD, then save
(for seeded products, this is already set)
-
Edit the same product again, disable USD pricing using the toggle in the Details tab, and save
-
Visit the storefront and view the product in the product grid
Result: the previously set USD price is still displayed even though USD pricing is disabled.
Which area(s) are affected?
area: templates
Environment Info
Binaries:
Node: 22.22.2
npm: 10.9.7
Yarn: 1.22.22
pnpm: 10.33.0
Relevant Packages:
payload: 3.81.0
next: 16.2.1
@payloadcms/db-postgres: 3.81.0
@payloadcms/drizzle: 3.81.0
@payloadcms/email-nodemailer: 3.81.0
@payloadcms/graphql: 3.81.0
@payloadcms/live-preview: 3.81.0
@payloadcms/live-preview-react: 3.81.0
@payloadcms/next/utilities: 3.81.0
@payloadcms/plugin-form-builder: 3.81.0
@payloadcms/plugin-seo: 3.81.0
@payloadcms/richtext-lexical: 3.81.0
@payloadcms/translations: 3.81.0
@payloadcms/ui/shared: 3.81.0
react: 19.2.4
react-dom: 19.2.4
Operating System:
Platform: linux
Arch: x64
Version: #1 SMP PREEMPT_DYNAMIC Thu, 26 Mar 2026 19:20:28 +0000
Available memory (MB): 64226
Available CPU cores: 16
Describe the Bug
In the ecommerce template, products can display a stale
priceInUSDeven after USD pricing has been disabled. When a product previously had a USD price set, disablingpriceInUSDEnableddoes not clear or invalidate the stored value, allowing outdated pricing data to persist and be used by the frontend.The issue originates in
shop/page.tsx, wherepriceInUSDis selected and passed into the product grid without checking whether it is enabled:This allows previously saved prices to flow through the storefront even when they are no longer active. This is especially problematic for products that rely on variant-level pricing, where disabling the base product price is expected behavior.
ProductGridItemthen simply renders any numeric price:This check is faulty, as it only verifies that the value is numeric, not whether the price is actually enabled. As a result, stale prices continue to be displayed.
A simple fix at the template level would be to also select
priceInUSDEnabledand only pass or renderpriceInUSDwhen it is true, preventing disabled prices from reaching the UI.Suggested fix:
In
shop/page.tsx, also selectpriceInUSDEnabled:Then normalize the results before rendering so disabled prices are not passed into
ProductGridItem:Render
cleanProductsinstead ofproducts.docsto prevent stale prices from being displayed.Link to the code that reproduces this issue
https://github.com/payloadcms/payload/tree/main/templates/ecommerce
Reproduction Steps
Create a new Payload app using the ecommerce template (I used PostgreSQL):
Start the app:
Open
http://localhost:3000, click Seed on the homepage, and create an admin accountGo to the admin panel at
/adminand open an existing product (or create a new one)Enable USD pricing and set a value for
priceInUSD, then save(for seeded products, this is already set)
Edit the same product again, disable USD pricing using the toggle in the Details tab, and save
Visit the storefront and view the product in the product grid
Result: the previously set USD price is still displayed even though USD pricing is disabled.
Which area(s) are affected?
area: templates
Environment Info