Skip to content

[Bug]: Backorder products incorrectly marked as insufficient_inventory for pickup shipping options #14640

@marlinjai

Description

@marlinjai

Package.json file

{
	"name": "busbasisberlin-monorepo",
	"version": "1.0.0",
	"description": "BusBasisBerlin MedusaJS E-commerce Monorepo",
	"private": true,
	"workspaces": [
		"busbasisberlin",
		"busbasisberlin-storefront"
	],
	"scripts": {
		"format": "npm run format:backend && npm run format:frontend",
		"format:backend": "cd busbasisberlin && npx prettier --write \"src/**/*.{ts,js,json}\" \"*.{ts,js,json}\"",
		"format:frontend": "cd busbasisberlin-storefront && npx prettier --write \"src/**/*.{ts,tsx,js,jsx,json}\" \"*.{ts,tsx,js,jsx,json}\"",
		"lint": "npm run lint:backend && npm run lint:frontend",
		"lint:backend": "cd busbasisberlin && npx eslint \"src/**/*.{ts,js}\" \"*.{ts,js}\" --fix || true",
		"lint:frontend": "cd busbasisberlin-storefront && npx eslint \"src/**/*.{ts,tsx,js,jsx}\" \"*.{ts,tsx,js,jsx}\" --fix || true",
		"format:all": "npm run format && npm run lint",
		"dev:backend": "cd busbasisberlin && npm run dev",
		"dev:frontend": "cd busbasisberlin-storefront && npm run dev",
		"build:backend": "cd busbasisberlin && npm run build",
		"build:frontend": "cd busbasisberlin-storefront && npm run build"
	},
	"devDependencies": {
		"prettier": "^3.0.0"
	},
	"keywords": [
		"medusajs",
		"ecommerce",
		"nextjs",
		"typescript",
		"monorepo"
	],
	"author": "BusBasisBerlin",
	"license": "MIT",
	"dependencies": {
		"ajv": "^8.17.1",
		"csv-parse": "^6.1.0",
		"csv-parser": "^3.2.0",
		"csv-writer": "^1.6.0",
		"gemeindeverzeichnis": "^0.1.0",
		"google-libphonenumber": "^3.2.42",
		"node-fetch": "^3.3.2",
		"openai": "^5.9.0",
		"p-limit": "^6.2.0",
		"pg": "^8.16.3",
		"postal-codes-js": "^2.5.2"
	},
	"packageManager": "npm@10.9.0",
	"overrides": {
		"@medusajs/ui": {
			"react": "19.0.0-rc-66855b96-20241106",
			"react-dom": "19.0.0-rc-66855b96-20241106"
		}
	}
}

Node.js version

v20.19.4

Database and its version

(PostgreSQL) 16.9 (Homebrew)

Operating system name and version

macOS Sequoia 15.7.3 (24G419)

Browser name

Google Chrome

What happended?

When using pickup/store-location shipping options, products with allow_backorder=true and inventory_quantity=0 are incorrectly flagged
with insufficient_inventory=true, which disables the pickup option at checkout.

Our Use Case

We have implemented a custom "Pickup at Storage Location" (Abholung am Lager) shipping option where:

  • Customers can pick up their order at our physical warehouse location
  • Payment is made in cash upon pickup
  • This is a valid fulfillment method even for backorder items, since we can order the parts and notify the customer when ready for
    pickup

Expected behavior

Expected Behavior

Products with allow_backorder=true should bypass the inventory check, since they can be fulfilled through backorder regardless of
current stock levels. The pickup option should remain available.

Suggested Fix

  1. Add "items.variant.allow_backorder" to the cart query fields (line 148):
    fields: [
    ...cartFieldsForPricingContext,
    "items.*",
    "items.variant.manage_inventory",
    "items.variant.allow_backorder", // Add this
    "items.variant.inventory_items.inventory_item_id",
    // ...
    ]

  2. Check allow_backorder before flagging insufficient inventory (around line 333):
    const itemsAtLocationWithoutAvailableQuantity = cart.items.filter((item) => {
    if (!item.variant?.manage_inventory) {
    return false
    }
    // If backorder is allowed, item is always "available" for pickup
    if (item.variant?.allow_backorder) {
    return false
    }
    return item.variant.inventory_items.some((inventoryItem) => {
    // ... existing logic
    })
    })

Affected File

packages/core/core-flows/src/cart/workflows/list-shipping-options-for-cart.ts

Workaround

We are currently using patch-package to apply this fix locally.

Actual behavior

Current Behavior

In list-shipping-options-for-cart.ts, the insufficient_inventory calculation (lines 331-358) checks if items have available quantity at
the pickup location:

const itemsAtLocationWithoutAvailableQuantity = cart.items.filter((item) => {
if (!item.variant?.manage_inventory) {
return false
}
// Missing: check for allow_backorder
return item.variant.inventory_items.some((inventoryItem) => {
// ... checks location levels for available_quantity
})
})

This flags insufficient_inventory=true for any item with inventory_quantity=0, even if allow_backorder=true.

Link to reproduction repo

https://github.com/medusajs/medusa/blob/develop/packages/core/core-flows/src/cart/workflows/list-shipping -options-for-cart.ts#L331-L358 No separate reproduction repo needed - this is reproducible on any Medusa 2.x installation: 1. Create a stock location with a fulfillment set for pickup 2. Create a shipping option linked to that fulfillment set (e.g., "Store Pickup") 3. Create a product variant with: - manage_inventory: true - allow_backorder: true - inventory_quantity: 0 at the pickup location 4. Add the product to cart 5. Go to checkout and request shipping options via API

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions