-
-
Notifications
You must be signed in to change notification settings - Fork 4k
Description
Bug Description
When using automatic promotions that apply a percentage discount to shipping methods (e.g., "Free shipping for orders >= $100"), the promotion discount is calculated using the old shipping amount instead of the newly calculated amount after cart items change.
This occurs because in refreshCartItemsWorkflow, the updateCartPromotionsWorkflow fetches cart data that contains the stale shipping method amount before refreshCartShippingMethodsWorkflow changes are visible.
Steps to Reproduce
- Create a calculated shipping option with a fulfillment provider that calculates shipping based on cart items (e.g., $4.79 + $1.50 per additional item)
- Create an automatic promotion for free shipping:
{ code: "FREE-SHIPPING-OVER-100", type: "standard", status: "active", is_automatic: true, rules: [{ attribute: "item_total", operator: "gte", values: ["100"] }], application_method: { type: "percentage", target_type: "shipping_methods", value: 100, // 100% off allocation: "across" } }
- Add items to cart until
item_total >= $100with a shipping method selected
Expected Behavior
- Shipping price recalculates (e.g., $9.29 → $10.79)
- Promotion applies 100% discount on new amount ($10.79)
shipping_total= $0
Actual Behavior
- Shipping price recalculates to $10.79
- Promotion applies 100% discount on old amount ($9.29)
shipping_total= $1.50 (the difference)
Technical Analysis
In packages/core/core-flows/src/cart/workflows/refresh-cart-items.ts:
// Line 243-245: Shipping methods are refreshed (price updated in DB)
refreshCartShippingMethodsWorkflow.runAsStep({
input: refreshCartInput,
})
// Line 287-293: Promotions are computed
updateCartPromotionsWorkflow.runAsStep({
input: {
cart_id: input.cart_id, // Fetches cart again
promo_codes: cartPromoCodes,
action: PromotionActions.REPLACE,
},
})The issue is that updateCartPromotionsWorkflow fetches cart data via useRemoteQueryStep, but the shipping method amount updated by refreshCartShippingMethodsWorkflow is not yet visible (likely due to transaction isolation within the workflow).
The promotion computation in packages/modules/promotion/src/utils/compute-actions/shipping-methods.ts uses method.subtotal (line 60, 66) which contains the stale value.
Environment
- Medusa version: v2.x (latest)
- Using calculated shipping options with custom fulfillment provider
Suggested Fix
Either:
- Pass the updated cart object from
refreshCartShippingMethodsWorkflowtoupdateCartPromotionsWorkflowinstead of re-fetching - Or ensure the workflow step changes are flushed/committed before subsequent steps fetch data
- Or recalculate shipping prices within the promotion computation workflow