Hello all,

I think I've stumbled across a bug in Zen where credit order total modules do not get handled correctly if they apply a credit that is near the order total.

Steps to reproduce (on a fresh install):

  1. Enable the low order fee module to charge $5 for orders under $50.
  2. Enable the Gift Certificates order total module.
  3. Ensure a cheap shipping module is enabled. I used per item shipping at $2.50.
  4. Enable PayPal WPP in sandbox mode.
  5. Create a customer account
  6. Give the customer account a GV balance of $40
  7. Add a $35 dollar item to your cart. I selected "A Bug's Life"
  8. Proceed to checkout. For step 1, select per-item shipping at $2.50.
  9. In step 2, your order total should be $43.49. Apply a GV balance of $40.00 (or any amount that reduces the grand total to less than the low order fee). Select PayPal for your payment method.
  10. Step 3, Confirm.

You will be immediately redirected to checkout_success rather than PayPal. If you examine the order in the admin section it will show the payment method as "Gift Certificate / Coupon."

As far as I can tell, the issue is that order_total->pre_confirmation_check() is called before order_total->process(). Since process() is the function that actually modifies the global order object, pre_confirmation_check() uses incorrect $order->info['total'] amounts to calculate the deductions versus the order total. As a consequence credit_covers is set true and $_SESSION['payment'] is cleared so the customer is never redirected to PayPal.

I don't think this is a bug in the low order fee module per se, but a design issue (or at least an issue in the order_total class). Using the other modules as an example it looks like modifying the global order object in process() is the "right thing to do," but that breaks pre_confirmation_check(). I came across this while working on my own order total class, but when I realized it was reproducible with a stock cart I decided to post here.

When I am writing an order total module, is process() the correct place to modify the global order object?

Thanks for any and all help!