Coupons Incorrectly Recalculated on Order Status Change
Summary:
This bug report describes an issue where WooCommerce incorrectly recalculates applied coupons when an order's status is changed. The core problem is that the wc_save_order_items() function, which is triggered during a status update, always calls $order->recalculate_coupons(). This method re-applies coupon rules based on the current state of the product catalog, rather than honoring the conditions that were valid at the time the order was originally placed and paid for.
The primary impact is that order totals can be altered after payment, leading to discrepancies between the charged amount and the amount displayed in the admin. This is particularly problematic for coupons with restrictions like "Exclude sale items." For example, if a product was on sale when the order was paid (correctly preventing the coupon from applying), but the sale ends before the order status is changed to "Completed," the coupon will be incorrectly applied during the status transition, reducing the order total.
How to Replicate:
- Create a coupon with the "Exclude sale items" restriction enabled.
- Create a product and set it to have a sale price.
- Create a new order, add the product, and attempt to apply the coupon. The coupon should not apply because the product is on sale.
- Save the order and set its status to "Processing" (simulating a paid order).
- Remove the sale price from the product (or wait for its sale period to end).
- Change the order status from "Processing" to "Completed".
- Observe that the coupon discount is now incorrectly applied to the order.