payloadcms / payloadcms/payload
bug: plugin-ecommerce confirmOrder stock $inc leaves _versions stale
@paulpopus is already working on this.
Since May 6, 2026.
- Dominant language
- TypeScript
- Stars
- 44.8k
- Forks
- 4.2k
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 53
Description
Describe the Bug
The ecommerce plugin's confirmOrder endpoint decrements stock with a direct payload.db.updateOne using a Mongo $inc:
await payload.db.updateOne({
id,
collection: variantsSlug, // or productsSlug
data: {
inventory: {
$inc: item.quantity * -1,
},
},
})
When the products / variants collection has drafts enabled (versions.drafts: true), Payload stores the document in two places:
- the main
productscollection (latest published doc) - the
_products_versionscollection (all snapshots, withlatest: truemarking the row that the admin list view reads throughqueryDrafts)
The payload.db.updateOne call only writes to the main collection. The _versions row marked latest: true keeps its pre-decrement inventory, so the admin list view (and any find({ draft: true }) read) continues to show the old stock value after order confirmation. In practice: a customer purchases a product, the order is created and paid, but the admin "Products" list keeps showing the pre-purchase inventory.
Suggested fix: when the target collection has drafts enabled, mirror the $inc onto the latest: true versions doc as well (e.g. via payload.db.updateVersion).
Link to the code that reproduces this issue
https://github.com/jhb-dev/payload-ecommerce-decrement-versions-stale
Reproduction Steps
- Clone the reproduction repository and run the development server
- The
onInitseed (src/seed.ts) creates aProductwithinventory: 10, then calls the samepayload.db.updateOne({ inventory: { $inc: -1 } })shape used by the plugin'sconfirmOrder - The seed reads back both the main collection doc and the
_versionsdoc withlatest: true, and logs them - Expected: both reads return
inventory: 9 - Actual: main collection returns
9, but_versions(andfind({ draft: true }), which is what the admin list view uses) still returns10
Server log output:
[11:36:54] INFO: --- Reproduction: stock $inc leaves _versions stale ---
[11:36:55] INFO: Created product 69fb0bb628ecf760cde3fa29 with inventory=10 (published)
[11:36:55] INFO: Called payload.db.updateOne({ inventory: { $inc: -1 } })
[11:36:55] INFO: Main collection inventory: 9
[11:36:55] INFO: _versions latest inventory: 10
[11:36:55] INFO: find({ draft: true }) inventory: 10 (this is what the admin list view shows)
[11:36:55] ERROR: BUG REPRODUCED: main collection decremented to 9, but _versions still shows 10. The admin list view will show 10.
Which area(s) are affected?
plugin: ecommerce
Environment Info
```
Binaries:
Node: 24.3.0
npm: 11.4.2
Yarn: 1.22.22
pnpm: 10.33.0
Relevant Packages:
payload: 3.84.1
next: 16.2.3
@payloadcms/db-mongodb: 3.84.1
@payloadcms/graphql: 3.84.1
@payloadcms/next/utilities: 3.84.1
@payloadcms/richtext-lexical: 3.84.1
@payloadcms/translations: 3.84.1
@payloadcms/ui/shared: 3.84.1
react: 19.2.4
react-dom: 19.2.4
Operating System:
Platform: darwin
Arch: arm64
Version: Darwin Kernel Version 24.6.0
```
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.