Skip to content

[Bug]: item-level discounts not applied #14580

@SaqlainSajid

Description

@SaqlainSajid

Package.json file

{
  "name": "xxx",
  "version": "0.0.2",
  "description": "A starter for Medusa projects.",
  "author": "Medusa (https://medusajs.com)",
  "license": "MIT",
  "keywords": [
    "sqlite",
    "postgres",
    "typescript",
    "ecommerce",
    "headless",
    "medusa"
  ],
  "scripts": {
    "build": "medusa build",
    "seed": "medusa exec ./src/scripts/seed.ts",
    "seed:categories": "medusa exec ./src/scripts/seed-categories.ts",
    "start": "medusa start",
    "dev": "medusa develop",
    "docker:up": "docker compose up --build -d",
    "docker:down": "docker compose down",
    "test:integration:http": "TEST_TYPE=integration:http NODE_OPTIONS=--experimental-vm-modules jest --silent=false --runInBand --forceExit",
    "test:integration:modules": "TEST_TYPE=integration:modules NODE_OPTIONS=--experimental-vm-modules jest --silent --runInBand --forceExit",
    "test:unit": "TEST_TYPE=unit NODE_OPTIONS=--experimental-vm-modules jest --silent --runInBand --forceExit"
  },
  "dependencies": {
    "@medusajs/admin-sdk": "2.12.3",
    "@medusajs/cli": "2.12.3",
    "@medusajs/framework": "2.12.3",
    "@medusajs/medusa": "2.12.3",
    "pg": "^8.13.0",
  },
  "devDependencies": {
    "@medusajs/test-utils": "2.12.3",
    "@swc/core": "1.7.28",
    "@swc/jest": "^0.2.36",
    "@types/jest": "^29.5.13",
    "@types/node": "^20.0.0",
    "jest": "^29.7.0",
    "prop-types": "^15.8.1",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "ts-node": "^10.9.2",
    "typescript": "^5.6.2",
    "vite": "^5.2.11",
    "yalc": "^1.0.0-pre.53"
  },
  "engines": {
    "node": ">=20"
  }
}

Node.js version

v22.19.0

Database and its version

Postgres 17

Operating system name and version

macOS Sequoia Version 15.7.2 (24G325)

Browser name

Chrome

What happended?

When applying an item-level promotion (with target_type: items) to a draft order via POST /admin/draft-orders/{id}/edit/promotions, Medusa accepts the promotion and adds it to the order's promotions array, but fails to calculate the discount. The order's discount_total remains $0.00, item totals are not adjusted, and the promotion's application_method field is missing from the response.

This bug is specific to item-level promotions on draft orders. Order-level promotions work correctly.

Test Configuration

Promotion: SPCPROD20

Retrieved from GET /admin/promotions:

{
  "id": "promo_01KEJFSWKSY6X6N19J3WDXVNQS",
  "code": "SPCPROD20",
  "type": "standard",
  "status": "active",
  "is_automatic": false,
  "is_tax_inclusive": false,
  "application_method": {
    "id": "proappmet_01KEJFSWKTQ4NMNWYKQ2J3JGC5",
    "currency_code": "cad",
    "max_quantity": 1,
    "type": "fixed",
    "target_type": "items",
    "allocation": "each",
    "value": 20,
    "target_rules": [
      {
        "id": "prorul_01KEJFSWKVK0WY5YA9R06AE3QE",
        "attribute": "items.product.categories.id",
        "operator": "eq",
        "values": [
          {
            "value": "pcat_01KAS4E6JEX5J2YMWJ5BV0GQZW"
          }
        ]
      }
    ]
  }
}

Key details:

  • Type: fixed discount of $20.00 CAD
  • Target Type: itemsItem-level promotion
  • Allocation: each ← Apply to each qualifying item
  • Max Quantity: 1 ← Apply to maximum 1 item
  • Target Rule: Product must be in category pcat_01KAS4E6JEX5J2YMWJ5BV0GQZW (Pre Roll)

Test Product: Qwest 35's - Pre-roll (Grape Cream Cake)

  • Product ID: prod_01KAS4KABWBCZMPHVF7X4TGHDJ
  • Variant ID: variant_01KAS4KBY2BS8Z1HPCSX3K4JJ7
  • Price: $25.99 CAD
  • Category ID: pcat_01KAS4E6JEX5J2YMWJ5BV0GQZW (Pre Roll)
  • Product matches promotion target rule

Expected behavior

Expected Behavior

When applying a valid item-level promotion to a draft order:

  1. Promotion should be added to the order's promotions array
  2. application_method should be populated in the response
  3. Item subtotal should reflect the discount: $25.99 - $20.00 = $5.99
  4. Order discount_total should show the discount: $20.00
  5. Item discount_total should show the discount: $20.00
  6. Tax should be recalculated on the discounted amount: $5.99 × 5% = $0.30
  7. Order total should reflect the final price: $5.99 + $0.30 = $6.29

Expected Response

{
  "order": {
    "id": "order_01KFBYN0FF6B9RTWNQGM5GRNPN",
    "status": "draft",
    "subtotal": 5.99,
    "discount_total": 20.00,
    "discount_subtotal": 20.00,
    "tax_total": 0.30,
    "total": 6.29,
    "items": [
      {
        "id": "ordli_01KFBYNP6SVCSZWTKP14025SRR",
        "title": "Qwest 35's - Pre-roll",
        "subtitle": "Grape Cream Cake 10 X 0.35g Pre-rolls",
        "variant_id": "variant_01KAS4KBY2BS8Z1HPCSX3K4JJ7",
        "product_id": "prod_01KAS4KABWBCZMPHVF7X4TGHDJ",
        "unit_price": 25.99,
        "quantity": 1,
        "subtotal": 5.99,
        "discount_total": 20.00,
        "tax_total": 0.30,
        "total": 6.29
      }
    ],
    "promotions": [
      {
        "id": "promo_01KEJFSWKSY6X6N19J3WDXVNQS",
        "code": "SPCPROD20",
        "type": "standard",
        "is_tax_inclusive": false,
        "application_method": {
          "type": "fixed",
          "value": 20,
          "currency_code": "cad",
          "target_type": "items",
          "allocation": "each",
          "max_quantity": 1
        }
      }
    ]
  }
}

Actual behavior

The promotion is accepted and added to the order, but:

  1. No discount is calculated
  2. Item totals remain unchanged
  3. Tax is calculated on the full price instead of the discounted price
  4. The application_method field is completely missing from the promotion object in the responsE

Order State BEFORE Applying Promotion

GET /admin/draft-orders/{id} response:

{
  "created_at": "2026-01-19T20:20:28.785Z",
  "currency_code": "cad",
  "discount_subtotal": 0,
  "discount_total": 0,
  "display_id": 10884,
  "id": "order_01KFBYN0FF6B9RTWNQGM5GRNPN",
  "is_draft_order": true,
  "items": [
    {
      "id": "ordli_01KFBYNP6SVCSZWTKP14025SRR",
      "metadata": {},
      "product_id": "prod_01KAS4KABWBCZMPHVF7X4TGHDJ",
      "quantity": 1,
      "subtitle": "Grape Cream Cake 10 X 0.35g Pre-rolls",
      "subtotal": 25.99,
      "title": "Qwest 35's - Pre-roll",
      "total": 27.2895,
      "unit_price": 25.99,
      "variant_id": "variant_01KAS4KBY2BS8Z1HPCSX3K4JJ7"
    }
  ],
  "metadata": {},
  "promotions": [],
  "region_id": "reg_01KAS4C7XRHQRVYBHJR0NKX35S",
  "status": "draft",
  "subtotal": 25.99,
  "summary": {
    "paid_total": 0,
    "pending_difference": 27.2895,
    "refunded_total": 0,
    "transaction_total": 0
  },
  "tax_total": 1.2995,
  "total": 27.2895,
  "updated_at": "2026-01-19T20:20:52.383Z"
}

Order State AFTER Applying Promotion (BUG DETECTED)

POST /admin/draft-orders/{id}/edit/promotions with body {"promo_codes": ["SPCPROD20"]}:

{
  "created_at": "2026-01-19T20:20:28.785Z",
  "currency_code": "cad",
  "discount_subtotal": 0,
  "discount_total": 0,
  "display_id": 10884,
  "id": "order_01KFBYN0FF6B9RTWNQGM5GRNPN",
  "is_draft_order": true,
  "items": [
    {
      "id": "ordli_01KFBYNP6SVCSZWTKP14025SRR",
      "metadata": {},
      "product_id": "prod_01KAS4KABWBCZMPHVF7X4TGHDJ",
      "quantity": 1,
      "subtitle": "Grape Cream Cake 10 X 0.35g Pre-rolls",
      "subtotal": 25.99,
      "title": "Qwest 35's - Pre-roll",
      "total": 27.2895,
      "unit_price": 25.99,
      "variant_id": "variant_01KAS4KBY2BS8Z1HPCSX3K4JJ7"
    }
  ],
  "metadata": {},
  "promotions": [
    {
      "code": "SPCPROD20",
      "id": "promo_01KEJFSWKSY6X6N19J3WDXVNQS",
      "is_tax_inclusive": false,
      "type": "standard"
    }
  ],
  "region_id": "reg_01KAS4C7XRHQRVYBHJR0NKX35S",
  "status": "draft",
  "subtotal": 25.99,
  "summary": {
    "paid_total": 0,
    "pending_difference": 27.2895,
    "refunded_total": 0,
    "transaction_total": 0
  },
  "tax_total": 1.2995,
  "total": 27.2895,
  "updated_at": "2026-01-19T20:21:35.678Z"
}

What's Wrong

Field Expected Actual Status
order.discount_total 20.XX 0 BUG
order.discount_subtotal 20.00 0 BUG
order.subtotal 5.99 25.99 BUG
order.tax_total 0.30 1.2995 BUG
order.total 6.29 27.2895 BUG
items[0].subtotal 5.99 25.99 BUG
items[0].total 6.29 27.2895 BUG
promotions[0].code "SPCPROD20" "SPCPROD20" Works
promotions[0].application_method {object} MISSING BUG

Order-level promotions work fine

Link to reproduction repo

N/A

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